Radix cross Linux package tools

Package Tools – is a set of utilities to create, install, and update RcL packages

3 Commits   0 Branches   2 Tags
11c606a6 (kx 2023-04-11 01:18:34 +0300    1) 
11c606a6 (kx 2023-04-11 01:18:34 +0300    2) /**********************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300    3) 
11c606a6 (kx 2023-04-11 01:18:34 +0300    4)   Copyright 2019 Andrey V.Kosteltsev
11c606a6 (kx 2023-04-11 01:18:34 +0300    5) 
11c606a6 (kx 2023-04-11 01:18:34 +0300    6)   Licensed under the Radix.pro License, Version 1.0 (the "License");
11c606a6 (kx 2023-04-11 01:18:34 +0300    7)   you may not use this file  except  in compliance with the License.
11c606a6 (kx 2023-04-11 01:18:34 +0300    8)   You may obtain a copy of the License at
11c606a6 (kx 2023-04-11 01:18:34 +0300    9) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   10)      https://radix.pro/licenses/LICENSE-1.0-en_US.txt
11c606a6 (kx 2023-04-11 01:18:34 +0300   11) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   12)   Unless required by applicable law or agreed to in writing, software
11c606a6 (kx 2023-04-11 01:18:34 +0300   13)   distributed under the License is distributed on an "AS IS" BASIS,
11c606a6 (kx 2023-04-11 01:18:34 +0300   14)   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11c606a6 (kx 2023-04-11 01:18:34 +0300   15)   implied.
11c606a6 (kx 2023-04-11 01:18:34 +0300   16) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   17)  **********************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300   18) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   19) #include <config.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   20) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   21) #include <stdlib.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   22) #include <stdio.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   23) #include <sys/types.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   24) #include <stdint.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   25) #include <dirent.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   26) #include <sys/stat.h> /* chmod(2)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   27) #include <sys/file.h> /* flock(2)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   28) #include <fcntl.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   29) #include <linux/limits.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   30) #include <alloca.h>   /* alloca(3)   */
11c606a6 (kx 2023-04-11 01:18:34 +0300   31) #include <string.h>   /* strdup(3)   */
11c606a6 (kx 2023-04-11 01:18:34 +0300   32) #include <strings.h>  /* index(3)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   33) #include <libgen.h>   /* basename(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300   34) #include <ctype.h>    /* tolower(3)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300   35) #include <errno.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   36) #include <time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   37) #include <sys/time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   38) #include <pwd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   39) #include <grp.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   40) #include <stdarg.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   41) #include <unistd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   42) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   43) #include <math.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   44) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   45) #include <sys/wait.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   46) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   47) #include <sys/resource.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   48) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   49) #include <signal.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   50) #if !defined SIGCHLD && defined SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   51) # define SIGCHLD SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   52) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300   53) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   54) #define _GNU_SOURCE
11c606a6 (kx 2023-04-11 01:18:34 +0300   55) #include <getopt.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   56) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   57) #include <config.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   58) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   59) #include <msglog.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   60) #include <system.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   61) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   62) #include <cmpvers.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   63) #include <dlist.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   64) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   65) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300   66) #include <dialog-ui.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   67) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300   68) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   69) #define PROGRAM_NAME "remove-package"
11c606a6 (kx 2023-04-11 01:18:34 +0300   70) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   71) #include <defs.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   72) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   73) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   74) char *program = PROGRAM_NAME;
11c606a6 (kx 2023-04-11 01:18:34 +0300   75) char *root = NULL, *pkgs_path = NULL, *rempkgs_path = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   76)      *pkg_fname = NULL, *pkglog_fname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   77)      *tmpdir = NULL, *rtmpdir = NULL, *curdir = NULL, *log_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   78) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   79) int   quiet = 0, ignore_chrefs_errors = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300   80) char *description = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   81) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   82) int   exit_status = EXIT_SUCCESS; /* errors counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300   83) char *selfdir     = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   84) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   85) static char           *pkgname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   86)                        *pkgver = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   87)                          *arch = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   88)                    *distroname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   89)                     *distrover = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   90)                         *group = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   91)             *short_description = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   92)                           *url = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   93)                       *license = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   94)             *uncompressed_size = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   95)               *compressed_size = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   96)                   *total_files = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   97) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   98) static char *requested_version = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   99) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  100) enum _remove_mode {
11c606a6 (kx 2023-04-11 01:18:34 +0300  101)   CONSOLE = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300  102)   INFODIALOG,
11c606a6 (kx 2023-04-11 01:18:34 +0300  103)   MENUDIALOG
11c606a6 (kx 2023-04-11 01:18:34 +0300  104) } remove_mode = CONSOLE;
11c606a6 (kx 2023-04-11 01:18:34 +0300  105) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  106) enum _input_type {
11c606a6 (kx 2023-04-11 01:18:34 +0300  107)   IFMT_PKG = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300  108)   IFMT_LOG,
11c606a6 (kx 2023-04-11 01:18:34 +0300  109) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  110)   IFMT_UNKNOWN
11c606a6 (kx 2023-04-11 01:18:34 +0300  111) } input_format = IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  112) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  113) char  uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  114) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  115) static struct dlist *dirs  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  116) static struct dlist *files = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  117) static struct dlist *links = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  118) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  119) static void free_list( struct dlist *list );
11c606a6 (kx 2023-04-11 01:18:34 +0300  120) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  121) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  122) #define FREE_PKGINFO_VARIABLES() \
11c606a6 (kx 2023-04-11 01:18:34 +0300  123)   if( pkgname )           { free( pkgname );           } pkgname = NULL;            \
11c606a6 (kx 2023-04-11 01:18:34 +0300  124)   if( pkgver )            { free( pkgver );            } pkgver = NULL;             \
11c606a6 (kx 2023-04-11 01:18:34 +0300  125)   if( arch )              { free( arch );              } arch = NULL;               \
11c606a6 (kx 2023-04-11 01:18:34 +0300  126)   if( distroname )        { free( distroname );        } distroname = NULL;         \
11c606a6 (kx 2023-04-11 01:18:34 +0300  127)   if( distrover )         { free( distrover );         } distrover = NULL;          \
11c606a6 (kx 2023-04-11 01:18:34 +0300  128)   if( group )             { free( group );             } group = NULL;              \
11c606a6 (kx 2023-04-11 01:18:34 +0300  129)   if( short_description ) { free( short_description ); } short_description = NULL;  \
11c606a6 (kx 2023-04-11 01:18:34 +0300  130)   if( description )       { free( description );       } description = NULL;        \
11c606a6 (kx 2023-04-11 01:18:34 +0300  131)   if( url )               { free( url );               } url = NULL;                \
11c606a6 (kx 2023-04-11 01:18:34 +0300  132)   if( license )           { free( license );           } license = NULL;            \
11c606a6 (kx 2023-04-11 01:18:34 +0300  133)   if( uncompressed_size ) { free( uncompressed_size ); } uncompressed_size = NULL;  \
11c606a6 (kx 2023-04-11 01:18:34 +0300  134)   if( compressed_size )   { free( compressed_size );   } compressed_size = NULL;    \
11c606a6 (kx 2023-04-11 01:18:34 +0300  135)   if( total_files )       { free( total_files );       } total_files = NULL;        \
11c606a6 (kx 2023-04-11 01:18:34 +0300  136)   if( requested_version ) { free( requested_version ); } requested_version = NULL
11c606a6 (kx 2023-04-11 01:18:34 +0300  137) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  138) void free_resources()
11c606a6 (kx 2023-04-11 01:18:34 +0300  139) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  140)   if( root )          { free( root );          root          = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  141)   if( pkgs_path )     { free( pkgs_path );     pkgs_path     = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  142)   if( rempkgs_path )  { free( rempkgs_path );  rempkgs_path  = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  143)   if( pkg_fname )     { free( pkg_fname );     pkg_fname     = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  144) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  145)   if( dirs )          { free_list( dirs );     dirs          = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  146)   if( files )         { free_list( files );    files         = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  147)   if( links )         { free_list( links );    links         = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  148) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  149)   if( rtmpdir )       { free( rtmpdir );       rtmpdir       = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  150)   if( curdir )        { free( curdir );        curdir        = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  151)   if( log_fname )     { free( log_fname );     log_fname     = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  152) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  153)   if( selfdir )       { free( selfdir );       selfdir       = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  154) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  155)   FREE_PKGINFO_VARIABLES();
11c606a6 (kx 2023-04-11 01:18:34 +0300  156) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  157) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  158) void usage()
11c606a6 (kx 2023-04-11 01:18:34 +0300  159) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  160)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  161) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  162)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  163)   fprintf( stdout, "Usage: %s [options] <package|pkglog|pkgname>\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  164)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  165)   fprintf( stdout, "Remove installed package.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  166)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  167)   fprintf( stdout, "Options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  168)   fprintf( stdout, "  -h,--help                     Display this information.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  169)   fprintf( stdout, "  -v,--version                  Display the version of %s utility.\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  170)   fprintf( stdout, "  --ignore-chrefs-errors        Ignore change references errors (code: 48).\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  171) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  172)   fprintf( stdout, "  -i,--info-dialog              Show package description during remove\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  173)   fprintf( stdout, "                                process using ncurses dialog.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  174)   fprintf( stdout, "  -m,--menu-dialog              Ask for confirmation the removal.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  175) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  176)   fprintf( stdout, "  -q,--quiet                    Do not display results. This option\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  177)   fprintf( stdout, "                                works unless options -i, -m\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  178)   fprintf( stdout, "                                are enabled.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  179)   fprintf( stdout, "  -r,--root=<DIR>               Target rootfs path.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  180)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  181)   fprintf( stdout, "Parameter:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  182)   fprintf( stdout, "  <package|pkglog|pkgname>      The PKGNAME, PACKAGE tarball or PKGLOG.\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  183)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  184)   fprintf( stdout, "Return codes:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  185)   fprintf( stdout, "  ------+-------------------------------------------------------\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  186)   fprintf( stdout, "   code | status\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  187)   fprintf( stdout, "  ------+-------------------------------------------------------\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  188)   fprintf( stdout, "     30 | package is not installed\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  189)   fprintf( stdout, "    ----+----\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  190)   fprintf( stdout, "     47 | cannot backup PKGLOG file in the Setup Database\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  191)   fprintf( stdout, "     43 | pre-remove script returned error status\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  192)   fprintf( stdout, "     46 | post-remove script returned error status\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  193)   fprintf( stdout, "     48 | references cannot be updated in Setup Database\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  194)   fprintf( stdout, "  ------+-------------------------------------------------------\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  195)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  196)   fprintf( stdout, "Upon successful completion zero is returned. Other non-zero return\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  197)   fprintf( stdout, "codes imply incorrect completion of the deinstallation.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  198)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  199) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  200)   exit( EXIT_FAILURE );
11c606a6 (kx 2023-04-11 01:18:34 +0300  201) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  202) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  203) void to_lowercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  204) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  205)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  206)   while( p && *p ) { int c = *p; *p = tolower( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  207) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  208) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  209) void to_uppercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  210) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  211)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  212)   while( p && *p ) { int c = *p; *p = toupper( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  213) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  214) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  215) void version()
11c606a6 (kx 2023-04-11 01:18:34 +0300  216) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  217)   char *upper = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  218) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  219)   upper = (char *)alloca( strlen( program ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  220) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  221)   strcpy( (char *)upper, (const char *)program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  222)   to_uppercase( upper );
11c606a6 (kx 2023-04-11 01:18:34 +0300  223) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  224)   fprintf( stdout, "%s (%s) %s\n", program, upper, PROGRAM_VERSION );
11c606a6 (kx 2023-04-11 01:18:34 +0300  225) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  226)   fprintf( stdout, "Copyright (C) 2019 Andrey V.Kosteltsev.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  227)   fprintf( stdout, "This is free software.   There is NO warranty; not even\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  228)   fprintf( stdout, "for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  229)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  230) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  231)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  232)   exit( EXIT_SUCCESS );
11c606a6 (kx 2023-04-11 01:18:34 +0300  233) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  234) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  235) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  236) static void remove_trailing_slash( char *dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  237) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  238)   char *s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  239) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  240)   if( !dir || dir[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  241) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  242)   s = dir + strlen( dir ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  243)   while( *s == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  244)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  245)     *s = '\0'; --s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  246)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  247) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  248) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  249) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  250) static int _mkdir_p( const char *dir, const mode_t mode )
11c606a6 (kx 2023-04-11 01:18:34 +0300  251) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  252)   char  *buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  253)   char  *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  254)   struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  255) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  256)   if( !dir ) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  257) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  258)   buf = (char *)alloca( strlen( dir ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  259)   strcpy( buf, dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  260) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  261)   remove_trailing_slash( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  262) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  263)   /* check if path exists and is a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  264)   if( stat( buf, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  265)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  266)     if( S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  267)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  268)       return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  269)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  270)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  271) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  272)   /* mkdir -p */
11c606a6 (kx 2023-04-11 01:18:34 +0300  273)   for( p = buf + 1; *p; ++p )
11c606a6 (kx 2023-04-11 01:18:34 +0300  274)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  275)     if( *p == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  276)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  277)       *p = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  278)       /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  279)       if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  280)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  281)         /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  282)         if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  283)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  284)           return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  285)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  286)       } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  287)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  288)         /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  289)         return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  290)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  291)       *p = '/';
11c606a6 (kx 2023-04-11 01:18:34 +0300  292)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  293)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  294) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  295)   /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  296)   if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  297)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  298)     /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  299)     if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  300)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  301)       return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  302)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  303)   } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  304)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  305)     /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  306)     return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  307)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  308) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  309)   return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  310) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  311) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  312) static void _rm_tmpdir( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300  313) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  314)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300  315)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300  316)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  317) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  318)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  319)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300  320) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  321)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  322)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  323)     return; /* stat returns error code; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  324)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  325) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  326)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  327)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  328)     return; /* dirpath is not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  329)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  330) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  331)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  332)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  333)     return; /* Cannot open direcroty; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  334)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  335) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  336)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  337) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  338)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300  339)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  340) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  341)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  342)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300  343) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  344)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300  345)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  346)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  347)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  348)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  349) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  350)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  351)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  352)       if( S_ISDIR(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  353)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  354)         /* recursively remove a nested directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  355)         _rm_tmpdir( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  356)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  357)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  358)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  359)         /* remove a file object */
11c606a6 (kx 2023-04-11 01:18:34 +0300  360)         (void)unlink( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  361)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  362)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  363)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300  364) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  365)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  366) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  367)   /* remove the devastated directory and close the object of this directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  368)   (void)rmdir( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  369) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  370)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  371) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  372) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  373) static char *_mk_tmpdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  374) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  375)   char   *buf = NULL, *p, *tmp = "/tmp";
11c606a6 (kx 2023-04-11 01:18:34 +0300  376)   size_t  len = 0, size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  377) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  378)   (void)umask( S_IWGRP | S_IWOTH ); /* octal 022 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  379) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  380)   /* Get preferred directory for tmp files */
11c606a6 (kx 2023-04-11 01:18:34 +0300  381)   if( (p = getenv( "TMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  382)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  383)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  384)   else if( (p = getenv( "TEMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  385)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  386)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  387) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  388)   size = strlen( tmp ) + strlen( DISTRO_NAME ) + strlen( program ) + 12;
11c606a6 (kx 2023-04-11 01:18:34 +0300  389) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  390)   buf = (char *)malloc( size );
11c606a6 (kx 2023-04-11 01:18:34 +0300  391)   if( !buf ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  392) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  393)   len = snprintf( buf, size, (const char *)"%s/%s/%s-%.7u", tmp, DISTRO_NAME, program, getpid() );
11c606a6 (kx 2023-04-11 01:18:34 +0300  394)   if( len == 0 || len == size - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  395)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  396)     free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  397)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  398) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  399)   _rm_tmpdir( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  400) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  401)   if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  402)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  403)     return buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  404)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  405) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  406)   free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  407) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  408) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  409) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  410) void fatal_error_actions( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  411) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  412)   logmsg( errlog, MSG_NOTICE, "Free resources on FATAL error..." );
11c606a6 (kx 2023-04-11 01:18:34 +0300  413)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  414)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  415) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  416) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  417) void sigint( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  418) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  419)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  420) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  421)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  422)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  423) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  424) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  425) static void set_signal_handlers()
11c606a6 (kx 2023-04-11 01:18:34 +0300  426) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  427)   struct sigaction  sa;
11c606a6 (kx 2023-04-11 01:18:34 +0300  428)   sigset_t          set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  429) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  430)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  431)   sa.sa_handler = sigint;          /* TERM, INT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  432)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  433)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  434)   sigaddset( &set, SIGTERM );
11c606a6 (kx 2023-04-11 01:18:34 +0300  435)   sigaddset( &set, SIGINT );
11c606a6 (kx 2023-04-11 01:18:34 +0300  436)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  437)   sigaction( SIGTERM, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  438)   sigaction( SIGINT, &sa,  NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  439) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  440)   memset( &sa, 0, sizeof( sa ) );  /* ignore SIGPIPE */
11c606a6 (kx 2023-04-11 01:18:34 +0300  441)   sa.sa_handler = SIG_IGN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  442)   sa.sa_flags = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  443)   sigaction( SIGPIPE, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  444) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  445)   /* System V fork+wait does not work if SIGCHLD is ignored */
11c606a6 (kx 2023-04-11 01:18:34 +0300  446)   signal( SIGCHLD, SIG_DFL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  447) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  448) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  449) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  450) static enum _input_type check_input_file( char *uncompress, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  451) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  452)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  453)   size_t pkglog_size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  454)   unsigned char buf[8];
11c606a6 (kx 2023-04-11 01:18:34 +0300  455)   int rc, fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300  456) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  457)   /* SIGNATURES: https://www.garykessler.net/library/file_sigs.html */
11c606a6 (kx 2023-04-11 01:18:34 +0300  458) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  459)   if( uncompress )
11c606a6 (kx 2023-04-11 01:18:34 +0300  460)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  461)     *uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  462)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  463) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  464)   if( stat( fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  465)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  466)     FATAL_ERROR( "Cannot access %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  467)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  468) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  469)   pkglog_size = st.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300  470) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  471)   if( (fd = open( fname, O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  472)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  473)     FATAL_ERROR( "Cannot open %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  474)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  475) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  476)   rc = (int)read( fd, (void *)&buf[0], 7 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  477)   if( rc != 7 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  478)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  479)     close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  480)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  481)   buf[7] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  482) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  483)   /* TEXT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  484)   if( !strncmp( (const char *)&buf[0], "PACKAGE", 7 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  485)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  486)     close( fd ); return IFMT_LOG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  487)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  488) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  489)   /* GZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  490)   if( buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x08 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  491)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  492)     if( uncompress ) { *uncompress = 'x'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  493)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  494)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  495) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  496)   /* BZ2 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  497)   if( buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  498)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  499)     if( uncompress ) { *uncompress = 'j'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  500)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  501)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  502) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  503)   /* XZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  504)   if( buf[0] == 0xFD && buf[1] == 0x37 && buf[2] == 0x7A &&
11c606a6 (kx 2023-04-11 01:18:34 +0300  505)       buf[3] == 0x58 && buf[4] == 0x5A && buf[5] == 0x00   )
11c606a6 (kx 2023-04-11 01:18:34 +0300  506)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  507)     if( uncompress ) { *uncompress = 'J'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  508)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  509)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  510) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  511)   if( pkglog_size > 262 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  512)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  513)     if( lseek( fd, 257, SEEK_SET ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  514)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  515)       FATAL_ERROR( "Cannot check signature of %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  516)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  517)     rc = (int)read( fd, &buf[0], 5 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  518)     if( rc != 5 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  519)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  520)       FATAL_ERROR( "Cannot read signature of %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  521)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  522)     /* TAR */
11c606a6 (kx 2023-04-11 01:18:34 +0300  523)     if( buf[0] == 0x75 && buf[1] == 0x73 && buf[2] == 0x74 && buf[3] == 0x61 && buf[4] == 0x72 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  524)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  525)       close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  526)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  527)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  528) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  529)   close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  530) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  531) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  532) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  533) void get_args( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300  534) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  535) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  536)   const char* short_options = "hvimqr:";
11c606a6 (kx 2023-04-11 01:18:34 +0300  537) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300  538)   const char* short_options = "hvqr:";
11c606a6 (kx 2023-04-11 01:18:34 +0300  539) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  540) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  541) #define IGNORE_CHREFS_ERRORS 872
11c606a6 (kx 2023-04-11 01:18:34 +0300  542) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  543)   const struct option long_options[] =
11c606a6 (kx 2023-04-11 01:18:34 +0300  544)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  545)     { "help",                 no_argument,       NULL, 'h' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  546)     { "version",              no_argument,       NULL, 'v' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  547)     { "ignore-chrefs-errors", no_argument,       NULL, IGNORE_CHREFS_ERRORS },
11c606a6 (kx 2023-04-11 01:18:34 +0300  548) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  549)     { "info-dialog",          no_argument,       NULL, 'i' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  550)     { "menu-dialog",          no_argument,       NULL, 'm' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  551) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  552)     { "quiet",                no_argument,       NULL, 'q' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  553)     { "root",                 required_argument, NULL, 'r' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  554)     { NULL,                   0,                 NULL,  0  }
11c606a6 (kx 2023-04-11 01:18:34 +0300  555)   };
11c606a6 (kx 2023-04-11 01:18:34 +0300  556) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  557)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  558)   int option_index = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  559) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  560)   while( (ret = getopt_long( argc, argv, short_options, long_options, &option_index )) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  561)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  562)     switch( ret )
11c606a6 (kx 2023-04-11 01:18:34 +0300  563)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  564)       case 'h':
11c606a6 (kx 2023-04-11 01:18:34 +0300  565)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  566)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  567)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  568)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  569)       case 'v':
11c606a6 (kx 2023-04-11 01:18:34 +0300  570)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  571)         version();
11c606a6 (kx 2023-04-11 01:18:34 +0300  572)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  573)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  574) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  575) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  576)       case 'i':
11c606a6 (kx 2023-04-11 01:18:34 +0300  577)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  578)         remove_mode = INFODIALOG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  579)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  580)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  581)       case 'm':
11c606a6 (kx 2023-04-11 01:18:34 +0300  582)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  583)         remove_mode = MENUDIALOG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  584)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  585)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  586) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  587)       case 'q':
11c606a6 (kx 2023-04-11 01:18:34 +0300  588)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  589)         quiet = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  590)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  591)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  592) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  593)       case IGNORE_CHREFS_ERRORS:
11c606a6 (kx 2023-04-11 01:18:34 +0300  594)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  595)         ignore_chrefs_errors = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  596)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  597)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  598) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  599)       case 'r':
11c606a6 (kx 2023-04-11 01:18:34 +0300  600)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  601)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  602)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  603)           char cwd[PATH_MAX];
11c606a6 (kx 2023-04-11 01:18:34 +0300  604) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  605)           bzero( (void *)cwd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  606)           if( optarg[0] != '/' && curdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  607)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  608)             /* skip current directory definition './' at start of argument: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  609)             if( !strncmp( optarg, "./", 2 ) && strncmp( optarg, "..", 2 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  610)               (void)sprintf( cwd, "%s/%s", curdir, optarg + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  611)             else if( (strlen( optarg ) == 1) && !strncmp( optarg, ".", 1 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  612)               (void)sprintf( cwd, "%s", curdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  613)             else
11c606a6 (kx 2023-04-11 01:18:34 +0300  614)               (void)sprintf( cwd, "%s/%s", curdir, optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  615)             root = strdup( (const char *)cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300  616)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  617)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300  618)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  619)             root = strdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  620)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  621)           remove_trailing_slash( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  622)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  623)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  624)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  625)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  626)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  627)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  628) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  629)       case '?': default:
11c606a6 (kx 2023-04-11 01:18:34 +0300  630)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  631)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  632)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  633)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  634)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  635)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  636) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  637) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  638)   if( optind < argc )
11c606a6 (kx 2023-04-11 01:18:34 +0300  639)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  640)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  641)     char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  642) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  643)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  644) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  645)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  646)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  647)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  648) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  649)     /* absolute path to input package: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  650)     if( argv[optind][0] != '/' && curdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  651)       (void)sprintf( buf, "%s/%s", curdir, (const char *)argv[optind] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  652)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  653)       (void)strcpy( buf, (const char *)argv[optind] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  654) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  655)     pkg_fname = strdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  656)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  657)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  658)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  659)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  660)     usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  661)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  662) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  663) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  664)   if( !pkgs_path )
11c606a6 (kx 2023-04-11 01:18:34 +0300  665)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  666)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  667)     char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  668)     int    len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  669) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  670)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  671) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  672)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  673)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  674)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  675) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  676)     if( !root )
11c606a6 (kx 2023-04-11 01:18:34 +0300  677)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  678)       buf[0] = '/'; buf[1] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  679)       root = strdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  680)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  681)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  682)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  683)       len = strlen( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  684) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  685)       (void)strcpy( buf, (const char *)root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  686)       if( buf[ len - 1 ] != '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  687)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  688)         buf[len] = '/'; buf[len+1] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  689)         free( root ); root = strdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  690)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  691)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  692) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  693)     if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  694)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  695)       FATAL_ERROR( "Cannot access '%s' file or directory: %s", buf, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  696)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  697)     if( !S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  698)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  699)       FATAL_ERROR( "Defined --root '%s' is not a directory", buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  700)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  701) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  702)     len = strlen( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  703) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  704)     (void)strcat( buf, PACKAGES_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300  705)     if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  706)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  707)       FATAL_ERROR( "Cannot access '/%s' directory", PACKAGES_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300  708)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  709)     pkgs_path = strdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  710) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  711)     /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  712)       Create other directories of Setup Database:
11c606a6 (kx 2023-04-11 01:18:34 +0300  713)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  714)     buf[len] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  715)     (void)strcat( buf, REMOVED_PKGS_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300  716)     if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  717)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  718)       FATAL_ERROR( "Cannot access '/%s' directory", REMOVED_PKGS_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300  719)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  720)     rempkgs_path = strdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  721) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  722)     buf[len] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  723)     (void)strcat( buf, SETUP_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300  724)     if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  725)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  726)       FATAL_ERROR( "Cannot access '/%s' directory", SETUP_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300  727)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  728) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  729)     /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  730)       Allocate memory for Setup LOG File name:
11c606a6 (kx 2023-04-11 01:18:34 +0300  731)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  732)     buf[len] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  733)     (void)strcat( buf, LOG_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300  734)     (void)strcat( buf, SETUP_LOG_FILE );
11c606a6 (kx 2023-04-11 01:18:34 +0300  735)     log_fname = strdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  736) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  737)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  738) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  739)   } /* End if( !pkgs_path ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300  740) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  741) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  742) static void setup_log( char *format, ... )
11c606a6 (kx 2023-04-11 01:18:34 +0300  743) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  744)   FILE *fp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  745) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  746)   time_t     t = time( NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  747)   struct tm tm = *localtime(&t);
11c606a6 (kx 2023-04-11 01:18:34 +0300  748) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  749)   va_list argp;
11c606a6 (kx 2023-04-11 01:18:34 +0300  750) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  751)   if( ! format ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  752) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  753)   fp = fopen( (const char *)log_fname, "a" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  754)   if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300  755)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  756)     FATAL_ERROR( "Cannot open /%s%s file", LOG_PATH, SETUP_LOG_FILE );
11c606a6 (kx 2023-04-11 01:18:34 +0300  757)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  758) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  759)   fprintf( fp, "[%04d-%02d-%02d %02d:%02d:%02d]: ",
11c606a6 (kx 2023-04-11 01:18:34 +0300  760)                   tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
11c606a6 (kx 2023-04-11 01:18:34 +0300  761)                                  tm.tm_hour, tm.tm_min, tm.tm_sec );
11c606a6 (kx 2023-04-11 01:18:34 +0300  762) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  763)   va_start( argp, format );
11c606a6 (kx 2023-04-11 01:18:34 +0300  764)   vfprintf( fp, format, argp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  765)   fprintf( fp, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  766) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  767)   fflush( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  768)   fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  769) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  770) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  771) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  772)   Remove leading spaces and take non-space characters only:
11c606a6 (kx 2023-04-11 01:18:34 +0300  773)   (Especialy for pkginfo lines)
11c606a6 (kx 2023-04-11 01:18:34 +0300  774)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  775) static char *skip_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  776) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  777)   char *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  778) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  779)   if( !s || *s == '\0' ) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  780) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  781)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  782) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  783)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  784)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  785) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  786)   if( *p == '\0' ) return (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  787) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  788)   return( strdup( p ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  789) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  790) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  791) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  792) /*******************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  793)   remove spaces at end of line:
11c606a6 (kx 2023-04-11 01:18:34 +0300  794)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  795) static void skip_eol_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  796) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  797)   char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  798) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  799)   if( !s || *s == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  800) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  801)   p = s + strlen( s ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  802)   while( isspace( *p ) ) { *p-- = '\0'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  803) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  804) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  805) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  806) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  807) /********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  808)   Read .FILELIST and .RESTORELINKS functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  809)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  810) static int __cmp_list_items( const void *a, const void *b )
11c606a6 (kx 2023-04-11 01:18:34 +0300  811) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  812)   if( a && b )
11c606a6 (kx 2023-04-11 01:18:34 +0300  813)     return strcmp( (const char *)a, (const char *)b );
11c606a6 (kx 2023-04-11 01:18:34 +0300  814)   else if( a )
11c606a6 (kx 2023-04-11 01:18:34 +0300  815)     return 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  816)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  817)     return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  818) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  819) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  820) static void __free_list( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300  821) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  822)   if( data ) { free( data ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  823) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  824) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  825) static void free_list( struct dlist *list )
11c606a6 (kx 2023-04-11 01:18:34 +0300  826) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  827)   if( list ) { dlist_free( list, __free_list ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  828) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  829) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  830) ////////////////////////////////////////////////////
11c606a6 (kx 2023-04-11 01:18:34 +0300  831) //static void __print_list( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300  832) //{
11c606a6 (kx 2023-04-11 01:18:34 +0300  833) //  int *counter = (int *)user_data;
11c606a6 (kx 2023-04-11 01:18:34 +0300  834) //
11c606a6 (kx 2023-04-11 01:18:34 +0300  835) //  if( counter ) { fprintf( stdout, "item[%.5d]: %s\n", *counter, (char *)data ); ++(*counter); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  836) //  else          { fprintf( stdout, "item: %s\n", (char *)data ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  837) //}
11c606a6 (kx 2023-04-11 01:18:34 +0300  838) //
11c606a6 (kx 2023-04-11 01:18:34 +0300  839) //static void print_list( struct dlist *list )
11c606a6 (kx 2023-04-11 01:18:34 +0300  840) //{
11c606a6 (kx 2023-04-11 01:18:34 +0300  841) //  int cnt = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  842) //  if( list ) { dlist_foreach( list, __print_list, (void *)&cnt ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  843) //}
11c606a6 (kx 2023-04-11 01:18:34 +0300  844) ////////////////////////////////////////////////////
11c606a6 (kx 2023-04-11 01:18:34 +0300  845) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  846) static void read_filelist( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  847) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  848)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  849)   FILE  *fp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  850) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  851)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  852)   char *line = NULL, *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  853) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  854)   tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  855)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  856)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  857) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  858)   (void)sprintf( &tmp[0], "%s/.FILELIST", rtmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  859)   bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  860)   if( (stat( (const char *)&tmp[0], &st ) == -1) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  861)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  862)     FATAL_ERROR( "Cannot get .FILELIST from '%s' file", basename( (char *)pkglog_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  863)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  864) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  865)   fp = fopen( (const char *)&tmp[0], "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  866)   if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300  867)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  868)     FATAL_ERROR( "Cannot open .FILELIST file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  869)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  870) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  871)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  872)   if( !line ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  873)   bzero( (void *)line, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  874) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  875)   while( (ln = fgets( line, PATH_MAX, fp )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  876)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  877)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  878)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300  879) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  880)     if( *(ln + strlen(ln) - 1) == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  881)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  882)       *(ln + strlen(ln) - 1) = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  883)       (void)sprintf( &tmp[0], "%s%s", (const char *)root, (const char *)ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300  884)       dirs = dlist_append( dirs, strdup( (const char *)&tmp[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  885)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  886)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  887)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  888)       (void)sprintf( &tmp[0], "%s%s", (const char *)root, (const char *)ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300  889)       files = dlist_append( files, strdup( (const char *)&tmp[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  890)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  891) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  892)   } /* End of while( file list entry ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300  893) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  894)   fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  895) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  896)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300  897)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  898) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  899) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  900) static void read_restorelinks( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  901) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  902)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  903)   FILE  *fp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  904) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  905)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  906)   char *line = NULL, *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  907) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  908)   tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  909)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  910)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  911) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  912)   (void)sprintf( &tmp[0], "%s/.RESTORELINKS", rtmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  913)   bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  914)   if( (stat( (const char *)&tmp[0], &st ) == -1) || (st.st_size < 8) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  915)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  916)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  917)     return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  918)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  919) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  920)   fp = fopen( (const char *)&tmp[0], "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  921)   if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300  922)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  923)     FATAL_ERROR( "Cannot open .RESTORELINKS file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  924)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  925) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  926)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  927)   if( !line ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  928)   bzero( (void *)line, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  929) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  930)   while( (ln = fgets( line, PATH_MAX, fp )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  931)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  932)     char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  933) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  934)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  935)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300  936) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  937)     if( (match = strstr( ln, "; rm -rf " )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  938)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  939)       char *q = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  940)       char *p = strstr( ln, "cd" ) + 2;
11c606a6 (kx 2023-04-11 01:18:34 +0300  941)       char *f = strstr( ln, "; rm -rf" ) + 8;
11c606a6 (kx 2023-04-11 01:18:34 +0300  942) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  943)       if( !p || !f ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300  944) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  945)       while( (*p == ' ' || *p == '\t') && *p != '\0' ) ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  946)       while( (*f == ' ' || *f == '\t') && *f != '\0' ) ++f;
11c606a6 (kx 2023-04-11 01:18:34 +0300  947) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  948)       q = p; while( *q != ' ' && *q != '\t' && *q != ';' && *q != '\0' ) ++q; *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  949)       q = f; while( *q != ' ' && *q != '\t' && *q != ';' && *q != '\0' ) ++q; *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  950) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  951)       if( p && f )
11c606a6 (kx 2023-04-11 01:18:34 +0300  952)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  953)         (void)sprintf( &tmp[0], "%s%s/%s", (const char *)root, p, f );
11c606a6 (kx 2023-04-11 01:18:34 +0300  954)         links = dlist_append( links, strdup( (const char *)&tmp[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  955)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  956)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  957)   } /* End of while( restore links entry ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300  958) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  959)   fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  960) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  961)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300  962)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  963) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  964) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  965)   End of read .FILELIST and .RESTORELINKS functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300  966)  ********************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  967) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  968) static void read_description( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  969) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  970)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  971)   FILE  *fp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  972) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  973)   char  *buf = NULL, *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  974)   char  *lp  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  975)   int    n   = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  976) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  977)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  978)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  979) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  980)   tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  981)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  982)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  983) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  984)   buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  985)   if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  986)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  987) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  988)   (void)sprintf( &tmp[0], "%s/.DESCRIPTION", rtmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  989)   bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  990)   if( (stat( (const char *)&tmp[0], &st ) == -1) || (st.st_size < 8) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  991)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  992)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  993)     return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  994)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  995) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  996)   fp = fopen( (const char *)&tmp[0], "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  997)   if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300  998)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  999)     FATAL_ERROR( "Cannot open .DESCRIPTION file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1000)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1001) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1002)   (void)sprintf( (char *)&buf[0], "%s:", pkgname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1003) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1004)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1005)   if( !line ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1006)   bzero( (void *)line, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1007) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1008)   lp = (char *)&tmp[0];
11c606a6 (kx 2023-04-11 01:18:34 +0300 1009)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1010)   (void)sprintf( (char *)&tmp[0], "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1011)   ++lp;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1012) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1013)   while( (ln = fgets( line, PATH_MAX, fp )) && n < DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1014)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1015)     char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1016) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1017)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1018) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1019)     if( (match = strstr( (const char *)ln, (const char *)buf )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1020)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1021)       int mlen   = strlen( match ), plen = strlen( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1022)       int length = ( mlen > plen )  ? (mlen - plen - 1) : 0 ;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1023) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1024)       if( length > DESCRIPTION_LENGTH_OF_LINE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1025)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1026)         /* WARNING( "Package DESCRIPTION contains lines with length greater than %d characters", DESCRIPTION_LENGTH_OF_LINE ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1027)         match[plen + 1 + DESCRIPTION_LENGTH_OF_LINE] = '\0'; /* truncating description line  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1028)         skip_eol_spaces( match );                            /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1029)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1030) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1031)       match += plen + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1032)       if( match[0] != '\0' ) { (void)sprintf( lp, " %s\n", match ); lp += strlen( match ) + 2; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1033)       else                   { (void)sprintf( lp, "\n" ); ++lp; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1034)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1035)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1036)   } /* End of while( ln = fgets() ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1037) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1038)   fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1039) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1040)   (void)sprintf( lp, " Uncompressed Size: %s\n", uncompressed_size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1041)   lp += strlen( uncompressed_size ) + 21;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1042) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1043)   description = strdup( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1044) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1045)   free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1046)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1047)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1048) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1049) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1050) static void pre_remove_routine( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1051) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1052)   pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1053)   int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1054) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1055)   int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1056)   char *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1057) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1058)   cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1059)   if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1060)   bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1061) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1062)   len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1063)                   "cd %s && %s/.INSTALL pre_remove %s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1064)                   root, rtmpdir, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1065)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1066)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1067)     FATAL_ERROR( "Cannot run pre-remove script for '%s-%s' package", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1068)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1069)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1070)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1071) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1072)   free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1073) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1074)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1075)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1076)     exit_status = 43;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1077) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1078)     if( remove_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1079)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1080) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1081)       info_pkg_box( "Remove:", pkgname, pkgver, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1082)                     "\n\\Z1Pre-remove script returned error status.\\Zn\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1083) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1084)       fprintf( stdout, "\nPre-remove script of '%s-%s' returned error status.\n\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1085) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1086)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1087)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1088)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1089)       fprintf( stdout, "\nPre-remove script of '%s-%s' returned error status.\n\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1090)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1091) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1092)     if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1093)     free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1094)     exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1095)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1096) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1097) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1098) /********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1099)   Removal functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1100)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1101) static void __remove_link( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1102) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1103)   const char *fname = (const char *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1104) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1105)   if( fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1106)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1107)     (void)unlink( fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1108)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1109) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1110) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1111) static void __remove_file( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1112) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1113)   const char *fname = (const char *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1114) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1115)   if( fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1116)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1117)     char *p = rindex( fname, '.' );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1118)     /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1119)       Если .new файл остался с тем же именем, это значит что до инсталляции
11c606a6 (kx 2023-04-11 01:18:34 +0300 1120)       в системе существовал такой же файл но без расширения .new и при этом
11c606a6 (kx 2023-04-11 01:18:34 +0300 1121)       он отличался от нового. В данном случае надо удалять только файл .new.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1122) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1123)       Если же файл .new не существует, то надо удалять такой же файл но без
11c606a6 (kx 2023-04-11 01:18:34 +0300 1124)       расширения .new .
11c606a6 (kx 2023-04-11 01:18:34 +0300 1125)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1126)     if( p && !strncmp( (const char *)p, ".new", 4 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1127)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1128)       struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1129) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1130)       bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1131)       if( (stat( fname, &st ) == -1) ) *p = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1132)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1133) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1134)     (void)unlink( fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1135)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1136) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1137) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1138) static int is_dir_empty( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1139) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1140)   int ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1141) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1142)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1143)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1144)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1145) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1146)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1147)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1148) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1149)   if( stat( dirpath, &path_sb ) == -1 )   return ret; /* stat returns error code; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1150)   if( S_ISDIR(path_sb.st_mode) == 0 )     return ret; /* dirpath is not a directory            */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1151)   if( (dir = opendir(dirpath) ) == NULL ) return ret; /* Cannot open direcroty; errno is set   */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1152) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1153)   ret = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1154) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1155)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1156)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1157)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1158)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1159)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1160) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1161)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1162)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1163)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1164)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1165)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1166) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1167)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1168)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1169)       ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1170)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1171)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1172)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1173)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1174)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1175) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1176)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1177) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1178) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1179) static void __remove_dir( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1180) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1181)   const char *dname = (const char *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1182) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1183)   if( dname && is_dir_empty( (const char *)dname ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1184)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1185)     (void)rmdir( dname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1186)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1187) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1188) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1189) static void remove_package( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1190) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1191)   /* Try to change CWD to the ROOT directory: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1192)   (void)chdir( (const char *)root );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1193) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1194)   if( links ) { dlist_foreach( links, __remove_link, NULL ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1195) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1196)   if( files ) { dlist_foreach( files, __remove_file, NULL ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1197) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1198)   if( dirs )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1199)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1200)     dirs = dlist_sort( dirs, __cmp_list_items );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1201)     dirs = dlist_reverse( dirs );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1202)     dlist_foreach( dirs, __remove_dir, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1203)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1204) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1205)   /* Try to change CWD to the CURRENT directory: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1206)   (void)chdir( (const char *)curdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1207) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1208) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1209)   End of removal functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1210)  ********************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1211) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1212) static void post_remove_routine( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1213) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1214)   pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1215)   int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1216) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1217)   int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1218)   char *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1219) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1220)   cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1221)   if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1222)   bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1223) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1224)   len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1225)                   "cd %s && %s/.INSTALL post_remove %s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1226)                   root, rtmpdir, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1227)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1228)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1229)     FATAL_ERROR( "Cannot run post-remove script for '%s-%s' package", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1230)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1231)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1232)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1233) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1234)   free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1235) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1236)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1237)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1238)     exit_status = 46;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1239) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1240)     if( remove_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1241)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1242) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1243)       info_pkg_box( "Remove:", pkgname, pkgver, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1244)                     "\n\\Z1Post-remove script returned error status.\\Zn\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1245) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1246)       fprintf( stdout, "\nPost-remove script of '%s-%s' returned error status.\n\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1247) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1248)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1249)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1250)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1251)       fprintf( stdout, "\nPost-remove script of '%s-%s' returned error status.\n\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1252)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1253) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1254)     if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1255)     free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1256)     exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1257)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1258) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1259) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1260) static void finalize_removal( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1261) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1262)   pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1263)   int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1264) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1265)   int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1266)   char *cmd = NULL, *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1267) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1268)   cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1269)   if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1270)   bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1271) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1272)   tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1273)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1274)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1275) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1276)   /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1277)     Decrement references in the Setup Database:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1278)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1279)   if( group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1280)     len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1281)                     "%s/chrefs --operation=dec --destination=%s %s/%s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1282)                     selfdir, pkgs_path, group, basename( (char *)pkglog_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1283)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1284)     len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1285)                     "%s/chrefs --operation=dec --destination=%s %s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1286)                     selfdir, pkgs_path, basename( (char *)pkglog_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1287)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1288)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1289)     FATAL_ERROR( "Cannot decrement '%s-%s' package references", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1290)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1291)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1292)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1293)   if( (rc != 0) && !ignore_chrefs_errors )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1294)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1295)     free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1296)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1297) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1298)     exit_status = 48;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1299) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1300)     if( remove_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1301)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1302) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1303)       info_pkg_box( "Remove:", pkgname, pkgver, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1304)                     "\n\\Z1Cannot decrement package references in Setup Database.\\Zn\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1305) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1306)       fprintf( stdout, "\nCannot decrement '%s-%s' package references in Setup Database.\n\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1307) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1308)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1309)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1310)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1311)       if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1312)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1313)         fprintf( stdout, "\nCannot decrement '%s-%s' package references in Setup Database.\n\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1314)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1315)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1316) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1317)     if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1318)     free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1319)     exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1320)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1321) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1322)   /*****************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1323)     Backup PKGLOG file into removed-packages directory:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1324)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1325)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1326) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1327)   if( group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1328)     (void)sprintf( &tmp[0], "%s/%s/", rempkgs_path, group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1329)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1330)     (void)sprintf( &tmp[0], "%s/", rempkgs_path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1331) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1332)   if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1333)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1334)     FATAL_ERROR( "Cannot access '/%s' directory", REMOVED_PKGS_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1335)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1336) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1337)   bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1338) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1339)   len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1340)                   "mv %s %s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1341)                   pkglog_fname, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1342)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1343)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1344)     FATAL_ERROR( "Cannot backup '%s' pkglog file", basename( (char *)pkglog_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1345)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1346)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1347)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1348) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1349)   free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1350) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1351)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1352)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1353)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1354) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1355)     exit_status = 47;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1356) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1357)     if( remove_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1358)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1359) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1360)       info_pkg_box( "Remove:", pkgname, pkgver, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1361)                     "\n\\Z1Cannot backup PKGLOG file.\\Zn\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1362) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1363)       fprintf( stdout, "\nCannot backup '%s' pkglog file.\n\n", basename( (char *)pkglog_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1364) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1365)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1366)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1367)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1368)       if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1369)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1370)         fprintf( stdout, "\nCannot backup '%s' pkglog file.\n\n", basename( (char *)pkglog_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1371)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1372)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1373) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1374)     if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1375)     free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1376)     exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1377)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1378) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1379)   /****************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1380)     Remove group directory if it is empty:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1381)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1382)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1383) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1384)   if( group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1385)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1386)     (void)sprintf( &tmp[0], "%s/%s/", pkgs_path, group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1387) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1388)     const char *dir = (const char *)&tmp[0];
11c606a6 (kx 2023-04-11 01:18:34 +0300 1389)     if( is_dir_empty( dir ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1390)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1391)       (void)rmdir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1392)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1393)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1394) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1395)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1396) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1397) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1398) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1399) static int ask_for_remove( int prev )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1400) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1401)   int ret = 0; /* continue removal */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1402) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1403)   /******************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1404)     Ask for remove dialog shown only in MENUDIALOG mode:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1405)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1406)   if( (remove_mode == MENUDIALOG) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1407)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1408)     if( prev < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1409)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1410)       char *msg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1411) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1412)       msg = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1413)       if( !msg ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1414)       bzero( (void *)msg, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1415) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1416)       (void)sprintf( &msg[0], "\nPrevious version '\\Z4%s\\Zn' of requested package installed.\n"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1417)                               "\n\\Z1Remove a previous vesion?\\Zn\n", pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1418) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1419)       ret =  ask_remove_box( "Remove:", pkgname, requested_version, (const char *)&msg[0], 9, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1420) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1421)       free( msg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1422)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1423)     else if( prev > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1424)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1425)       char *msg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1426) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1427)       msg = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1428)       if( !msg ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1429)       bzero( (void *)msg, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1430) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1431)       (void)sprintf( &msg[0], "\nA newer version '\\Z4%s\\Zn' of requested package installed.\n"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1432)                               "\n\\Z1Remove a newer vesion?\\Zn\n", pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1433) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1434)       ret =  ask_remove_box( "Remove:", pkgname, requested_version, (const char *)&msg[0], 9, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1435) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1436)       free( msg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1437)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1438)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1439)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1440)       ret =  ask_remove_box( "Remove:", pkgname, pkgver, description, 18, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1441)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1442)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1443) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1444)   if( ret )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1445)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1446)     info_pkg_box( "Remove:", pkgname, pkgver, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1447)                   "\nPackage removal terminated by user.\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1448)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1449) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1450)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1451) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1452) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1453) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1454) static void show_removal_progress( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1455) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1456)   if( remove_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1457)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1458) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1459)     info_pkg_box( "Remove:", pkgname, pkgver, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1460)                   description, 16, 1, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1461) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1462)     fprintf( stdout, "\n Remobe: %s-%s ...\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1463)     /*************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1464)       Ruler: 68 characters + 2 spaces left and right:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1465) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1466)                       | ----handy-ruler----------------------------------------------------- | */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1467)     fprintf( stdout, "|======================================================================|\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1468)     fprintf( stdout, "%s\n", description );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1469)     fprintf( stdout, "|======================================================================|\n\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1470) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1471)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1472)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1473)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1474)     if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1475)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1476)       fprintf( stdout, "\n Remove: %s-%s ...\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1477)       /*************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1478)         Ruler: 68 characters + 2 spaces left and right:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1479) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1480)                         | ----handy-ruler----------------------------------------------------- | */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1481)       fprintf( stdout, "|======================================================================|\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1482)       fprintf( stdout, "%s\n", description );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1483)       fprintf( stdout, "|======================================================================|\n\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1484)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1485)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1486) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1487) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1488) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1489) static void read_pkginfo( const char *pkginfo_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1490) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1491)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1492)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1493) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1494)   FILE *pkginfo = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1495) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1496)   if( pkginfo_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1497)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1498)     pkginfo = fopen( (const char *)pkginfo_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1499)     if( !pkginfo )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1500)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1501)       FATAL_ERROR( "Cannot open %s file", pkginfo_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1502)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1503)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1504) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1505)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1506)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1507)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1508)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1509)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1510) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1511)   while( (ln = fgets( line, PATH_MAX, pkginfo )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1512)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1513)     char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1514) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1515)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1516)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1517) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1518)     if( (match = strstr( ln, "pkgname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1519)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1520)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1521)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1522)         if( pkgname ) { free( pkgname ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1523)         pkgname = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1524)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1525)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1526)     if( (match = strstr( ln, "pkgver" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1527)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1528)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1529)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1530)         if( pkgver ) { free( pkgver ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1531)         pkgver = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1532)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1533)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1534)     if( (match = strstr( ln, "arch" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1535)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1536)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1537)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1538)         if( arch ) { free( arch ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1539)         arch = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1540)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1541)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1542)     if( (match = strstr( ln, "distroname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1543)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1544)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1545)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1546)         if( distroname ) { free( distroname ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1547)         distroname = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1548)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1549)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1550)     if( (match = strstr( ln, "distrover" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1551)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1552)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1553)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1554)         if( distrover ) { free( distrover ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1555)         distrover = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1556)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1557)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1558) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1559)     if( (match = strstr( ln, "group" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1560)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1561)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1562)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1563)         if( group ) { free( group ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1564)         group = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1565)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1566)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1567) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1568)     if( (match = strstr( ln, "short_description" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1569)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1570)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1571)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1572)         char *b =  index( p, '"'),
11c606a6 (kx 2023-04-11 01:18:34 +0300 1573)              *e = rindex( p, '"');
11c606a6 (kx 2023-04-11 01:18:34 +0300 1574)         if( b && e && ( b != e ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1575)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1576)           p = ++b; *e = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1577)           if( short_description ) { free( short_description ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1578)           short_description = strdup( (const char *)p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1579)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1580)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1581)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1582)     if( (match = strstr( ln, "url" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1583)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1584)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1585)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1586)         if( url ) { free( url ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1587)         url = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1588)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1589)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1590)     if( (match = strstr( ln, "license" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1591)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1592)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1593)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1594)         if( license ) { free( license ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1595)         license = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1596)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1597)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1598) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1599)     if( (match = strstr( ln, "uncompressed_size" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1600)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1601)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1602)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1603)         if( uncompressed_size ) { free( uncompressed_size ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1604)         uncompressed_size = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1605)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1606)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1607)     if( (match = strstr( ln, "total_files" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1608)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1609)       if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1610)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1611)         if( total_files ) { free( total_files ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1612)         total_files = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1613)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1614)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1615)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1616) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1617)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1618) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1619)   if( !pkgname || !pkgver || !arch || !distroname || !distrover )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1620)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1621)     FATAL_ERROR( "Invalid input .PKGINFO file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1622)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1623) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1624)   fclose( pkginfo );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1625) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1626) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1627) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1628) /***************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1629)   Probe functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1630)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1631) static void _probe_pkglog( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1632) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1633)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1634)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1635)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1636) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1637)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1638)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1639) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1640)   if( pkglog_fname ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1641) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1642)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1643)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1644)     FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1645)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1646) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1647)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1648)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1649)     FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1650)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1651) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1652)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1653)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1654)     FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1655)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1656) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1657)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1658) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1659)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1660)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1661)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1662)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1663) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1664)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1665)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1666) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1667)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1668)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1669)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1670) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1671)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1672)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1673)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1674)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1675)         char *match  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1676)         char *pkglog = basename( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1677) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1678)         if( (match = strstr( pkglog, (const char *)basename( pkg_fname ) )) && match == pkglog )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1679)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1680)           char *buf = NULL, *p = NULL, *q = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1681) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1682)           p = q = buf = strdup( (const char *)pkglog );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1683)           ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1684)           while( *p != '\0' && !isblank(*p) && !(*q == '-' && isdigit(*p)) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1685)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1686)             /* package version starts with a number and separated by '-' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1687)             ++p; ++q;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1688)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1689)           *(--p) = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1690) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1691)           /*******************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1692)             We have to make sure that the name we are looking for
11c606a6 (kx 2023-04-11 01:18:34 +0300 1693)             is not shorter than the name of the found package.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1694)            */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1695)           if( strlen(pkg_fname) >= strlen(buf) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1696)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1697) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1698)             pkglog_fname = strdup( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1699)             free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1700)             closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1701)             return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1702)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1703)           free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1704)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1705)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1706)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1707)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1708)         _probe_pkglog( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1709)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1710)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1711)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1712)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1713) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1714)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1715) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1716) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1717) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1718)   probe_package():
11c606a6 (kx 2023-04-11 01:18:34 +0300 1719)   ---------------
11c606a6 (kx 2023-04-11 01:18:34 +0300 1720)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1721) static char *probe_package( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1722) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1723)   char *ret = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1724) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1725)   _probe_pkglog( (const char *)pkgs_path, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1726)   if( pkglog_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1727)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1728)     free( pkg_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1729)     ret = pkg_fname = pkglog_fname;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1730)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1731) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1732)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1733) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1734) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1735)   Enf of Probe functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1736)  ***********************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1737) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1738) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1739)   Find functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1740)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1741) static void _search_pkglog( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1742) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1743)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1744)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1745)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1746) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1747)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1748)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1749) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1750)   char   *pname = (char *)dirpath + strlen( root ); /* do not remove leading '/' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1751) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1752)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1753)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1754)     FATAL_ERROR( "%s: Cannot stat Setup Database or group directory", pname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1755)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1756) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1757)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1758)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1759)     FATAL_ERROR( "%s: Setup Database or group is not a directory", pname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1760)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1761) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1762)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1763)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1764)     FATAL_ERROR( "Canot access %s directory: %s", pname, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1765)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1766) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1767)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1768) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1769)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1770)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1771)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1772)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1773) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1774)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1775)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1776) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1777)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1778)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1779)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1780) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1781)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1782)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1783)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1784)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1785)         char *match = NULL, *name  = basename( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1786) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1787)         if( (match = strstr( name, pkgname )) && match == name )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1788)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1789)           /****************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1790)             Здесь мы еще должны проверить, что найденный пакет не имеет
11c606a6 (kx 2023-04-11 01:18:34 +0300 1791)             более длинное имя, которое начинается с имени искомого пакета.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1792)             Полагаясь на факт, что версия может начинаться только с цифры,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1793)             мы пропускаем символ '-', разделяющий имя и версию пакета,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1794)             а затем проверяем начальный символ версии:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1795)            */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1796)           if( *(name + strlen( pkgname )) == '-' && isdigit( *(name + strlen( pkgname ) + 1) ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1797)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1798)             pkglog_fname = strdup( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1799)             closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1800)             return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1801)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1802)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1803)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1804)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1805)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1806)         /**************************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1807)           NOTE:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1808)             In the Setup Database can be only one package with the same pkgname
11c606a6 (kx 2023-04-11 01:18:34 +0300 1809)             but in different groups. For example, the package named 'cairo'
11c606a6 (kx 2023-04-11 01:18:34 +0300 1810)             has two instance: libs/cairo-1.14.6 and xlibs/cairo-1.14.6. During
11c606a6 (kx 2023-04-11 01:18:34 +0300 1811)             system installation the package libs/cairo-1.14.6 installed first
11c606a6 (kx 2023-04-11 01:18:34 +0300 1812)             and then updated by xlibs/cairo-1.14.6 and PKGLOG of libs/cairo-1.14.6
11c606a6 (kx 2023-04-11 01:18:34 +0300 1813)             moved from /var/log/radix/packages to /var/log/radix/removed-packages.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1814) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1815)             So here we have to look for the PKGLOG in all group directories:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1816)          */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1817)         _search_pkglog( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1818)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1819)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1820)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1821)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1822) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1823)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1824) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1825) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1826) static char *find_package( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1827) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1828)   char *ret = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1829) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1830)   _search_pkglog( (const char *)pkgs_path, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1831)   if( pkglog_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1832)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1833)     free( pkg_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1834)     ret = pkg_fname = pkglog_fname;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1835)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1836) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1837)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1838) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1839) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1840)   Enf of Find functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1841)  ***********************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1842) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1843) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1844) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1845)   check_input_package():
11c606a6 (kx 2023-04-11 01:18:34 +0300 1846)   ---------------------
11c606a6 (kx 2023-04-11 01:18:34 +0300 1847) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1848)     Возвращает:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1849)      -1 если пакет установлен, но его версия меньше
11c606a6 (kx 2023-04-11 01:18:34 +0300 1850)         запрашиваемого,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1851)       0 если версия установленного и запрашиваемого равны,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1852)       1 если пакет установлен, но его версия больше
11c606a6 (kx 2023-04-11 01:18:34 +0300 1853)         запрашиваемого.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1854) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1855)     В случае возврата -1 или 1, устанавливается переменная
11c606a6 (kx 2023-04-11 01:18:34 +0300 1856)     requested_version, равная версии пакета который запросили
11c606a6 (kx 2023-04-11 01:18:34 +0300 1857)     на удаление.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1858) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1859)     Если пакет не установлен, осуществляется выход со статусом 30.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1860)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1861) static int check_input_package( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1862) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1863)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1864)   char *fname = pkg_fname;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1865) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1866)   enum _input_type  type = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1867)   char              uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1868) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1869)   int ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1870) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1871)   bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1872) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1873)   if( stat( (const char *)fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1874)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1875)     /*************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1876)       Specified pkg_fname is not a file or directory.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1877)       Try to find installed package  with name equal
11c606a6 (kx 2023-04-11 01:18:34 +0300 1878)       to pkg_fname:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1879)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1880)     fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1881)     fname = probe_package();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1882)     if( !fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1883)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1884)       if( remove_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1885)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1886) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1887)         info_pkg_box( "Remove:", basename( pkg_fname ), NULL, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1888)                       "\nPackage is not installed.\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1889) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1890)         fprintf( stdout, "\nPackage '%s' is not installed.\n\n", basename( pkg_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1891) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1892)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1893)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1894)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1895)         if( !quiet ) fprintf( stdout, "Specified package '%s' is not installed.\n\n", basename( pkg_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1896)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1897) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1898)       exit_status = 30; /* Package is not installed: install */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1899) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1900)       if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1901)       free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1902) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1903)       exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1904)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1905)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1906)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1907)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1908)     if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1909)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1910)       pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1911)       int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1912) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1913)       int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1914)       char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1915) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1916)       tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1917)       if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1918)       bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1919) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1920)       (void)sprintf( &tmp[0], "%s", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1921)       if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1922)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1923)         FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1924)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1925) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1926)       cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1927)       if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1928)       bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1929) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1930)       len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1931)                       "%s/pkginfo -d %s -o pkginfo %s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1932)                       selfdir, tmp, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1933)       if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1934)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1935)         FATAL_ERROR( "Cannot get PKGINFO from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1936)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1937)       p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1938)       rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1939)       if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1940)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1941)         FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1942)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1943) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1944)       (void)strcat( tmp, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1945)       read_pkginfo( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1946)       (void)unlink( (const char *)&tmp[0] ); /* :remove unnecessary .PKGINFO file */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1947)       *(strstr( tmp, "/.PKGINFO" )) = '\0';  /* :restore 'tmpdir' in tmp[] buffer */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1948) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1949)       requested_version = strdup( (const char *)pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1950) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1951)       fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1952)       fname = find_package();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1953)       if( !fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1954)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1955)         if( remove_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1956)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1957) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1958)           info_pkg_box( "Remove:", basename( pkg_fname ), NULL, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1959)                         "\nPackage is not installed.\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1960) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1961)           fprintf( stdout, "\nPackage '%s' is not installed.\n\n", basename( pkg_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1962) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1963)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1964)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1965)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1966)           if( !quiet ) fprintf( stdout, "Specified package '%s' is not installed.\n\n", basename( pkg_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1967)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1968) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1969)         exit_status = 30; /* Package is not installed: install */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1970) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1971)         if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1972)         free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1973) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1974)         exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1975)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1976) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1977)       free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1978)       free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1979)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1980)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1981)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1982)       FATAL_ERROR( "Input %s file is not a regular file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1983)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1984)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1985) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1986)   /* check pkg_fname again: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1987)   if( stat( (const char *)fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1988)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1989)     FATAL_ERROR( "Cannot access input '%s' file: %s", fname, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1990)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1991) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1992)   type = check_input_file( &uncompress, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1993)   if( type == IFMT_UNKNOWN )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1994)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1995)     FATAL_ERROR( "Unknown format of input '%s' file", fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1996)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1997) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1998)   if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1999)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2000)     pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2001)     int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2002) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2003)     int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2004)     char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2005) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2006)     tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2007)     if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2008)     bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2009) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2010)     (void)sprintf( &tmp[0], "%s/to-remove", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2011)     if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2012)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2013)       FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2014)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2015)     rtmpdir = strdup( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2016) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2017)     cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2018)     if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2019)     bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2020) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2021)     len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 2022)                     "%s/pkginfo -d %s -o pkginfo,description,install-script,restore-links,filelist %s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2023)                     selfdir, tmp, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2024)     if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2025)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2026)       FATAL_ERROR( "Cannot get PKGINFO from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2027)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2028)     p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2029)     rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2030)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2031)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2032)       FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2033)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2034) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2035)     (void)strcat( tmp, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2036)     read_pkginfo( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2037)     *(strstr( tmp, "/.PKGINFO" )) = '\0'; /* :restore tmpdir in tmp[] buffer */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2038) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2039)     free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2040)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2041) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2042)     if( requested_version )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2043)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2044)       ret = cmp_version( (const char *)pkgver, (const char *)requested_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2045)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2046)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2047)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2048)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2049)     FATAL_ERROR( "Input %s file is not a regular file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2050)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2051) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2052)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2053) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2054) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2055) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2056) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2057) static void dialogrc( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2058) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2059)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2060)   char  *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2061) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2062)   tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2063)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2064)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2065) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2066)   /* imagine that the utility is in /sbin directory: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2067)   (void)sprintf( &tmp[0], "%s/../usr/share/%s/.dialogrc", selfdir, PACKAGE_NAME );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2068)   if( stat( (const char *)&tmp[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2069)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2070)     /* finaly assume that /usr/sbin is a sbindir: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2071)     (void)sprintf( &tmp[0], "%s/../../usr/share/%s/.dialogrc", selfdir, PACKAGE_NAME );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2072)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2073) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2074)   setenv( "DIALOGRC", (const char *)&tmp[0], 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2075) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2076)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2077) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2078) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2079) static char *get_curdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2080) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2081)   char *cwd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2082) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2083)   cwd = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2084)   if( !cwd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2085)   bzero( (void *)cwd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2086) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2087)   if( getcwd( cwd, (size_t)PATH_MAX ) != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2088)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2089)     char *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2090)     remove_trailing_slash( cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2091)     p = strdup( cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2092)     free( cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2093)     return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2094)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2095)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2096)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2097)     FATAL_ERROR( "Cannot get absolute path to current directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2098)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2099) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2100)   return (char *)NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2101) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2102) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2103) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2104) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2105)   Get directory where this program is placed:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2106)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2107) char *get_selfdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2108) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2109)   char    *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2110)   ssize_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2111) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2112)   buf = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2113)   if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2114)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2115)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2116)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2117) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2118)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2119)   len = readlink( "/proc/self/exe", buf, (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2120)   if( len > 0 && len < PATH_MAX )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2121)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2122)     char *p = strdup( dirname( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2123)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2124)     return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2125)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2126)   FATAL_ERROR( "Cannot determine self directory. Please mount /proc filesystem" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2127) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2128) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2129) void set_stack_size( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2130) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2131)   const rlim_t   stack_size = 16 * 1024 * 1024; /* min stack size = 16 MB */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2132)   struct rlimit  rl;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2133)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2134) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2135)   ret = getrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2136)   if( ret == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2137)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2138)     if( rl.rlim_cur < stack_size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2139)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2140)       rl.rlim_cur = stack_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2141)       ret = setrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2142)       if( ret != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2143)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2144)         fprintf(stderr, "setrlimit returned result = %d\n", ret);
11c606a6 (kx 2023-04-11 01:18:34 +0300 2145)         FATAL_ERROR( "Cannot set stack size" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2146)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2147)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2148)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2149) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2150) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2151) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2152) int main( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2153) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2154)   gid_t  gid;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2155) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2156)   set_signal_handlers();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2157) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2158)   gid = getgid();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2159)   setgroups( 1, &gid );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2160) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2161)   fatal_error_hook = fatal_error_actions;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2162) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2163)   selfdir = get_selfdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2164)   curdir  = get_curdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2165)   dialogrc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2166) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2167)   errlog = stderr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2168) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2169)   program = basename( argv[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2170)   get_args( argc, argv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2171) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2172)   /* set_stack_size(); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2173) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2174)   tmpdir = _mk_tmpdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2175)   if( !tmpdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2176)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2177)     FATAL_ERROR( "Cannot create temporary directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2178)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2179) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2180)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2181)     int status = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2182) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2183)     /**********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2184)       Fill pkginfo data and put or replace pkglog into tmpdir:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2185)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2186)     status = check_input_package();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2187) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2188)     read_filelist();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2189)     read_restorelinks();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2190)     read_description();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2191) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2192)     if( ask_for_remove( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2193)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2194)       /* Terminate removal: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2195)       if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2196)       free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2197)       exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2198)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2199)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2200) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2201)   show_removal_progress();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2202) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2203)   /************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2204)     DO REMOVE:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2205)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2206)   pre_remove_routine();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2207)   remove_package();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2208)   post_remove_routine();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2209)   finalize_removal();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2210) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2211)   if( remove_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2212)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2213) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2214)     info_pkg_box( "Remove:", pkgname, pkgver, NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 2215)                   "\nPackage has been removed.\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2216) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2217)     fprintf( stdout, "\nPackage '%s-%s' has been removed.\n\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2218) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 2219)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2220)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2221)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2222)     if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2223)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2224)       fprintf( stdout, "\nPackage '%s-%s' has been removed.\n\n", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2225)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2226)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2227) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2228)   setup_log( "Package '%s-%s' has been removed", pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2229) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2230)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2231)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2232) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2233)   exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2234) }