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/sysinfo.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   24) #include <sys/types.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   25) #include <stdint.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   26) #include <dirent.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   27) #include <sys/stat.h> /* chmod(2)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   28) #include <sys/file.h> /* flock(2)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   29) #include <fcntl.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   30) #include <linux/limits.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   31) #include <alloca.h>   /* alloca(3)   */
11c606a6 (kx 2023-04-11 01:18:34 +0300   32) #include <string.h>   /* strdup(3)   */
11c606a6 (kx 2023-04-11 01:18:34 +0300   33) #include <strings.h>  /* index(3)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   34) #include <libgen.h>   /* basename(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300   35) #include <ctype.h>    /* tolower(3)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300   36) #include <errno.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   37) #include <time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   38) #include <sys/time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   39) #include <pwd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   40) #include <grp.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   41) #include <stdarg.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   42) #include <unistd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   43) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   44) #include <pthread.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   45) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   46) #include <math.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   47) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   48) #include <sys/wait.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   49) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   50) #include <sys/resource.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   51) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   52) #include <signal.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   53) #if !defined SIGCHLD && defined SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   54) # define SIGCHLD SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   55) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300   56) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   57) #define _GNU_SOURCE
11c606a6 (kx 2023-04-11 01:18:34 +0300   58) #include <getopt.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   59) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   60) #include <msglog.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   61) #include <wrapper.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   62) #include <system.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 "install-pkglist"
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) 
a745159c (kx 2023-10-23 21:39:58 +0300   73) #define START_USEC_FOR_CHILD 30000
a745159c (kx 2023-10-23 21:39:58 +0300   74) #define  WAIT_USEC_FOR_CHILD 10000
11c606a6 (kx 2023-04-11 01:18:34 +0300   75) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   76) char *program = PROGRAM_NAME;
11c606a6 (kx 2023-04-11 01:18:34 +0300   77) char *root = NULL, *srcdir = NULL, *pkglist_fname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   78)      *tmpdir = NULL, *curdir = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   79) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   80) int   rqck = 0, gpgck = 0, progress = 0, parallel = 0, error_pkgs_list = 0, ncpus = 0;
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) int __done = 0, __child = 0, __terminated = 0, __successful = 0, __all = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300   86) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   87) enum _install_mode {
11c606a6 (kx 2023-04-11 01:18:34 +0300   88)   CONSOLE = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300   89)   INFODIALOG,
11c606a6 (kx 2023-04-11 01:18:34 +0300   90)   MENUDIALOG
11c606a6 (kx 2023-04-11 01:18:34 +0300   91) } install_mode = CONSOLE;
11c606a6 (kx 2023-04-11 01:18:34 +0300   92) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   93) enum _input_type {
11c606a6 (kx 2023-04-11 01:18:34 +0300   94)   IFMT_PKG = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300   95)   IFMT_LOG,
11c606a6 (kx 2023-04-11 01:18:34 +0300   96) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   97)   IFMT_UNKNOWN
11c606a6 (kx 2023-04-11 01:18:34 +0300   98) };
11c606a6 (kx 2023-04-11 01:18:34 +0300   99) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  100) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  101)   Package structures and declarations:
11c606a6 (kx 2023-04-11 01:18:34 +0300  102)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  103) enum _procedure
11c606a6 (kx 2023-04-11 01:18:34 +0300  104) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  105)   INSTALL = 0, /* 'install' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  106)   UPDATE       /* 'update'  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  107) };
11c606a6 (kx 2023-04-11 01:18:34 +0300  108) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  109) enum _priority
11c606a6 (kx 2023-04-11 01:18:34 +0300  110) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  111)   REQUIRED = 0, /* synonims: REQUIRED    | required    | REQ | req */
11c606a6 (kx 2023-04-11 01:18:34 +0300  112)   RECOMMENDED,  /* synonims: RECOMMENDED | recommended | REC | rec */
11c606a6 (kx 2023-04-11 01:18:34 +0300  113)   OPTIONAL,     /* synonims: OPTIONAL    | optional    | OPT | opt */
11c606a6 (kx 2023-04-11 01:18:34 +0300  114)   SKIP          /* synonims: SKIP        | skip        | SKP | skp */
11c606a6 (kx 2023-04-11 01:18:34 +0300  115) };
11c606a6 (kx 2023-04-11 01:18:34 +0300  116) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  117) struct pkg
11c606a6 (kx 2023-04-11 01:18:34 +0300  118) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  119)   char *group;
11c606a6 (kx 2023-04-11 01:18:34 +0300  120)   char *name;
11c606a6 (kx 2023-04-11 01:18:34 +0300  121)   char *version;
11c606a6 (kx 2023-04-11 01:18:34 +0300  122) };
11c606a6 (kx 2023-04-11 01:18:34 +0300  123) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  124) struct package
11c606a6 (kx 2023-04-11 01:18:34 +0300  125) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  126)   char  *name;
11c606a6 (kx 2023-04-11 01:18:34 +0300  127)   char  *version;
11c606a6 (kx 2023-04-11 01:18:34 +0300  128)   char  *group;
11c606a6 (kx 2023-04-11 01:18:34 +0300  129)   char  *description;
11c606a6 (kx 2023-04-11 01:18:34 +0300  130) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  131)   char  *tarball;
11c606a6 (kx 2023-04-11 01:18:34 +0300  132) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  133)   enum  _procedure procedure; /* install procedure     */
11c606a6 (kx 2023-04-11 01:18:34 +0300  134)   enum  _priority  priority;  /* install user priority */
11c606a6 (kx 2023-04-11 01:18:34 +0300  135) };
11c606a6 (kx 2023-04-11 01:18:34 +0300  136) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  137) enum _priority install_priority = OPTIONAL; /* by default allow all packages exept 'SKIP' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  138) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  139) struct dlist *requires = NULL; /* list of pkg structs     */
11c606a6 (kx 2023-04-11 01:18:34 +0300  140) struct dlist *packages = NULL; /* list of package structs */
11c606a6 (kx 2023-04-11 01:18:34 +0300  141) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  142) static void free_requires( void );
11c606a6 (kx 2023-04-11 01:18:34 +0300  143) static void free_packages( void );
11c606a6 (kx 2023-04-11 01:18:34 +0300  144) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  145) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  146)   End of package structures and declarations.
11c606a6 (kx 2023-04-11 01:18:34 +0300  147)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  148) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  149) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  150)   Return status declarations:
11c606a6 (kx 2023-04-11 01:18:34 +0300  151)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  152) struct pkgrc
11c606a6 (kx 2023-04-11 01:18:34 +0300  153) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  154)   pid_t  pid;
11c606a6 (kx 2023-04-11 01:18:34 +0300  155)   int    status;
11c606a6 (kx 2023-04-11 01:18:34 +0300  156)   char  *name;
11c606a6 (kx 2023-04-11 01:18:34 +0300  157)   char  *version;
11c606a6 (kx 2023-04-11 01:18:34 +0300  158)   char  *group;
11c606a6 (kx 2023-04-11 01:18:34 +0300  159) };
11c606a6 (kx 2023-04-11 01:18:34 +0300  160) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  161) struct dlist *pkgrcl = NULL; /* list of pkgrc structs */
11c606a6 (kx 2023-04-11 01:18:34 +0300  162) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  163) static void          free_pkgrcl( void );
11c606a6 (kx 2023-04-11 01:18:34 +0300  164) static struct pkgrc *find_pkgrc( struct dlist *list, pid_t pid );
11c606a6 (kx 2023-04-11 01:18:34 +0300  165) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  166)   End of return status declarations.
11c606a6 (kx 2023-04-11 01:18:34 +0300  167)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  168) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  169) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  170) void free_resources()
11c606a6 (kx 2023-04-11 01:18:34 +0300  171) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  172)   if( root )           { free( root );           root           = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  173)   if( srcdir )         { free( srcdir );         srcdir         = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  174)   if( pkglist_fname )  { free( pkglist_fname );  pkglist_fname  = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  175) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  176)   if( requires ) free_requires();
11c606a6 (kx 2023-04-11 01:18:34 +0300  177)   if( packages ) free_packages();
11c606a6 (kx 2023-04-11 01:18:34 +0300  178)   if( pkgrcl )   free_pkgrcl();
11c606a6 (kx 2023-04-11 01:18:34 +0300  179) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  180)   if( curdir )         { free( curdir );         curdir         = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  181)   if( selfdir )        { free( selfdir );        selfdir        = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  182) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  183) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  184) void usage()
11c606a6 (kx 2023-04-11 01:18:34 +0300  185) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  186)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  187) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  188)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  189)   fprintf( stdout, "Usage: %s [options] <pkglist>\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  190)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  191)   fprintf( stdout, "Create Packages List in the installation order from set of PKGLOGs\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  192)   fprintf( stdout, "or  set of PACKAGEs placed in the source directory.  If the source\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  193)   fprintf( stdout, "directory is not defined then directory of <pkglist>  will be used\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  194)   fprintf( stdout, "as source PACKAGE directory.\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, "Options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  197)   fprintf( stdout, "  -h,--help                     Display this information.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  198)   fprintf( stdout, "  -v,--version                  Display the version of %s utility.\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  199) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  200)   fprintf( stdout, "  -c,--check-requires           Check the list of requires before install.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  201)   fprintf( stdout, "  -g,--gpg-verify               Verify GPG2 signature. The signature must be\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  202)   fprintf( stdout, "                                saved in a file whose name is the same as the\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  203)   fprintf( stdout, "                                package file name, but with the extension '.asc'\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  204)   fprintf( stdout, "                                and located in the same directory as the package.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  205) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  206)   fprintf( stdout, "  -i,--info-dialog              Show package description during install\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  207)   fprintf( stdout, "                                process using ncurses dialog.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  208)   fprintf( stdout, "  -m,--menu-dialog              Ask for confirmation the inatallation.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  209) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  210)   fprintf( stdout, "  --parallel                    Parallel installation (dangerous; required the\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  211)   fprintf( stdout, "                                checking of DB integrity after installation).\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  212)   fprintf( stdout, "  --errlist                     Print the list of not installed packages to the\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  213)   fprintf( stdout, "                                stderr in following format:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  214)   fprintf( stdout, "                                    group/name:version:status\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  215)   fprintf( stdout, "                                This option is applicable only for parallel\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  216)   fprintf( stdout, "                                installations.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  217)   fprintf( stdout, "  --progress                    Show progress bar instead of packages information.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  218) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  219)   fprintf( stdout, "  -p,--priority=<required|recommended|optional|all>\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  220)   fprintf( stdout, "                                Рackage priorities allowed for installation:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  221)   fprintf( stdout, "                                - optional | all ) install all packages;\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  222)   fprintf( stdout, "                                - recommended )    install required and recommended;\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  223)   fprintf( stdout, "                                - required )       install only required packages.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  224) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  225)   fprintf( stdout, "  -r,--root=<DIR>               Target rootfs path.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  226) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  227)   fprintf( stdout, "  -s,--source=<DIR>             Packages source directory.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  228) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  229)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  230)   fprintf( stdout, "Parameter:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  231)   fprintf( stdout, "  <DIR|pkglist>                 Input PKGLIST file name or a source\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  232)   fprintf( stdout, "                                directory to find default PKGLIST.\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  233)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  234)   fprintf( stdout, "If sourse packages directory is defined by option -s,--source then\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  235)   fprintf( stdout, "specified <DIR|pkglist> argumet will be considered relative to the\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  236)   fprintf( stdout, "source directory.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  237)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  238) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  239)   exit( EXIT_FAILURE );
11c606a6 (kx 2023-04-11 01:18:34 +0300  240) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  241) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  242) void to_lowercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  243) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  244)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  245)   while( p && *p ) { int c = *p; *p = tolower( c ); ++p; }
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) void to_uppercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  249) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  250)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  251)   while( p && *p ) { int c = *p; *p = toupper( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  252) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  253) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  254) void version()
11c606a6 (kx 2023-04-11 01:18:34 +0300  255) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  256)   char *upper = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  257) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  258)   upper = (char *)alloca( strlen( program ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  259) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  260)   strcpy( (char *)upper, (const char *)program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  261)   to_uppercase( upper );
11c606a6 (kx 2023-04-11 01:18:34 +0300  262) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  263)   fprintf( stdout, "%s (%s) %s\n", program, upper, PROGRAM_VERSION );
11c606a6 (kx 2023-04-11 01:18:34 +0300  264) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  265)   fprintf( stdout, "Copyright (C) 2019 Andrey V.Kosteltsev.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  266)   fprintf( stdout, "This is free software.   There is NO warranty; not even\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  267)   fprintf( stdout, "for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  268)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  269) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  270)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  271)   exit( EXIT_SUCCESS );
11c606a6 (kx 2023-04-11 01:18:34 +0300  272) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  273) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  274) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  275) static void remove_trailing_slash( char *dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  276) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  277)   char *s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  278) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  279)   if( !dir || dir[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  280) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  281)   s = dir + strlen( dir ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  282)   while( *s == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  283)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  284)     *s = '\0'; --s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  285)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  286) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  287) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  288) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  289) static int _mkdir_p( const char *dir, const mode_t mode )
11c606a6 (kx 2023-04-11 01:18:34 +0300  290) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  291)   char  *buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  292)   char  *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  293)   struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  294) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  295)   if( !dir ) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  296) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  297)   buf = (char *)alloca( strlen( dir ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  298)   strcpy( buf, dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  299) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  300)   remove_trailing_slash( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  301) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  302)   /* check if path exists and is a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  303)   if( stat( buf, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  304)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  305)     if( S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  306)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  307)       return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  308)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  309)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  310) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  311)   /* mkdir -p */
11c606a6 (kx 2023-04-11 01:18:34 +0300  312)   for( p = buf + 1; *p; ++p )
11c606a6 (kx 2023-04-11 01:18:34 +0300  313)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  314)     if( *p == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  315)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  316)       *p = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  317)       /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  318)       if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  319)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  320)         /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  321)         if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  322)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  323)           return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  324)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  325)       } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  326)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  327)         /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  328)         return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  329)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  330)       *p = '/';
11c606a6 (kx 2023-04-11 01:18:34 +0300  331)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  332)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  333) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  334)   /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  335)   if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  336)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  337)     /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  338)     if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  339)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  340)       return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  341)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  342)   } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  343)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  344)     /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  345)     return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  346)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  347) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  348)   return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  349) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  350) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  351) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  352) static void _rm_tmpdir( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300  353) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  354)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300  355)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300  356)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  357) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  358)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  359)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300  360) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  361)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  362)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  363)     return; /* stat returns error code; errno is set */
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)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  367)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  368)     return; /* dirpath is not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  369)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  370) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  371)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  372)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  373)     return; /* Cannot open direcroty; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  374)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  375) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  376)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  377) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  378)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300  379)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  380) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  381)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  382)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300  383) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  384)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300  385)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  386)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  387)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  388)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  389) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  390)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  391)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  392)       if( S_ISDIR(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  393)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  394)         /* recursively remove a nested directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  395)         _rm_tmpdir( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  396)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  397)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  398)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  399)         /* remove a file object */
11c606a6 (kx 2023-04-11 01:18:34 +0300  400)         (void)unlink( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  401)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  402)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  403)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  407)   /* remove the devastated directory and close the object of this directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  408)   (void)rmdir( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  409) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  410)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  411) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  412) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  413) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  414) static char *_mk_tmpdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  415) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  416)   char   *buf = NULL, *p, *tmp = "/tmp";
11c606a6 (kx 2023-04-11 01:18:34 +0300  417)   size_t  len = 0, size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  418) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  419)   (void)umask( S_IWGRP | S_IWOTH ); /* octal 022 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  420) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  421)   /* Get preferred directory for tmp files */
11c606a6 (kx 2023-04-11 01:18:34 +0300  422)   if( (p = getenv( "TMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  423)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  424)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  425)   else if( (p = getenv( "TEMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  426)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  427)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  428) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  429)   size = strlen( tmp ) + strlen( DISTRO_NAME ) + strlen( program ) + 12;
11c606a6 (kx 2023-04-11 01:18:34 +0300  430) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  431)   buf = (char *)malloc( size );
11c606a6 (kx 2023-04-11 01:18:34 +0300  432)   if( !buf ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  433) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  434)   len = snprintf( buf, size, (const char *)"%s/%s/%s-%.7u", tmp, DISTRO_NAME, program, getpid() );
11c606a6 (kx 2023-04-11 01:18:34 +0300  435)   if( len == 0 || len == size - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  436)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  437)     free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  438)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  439) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  440)   _rm_tmpdir( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  441) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  442)   if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  443)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  444)     return buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  445)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  446) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  447)   free( buf ); return NULL;
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  451) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  452) void fatal_error_actions( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  453) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  454)   logmsg( errlog, MSG_NOTICE, "Free resources on FATAL error..." );
11c606a6 (kx 2023-04-11 01:18:34 +0300  455)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  456)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  457) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  458) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  459) void sigint( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  460) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  461)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  462) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  463)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  464)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  465) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  466) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  467) void sigchld( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  468) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  469)   pid_t  pid = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  470)   int    status;
11c606a6 (kx 2023-04-11 01:18:34 +0300  471) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  472)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  473) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  474)   while( (pid = waitpid( -1, &status, WNOHANG )) > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  475)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  476)     struct pkgrc *pkgrc = find_pkgrc( pkgrcl, pid );
11c606a6 (kx 2023-04-11 01:18:34 +0300  477) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  478)     ++__terminated; /* One of children with 'pid' is terminated */
11c606a6 (kx 2023-04-11 01:18:34 +0300  479) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  480)     if( WIFEXITED( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  481)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  482)       if( (int)WEXITSTATUS( status ) > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  483)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  484)         ++exit_status; /* printf( "Child %d returned non zero status: %d\n", pid, (int)WEXITSTATUS (status) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  485)         if( pkgrc ) pkgrc->status = (int)WEXITSTATUS (status);
11c606a6 (kx 2023-04-11 01:18:34 +0300  486)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  487)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  488)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  489)         ++__successful; /* printf( "Child %d terminated with status: %d\n", pid, (int)WEXITSTATUS (status) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  490)         if( pkgrc ) pkgrc->status = (int)WEXITSTATUS (status);
11c606a6 (kx 2023-04-11 01:18:34 +0300  491)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  492)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  493)     else if( WIFSIGNALED( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  494)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  495)       ++exit_status; /* printf( "Child %d terminated on signal: %d\n", pid, WTERMSIG( status ) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  496)       if( pkgrc ) pkgrc->status = 253;
11c606a6 (kx 2023-04-11 01:18:34 +0300  497)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  498)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  499)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  500)       ++exit_status; /* printf( "Child %d terminated on unknown reason\n", pid ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  501)       if( pkgrc ) pkgrc->status = 254;
11c606a6 (kx 2023-04-11 01:18:34 +0300  502)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  503) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  504)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  505) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  506)   if( pid == -1 && errno == ECHILD )
11c606a6 (kx 2023-04-11 01:18:34 +0300  507)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  508)     /* No child processes: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  509)     __done = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  510)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  511)   return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  512) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  513) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  514) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  515) static void set_signal_handlers()
11c606a6 (kx 2023-04-11 01:18:34 +0300  516) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  517)   struct sigaction  sa;
11c606a6 (kx 2023-04-11 01:18:34 +0300  518)   sigset_t          set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  519) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  520)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  521)   sa.sa_handler = sigint;          /* TERM, INT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  522)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  523)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  524)   sigaddset( &set, SIGTERM );
11c606a6 (kx 2023-04-11 01:18:34 +0300  525)   sigaddset( &set, SIGINT );
11c606a6 (kx 2023-04-11 01:18:34 +0300  526)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  527)   sigaction( SIGTERM, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  528)   sigaction( SIGINT, &sa,  NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  529) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  530)   /* System V fork+wait does not work if SIGCHLD is ignored */
11c606a6 (kx 2023-04-11 01:18:34 +0300  531)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  532)   sa.sa_handler = sigchld;         /* CHLD */
11c606a6 (kx 2023-04-11 01:18:34 +0300  533)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  534)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  535)   sigaddset( &set, SIGCHLD );
11c606a6 (kx 2023-04-11 01:18:34 +0300  536)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  537)   sigaction( SIGCHLD, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  538) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  539)   memset( &sa, 0, sizeof( sa ) );  /* ignore SIGPIPE */
11c606a6 (kx 2023-04-11 01:18:34 +0300  540)   sa.sa_handler = SIG_IGN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  541)   sa.sa_flags = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  542)   sigaction( SIGPIPE, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  543) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  544) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  545) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  546) static enum _input_type check_package_file( char *uncompress, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  547) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  548)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  549)   size_t pkglog_size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  550)   unsigned char buf[8];
11c606a6 (kx 2023-04-11 01:18:34 +0300  551)   int rc, fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300  552) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  553)   /* SIGNATURES: https://www.garykessler.net/library/file_sigs.html */
11c606a6 (kx 2023-04-11 01:18:34 +0300  554) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  555)   if( uncompress )
11c606a6 (kx 2023-04-11 01:18:34 +0300  556)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  557)     *uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  558)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  559) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  560)   if( stat( fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  561)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  562)     FATAL_ERROR( "Cannot access %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  563)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  564) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  565)   pkglog_size = st.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300  566) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  567)   if( (fd = open( fname, O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  568)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  569)     FATAL_ERROR( "Cannot open %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  570)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  571) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  572)   rc = (int)read( fd, (void *)&buf[0], 7 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  573)   if( rc != 7 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  574)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  575)     close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  576)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  577)   buf[7] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  578) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  579)   /* TEXT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  580)   if( !strncmp( (const char *)&buf[0], "PACKAGE", 7 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  581)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  582)     close( fd ); return IFMT_LOG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  583)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  584) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  585)   /* GZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  586)   if( buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x08 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  587)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  588)     if( uncompress ) { *uncompress = 'x'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  589)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  590)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  591) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  592)   /* BZ2 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  593)   if( buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  594)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  595)     if( uncompress ) { *uncompress = 'j'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  596)     close( fd ); return IFMT_PKG;
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)   /* XZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  600)   if( buf[0] == 0xFD && buf[1] == 0x37 && buf[2] == 0x7A &&
11c606a6 (kx 2023-04-11 01:18:34 +0300  601)       buf[3] == 0x58 && buf[4] == 0x5A && buf[5] == 0x00   )
11c606a6 (kx 2023-04-11 01:18:34 +0300  602)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  603)     if( uncompress ) { *uncompress = 'J'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  604)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  605)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  606) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  607)   if( pkglog_size > 262 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  608)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  609)     if( lseek( fd, 257, SEEK_SET ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  610)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  611)       FATAL_ERROR( "Cannot check signature of %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  612)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  613)     rc = (int)read( fd, &buf[0], 5 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  614)     if( rc != 5 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  615)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  616)       FATAL_ERROR( "Cannot read signature of %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  617)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  618)     /* TAR */
11c606a6 (kx 2023-04-11 01:18:34 +0300  619)     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  620)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  621)       close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  622)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  623)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  624) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  625)   close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  626) }
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) void get_args( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300  630) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  631) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  632)   const char* short_options = "hvcgimp:r:s:";
11c606a6 (kx 2023-04-11 01:18:34 +0300  633) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300  634)   const char* short_options = "hvcgp:r:s:";
11c606a6 (kx 2023-04-11 01:18:34 +0300  635) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  636) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  637) #define PROGRESS 812
11c606a6 (kx 2023-04-11 01:18:34 +0300  638) #define PARALLEL 872
11c606a6 (kx 2023-04-11 01:18:34 +0300  639) #define _ERRLIST 873
11c606a6 (kx 2023-04-11 01:18:34 +0300  640) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  641)   const struct option long_options[] =
11c606a6 (kx 2023-04-11 01:18:34 +0300  642)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  643)     { "help",           no_argument,       NULL, 'h' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  644)     { "version",        no_argument,       NULL, 'v' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  645)     { "check-requires", no_argument,       NULL, 'c' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  646)     { "gpg-verify",     no_argument,       NULL, 'g' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  647) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  648)     { "info-dialog",    no_argument,       NULL, 'i' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  649)     { "menu-dialog",    no_argument,       NULL, 'm' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  650) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  651)     { "parallel",       no_argument,       NULL, PARALLEL },
11c606a6 (kx 2023-04-11 01:18:34 +0300  652)     { "errlist",        no_argument,       NULL, _ERRLIST },
11c606a6 (kx 2023-04-11 01:18:34 +0300  653)     { "progress",       no_argument,       NULL, PROGRESS },
11c606a6 (kx 2023-04-11 01:18:34 +0300  654)     { "priority",       required_argument, NULL, 'p' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  655)     { "root",           required_argument, NULL, 'r' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  656)     { "source",         required_argument, NULL, 's' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  657)     { NULL,             0,                 NULL,  0  }
11c606a6 (kx 2023-04-11 01:18:34 +0300  658)   };
11c606a6 (kx 2023-04-11 01:18:34 +0300  659) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  660)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  661)   int option_index = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  662) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  663)   while( (ret = getopt_long( argc, argv, short_options, long_options, &option_index )) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  664)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  665)     switch( ret )
11c606a6 (kx 2023-04-11 01:18:34 +0300  666)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  667)       case 'h':
11c606a6 (kx 2023-04-11 01:18:34 +0300  668)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  669)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  670)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  671)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  672)       case 'v':
11c606a6 (kx 2023-04-11 01:18:34 +0300  673)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  674)         version();
11c606a6 (kx 2023-04-11 01:18:34 +0300  675)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  676)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  677)       case 'c':
11c606a6 (kx 2023-04-11 01:18:34 +0300  678)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  679)         rqck = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  680)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  681)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  682)       case 'g':
11c606a6 (kx 2023-04-11 01:18:34 +0300  683)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  684)         gpgck = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  685)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  686)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  687) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  688) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  689)       case 'i':
11c606a6 (kx 2023-04-11 01:18:34 +0300  690)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  691)         install_mode = INFODIALOG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  692)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  693)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  694)       case 'm':
11c606a6 (kx 2023-04-11 01:18:34 +0300  695)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  696)         install_mode = MENUDIALOG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  697)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  698)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  699) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  700) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  701)       case PARALLEL:
11c606a6 (kx 2023-04-11 01:18:34 +0300  702)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  703)         parallel = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  704)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  705)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  706)       case _ERRLIST:
11c606a6 (kx 2023-04-11 01:18:34 +0300  707)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  708)         error_pkgs_list = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  709)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  710)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  711)       case PROGRESS:
11c606a6 (kx 2023-04-11 01:18:34 +0300  712)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  713)         progress = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  714)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  715)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  716) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  717)       case 'p':
11c606a6 (kx 2023-04-11 01:18:34 +0300  718)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  719)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  720)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  721)           char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  722) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  723)           if( strlen( (const char *)optarg ) > 2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  724)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  725)             to_lowercase( optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  726)             if( (match = strstr( optarg, "req" )) && match == optarg ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  727)               install_priority = REQUIRED;
11c606a6 (kx 2023-04-11 01:18:34 +0300  728)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300  729)             else if( (match = strstr( optarg, "rec" )) && match == optarg ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  730)               install_priority = RECOMMENDED;
11c606a6 (kx 2023-04-11 01:18:34 +0300  731)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300  732)             else if( (match = strstr( optarg, "opt" )) && match == optarg ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  733)               install_priority = OPTIONAL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  734)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300  735)             else if( (match = strstr( optarg, "all" )) && match == optarg ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  736)               install_priority = OPTIONAL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  737)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300  738)             else {
11c606a6 (kx 2023-04-11 01:18:34 +0300  739)               FATAL_ERROR( "Unknown --priority '%s' value", optarg );
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)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300  743)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  744)             FATAL_ERROR( "Unknown --priority '%s' value", optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  745)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  746)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  747)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  748)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  749)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  750)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  751)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  752) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  753)       case 'r':
11c606a6 (kx 2023-04-11 01:18:34 +0300  754)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  755)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  756)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  757)           char cwd[PATH_MAX];
11c606a6 (kx 2023-04-11 01:18:34 +0300  758) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  759)           bzero( (void *)cwd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  760)           if( optarg[0] != '/' && curdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  761)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  762)             /* skip current directory definition './' at start of argument: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  763)             if( !strncmp( optarg, "./", 2 ) && strncmp( optarg, "..", 2 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  764)               (void)sprintf( cwd, "%s/%s", curdir, optarg + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  765)             else if( (strlen( optarg ) == 1) && !strncmp( optarg, ".", 1 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  766)               (void)sprintf( cwd, "%s", curdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  767)             else
11c606a6 (kx 2023-04-11 01:18:34 +0300  768)               (void)sprintf( cwd, "%s/%s", curdir, optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  769)             root = xstrdup( (const char *)cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300  770)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  771)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300  772)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  773)             root = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  774)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  775)           remove_trailing_slash( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  776)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  777)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  778)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  779)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  780)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  781)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  782) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  783)       case 's':
11c606a6 (kx 2023-04-11 01:18:34 +0300  784)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  785)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  786)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  787)           char cwd[PATH_MAX];
11c606a6 (kx 2023-04-11 01:18:34 +0300  788) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  789)           bzero( (void *)cwd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  790)           if( optarg[0] != '/' && curdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  791)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  792)             (void)sprintf( cwd, "%s/%s", curdir, optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  793)             srcdir = xstrdup( (const char *)cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300  794)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  795)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300  796)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  797)             srcdir = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  798)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  799)           remove_trailing_slash( srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  800)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  801)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  802)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  803)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  804)         break;
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)       case '?': default:
11c606a6 (kx 2023-04-11 01:18:34 +0300  808)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  809)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  810)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  811)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  812)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  813)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  814) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  815) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  816)   /* last command line argument is the intput PKGLIST file */
11c606a6 (kx 2023-04-11 01:18:34 +0300  817)   if( optind < argc )
11c606a6 (kx 2023-04-11 01:18:34 +0300  818)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  819)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  820)     char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  821) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  822)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  823) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  824)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  825)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  826)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  827) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  828)     (void)strcpy( buf, (const char *)argv[optind++] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  829)     remove_trailing_slash( (char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  830) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  831)     if( srcdir)
11c606a6 (kx 2023-04-11 01:18:34 +0300  832)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  833)       char *tmp = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  834) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  835)       /* Ignore already defined srcdir if absolute path is specified: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  836)       if( buf[0] != '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  837)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  838)         if( !strncmp( tmp, "./", 2 ) && strncmp( tmp, "..", 2 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  839)           (void)sprintf( buf, "%s/%s", srcdir, tmp + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  840)         else if( (strlen( tmp ) == 1) && !strncmp( tmp, ".", 1 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  841)           (void)sprintf( buf, "%s", srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  842)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  843)           (void)sprintf( buf, "%s/%s", srcdir, tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  844)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  845)       free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  846) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  847)       free( srcdir ); srcdir = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  848)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  849)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  850)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  851)       char *tmp = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  852) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  853)       if( buf[0] != '/' && curdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  854)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  855)         if( !strncmp( tmp, "./", 2 ) && strncmp( tmp, "..", 2 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  856)           (void)sprintf( buf, "%s/%s", curdir, tmp + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  857)         else if( (strlen( tmp ) == 1) && !strncmp( tmp, ".", 1 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  858)           (void)sprintf( buf, "%s", curdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  859)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  860)           (void)sprintf( buf, "%s/%s", curdir, tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  861)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  862)       free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  863) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  864)       srcdir = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  865)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  866) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  867)     stat( (const char *)&buf[0], &st ); /* Do not check return status */
11c606a6 (kx 2023-04-11 01:18:34 +0300  868) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  869)     if( S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  870)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  871)       /**********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  872)         Add default '.pkglist' file name to the source dir name:
11c606a6 (kx 2023-04-11 01:18:34 +0300  873)        */
11c606a6 (kx 2023-04-11 01:18:34 +0300  874)       (void)sprintf( buf, "%s/.pkglist", srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  875)       pkglist_fname = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  876)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  877)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  878)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  879)       if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  880)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  881)         pkglist_fname = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  882)         free( srcdir ); srcdir = xstrdup( (const char *)dirname( (char *)&buf[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  883)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  884)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  885)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  886)         FATAL_ERROR( "Specified '%s' PKGLIST is not a regular file", basename( (char *)&buf[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  887)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  888)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  889) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  890)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  891)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  892)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  893)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  894)     usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  895)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  896) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  897)   /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  898)     root is always have the trailing slash '/':
11c606a6 (kx 2023-04-11 01:18:34 +0300  899)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300  900)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  901)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  902)     char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  903)     int    len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  904) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  905)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  906) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  907)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  908)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  909)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  910) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  911)     if( !root )
11c606a6 (kx 2023-04-11 01:18:34 +0300  912)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  913)       buf[0] = '/'; buf[1] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  914)       root = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  915)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  916)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  917)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  918)       len = strlen( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  919) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  920)       (void)strcpy( buf, (const char *)root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  921)       if( buf[ len - 1 ] != '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  922)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  923)         buf[len] = '/'; buf[len+1] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  924)         free( root ); root = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  925)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  926)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  927) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  928)     if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  929)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  930)       FATAL_ERROR( "Cannot access '%s' file or directory: %s", buf, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  931)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  932)     if( !S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  933)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  934)       FATAL_ERROR( "Defined --root '%s' is not a directory", buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  935)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  936) 
a745159c (kx 2023-10-23 21:39:58 +0300  937)     len = strlen( (const char *)buf );
a745159c (kx 2023-10-23 21:39:58 +0300  938) 
a745159c (kx 2023-10-23 21:39:58 +0300  939)     (void)strcat( buf, PACKAGES_PATH );
a745159c (kx 2023-10-23 21:39:58 +0300  940)     if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
a745159c (kx 2023-10-23 21:39:58 +0300  941)     {
a745159c (kx 2023-10-23 21:39:58 +0300  942)       FATAL_ERROR( "Cannot access '/%s' directory", PACKAGES_PATH );
a745159c (kx 2023-10-23 21:39:58 +0300  943)     }
a745159c (kx 2023-10-23 21:39:58 +0300  944) 
a745159c (kx 2023-10-23 21:39:58 +0300  945)     /*********************************************
a745159c (kx 2023-10-23 21:39:58 +0300  946)       Create other directories of Setup Database:
a745159c (kx 2023-10-23 21:39:58 +0300  947)      */
a745159c (kx 2023-10-23 21:39:58 +0300  948)     buf[len] = '\0';
a745159c (kx 2023-10-23 21:39:58 +0300  949)     (void)strcat( buf, REMOVED_PKGS_PATH );
a745159c (kx 2023-10-23 21:39:58 +0300  950)     if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
a745159c (kx 2023-10-23 21:39:58 +0300  951)     {
a745159c (kx 2023-10-23 21:39:58 +0300  952)       FATAL_ERROR( "Cannot access '/%s' directory", REMOVED_PKGS_PATH );
a745159c (kx 2023-10-23 21:39:58 +0300  953)     }
a745159c (kx 2023-10-23 21:39:58 +0300  954) 
a745159c (kx 2023-10-23 21:39:58 +0300  955)     buf[len] = '\0';
a745159c (kx 2023-10-23 21:39:58 +0300  956)     (void)strcat( buf, SETUP_PATH );
a745159c (kx 2023-10-23 21:39:58 +0300  957)     if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
a745159c (kx 2023-10-23 21:39:58 +0300  958)     {
a745159c (kx 2023-10-23 21:39:58 +0300  959)       FATAL_ERROR( "Cannot access '/%s' directory", SETUP_PATH );
a745159c (kx 2023-10-23 21:39:58 +0300  960)     }
a745159c (kx 2023-10-23 21:39:58 +0300  961) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  962)     free( buf );
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 set root path routine.
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  969) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  970) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  971) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  972) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  973)   Package functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  974)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  975) static char *strprio( enum _priority priority, int short_name )
11c606a6 (kx 2023-04-11 01:18:34 +0300  976) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  977)   char *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  978) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  979)   switch( priority )
11c606a6 (kx 2023-04-11 01:18:34 +0300  980)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  981)     case REQUIRED:
11c606a6 (kx 2023-04-11 01:18:34 +0300  982)       p = ( short_name ) ? "REQ" : "REQUIRED";
11c606a6 (kx 2023-04-11 01:18:34 +0300  983)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  984)     case RECOMMENDED:
11c606a6 (kx 2023-04-11 01:18:34 +0300  985)       p = ( short_name ) ? "REC" : "RECOMMENDED";
11c606a6 (kx 2023-04-11 01:18:34 +0300  986)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  987)     case OPTIONAL:
11c606a6 (kx 2023-04-11 01:18:34 +0300  988)       p = ( short_name ) ? "OPT" : "OPTIONAL";
11c606a6 (kx 2023-04-11 01:18:34 +0300  989)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  990)     case SKIP:
11c606a6 (kx 2023-04-11 01:18:34 +0300  991)       p = ( short_name ) ? "SKP" : "SKIP";
11c606a6 (kx 2023-04-11 01:18:34 +0300  992)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  993)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  994)   return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  995) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  996) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  997) static char *strproc( enum _procedure procedure )
11c606a6 (kx 2023-04-11 01:18:34 +0300  998) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  999)   char *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1000) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1001)   switch( procedure )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1002)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1003)     case INSTALL:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1004)       p = "install";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1005)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1006)     case UPDATE:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1007)       p = "update";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1008)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1009)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1010)   return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1011) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1012) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1013) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1014) static struct pkg *pkg_alloc( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1015) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1016)   struct pkg *pkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1017) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1018)   pkg = (struct pkg *)malloc( sizeof( struct pkg ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1019)   if( !pkg ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1020)   bzero( (void *)pkg, sizeof( struct pkg ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1021) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1022)   return pkg;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1023) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1024) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1025) static void pkg_free( struct pkg *pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1026) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1027)   if( pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1028)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1029)     if( pkg->name )    { free( pkg->name );    pkg->name    = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1030)     if( pkg->version ) { free( pkg->version ); pkg->version = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1031)     if( pkg->group )   { free( pkg->group );   pkg->group   = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1032) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1033)     free( pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1034)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1035) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1036) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1037) static void __pkg_free_func( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1038) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1039)   struct pkg *pkg = (struct pkg *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1040)   if( pkg ) { pkg_free( pkg ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1041) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1042) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1043) static void free_requires( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1044) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1045)   if( requires ) { dlist_free( requires, __pkg_free_func ); requires = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1046) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1047) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1048) static void add_required( struct pkg *pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1049) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1050)   requires = dlist_append( requires, (void *)pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1051) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1052) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1053) ///////////////////// only if we deside to print requires list
11c606a6 (kx 2023-04-11 01:18:34 +0300 1054) //static void _print_requires( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1055) //{
11c606a6 (kx 2023-04-11 01:18:34 +0300 1056) //  struct pkg *pkg = (struct pkg *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1057) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1058) //  if( pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1059) //  {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1060) //    if( pkg->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1061) //      fprintf( stderr, "%s/%s:%s\n", pkg->group, pkg->name, pkg->version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1062) //    else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1063) //      fprintf( stderr, "%s:%s\n", pkg->name, pkg->version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1064) //  }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1065) //}
11c606a6 (kx 2023-04-11 01:18:34 +0300 1066) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1067) //static void print_requires( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1068) //{
11c606a6 (kx 2023-04-11 01:18:34 +0300 1069) //  dlist_foreach( requires, _print_requires, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1070) //}
11c606a6 (kx 2023-04-11 01:18:34 +0300 1071) /////////////////////
11c606a6 (kx 2023-04-11 01:18:34 +0300 1072) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1073) static struct package *package_alloc( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1074) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1075)   struct package *package = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1076) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1077)   package = (struct package *)malloc( sizeof( struct package ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1078)   if( !package ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1079)   bzero( (void *)package, sizeof( struct package ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1080) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1081)   return package;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1082) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1083) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1084) static void package_free( struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1085) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1086)   if( package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1087)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1088)     if( package->name )    { free( package->name );    package->name    = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1089)     if( package->version ) { free( package->version ); package->version = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1090)     if( package->group )   { free( package->group );   package->group   = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1091) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1092)     if( package->description ) { free( package->description ); package->description   = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1093)     if( package->tarball )     { free( package->tarball );     package->tarball   = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1094) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1095)     free( package );
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) static void __package_free_func( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1100) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1101)   struct package *package = (struct package *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1102)   if( package ) { package_free( package ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1103) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1104) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1105) static void free_packages( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1106) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1107)   if( packages ) { dlist_free( packages, __package_free_func ); packages = NULL; }
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) static void add_package( struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1111) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1112)   packages = dlist_append( packages, (void *)package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1113) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1114) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1115) ////////////////////////////// just for testing
11c606a6 (kx 2023-04-11 01:18:34 +0300 1116) //static void _print_packages( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1117) //{
11c606a6 (kx 2023-04-11 01:18:34 +0300 1118) //  struct package *package = (struct package *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1119) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1120) //  if( package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1121) //  {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1122) //    if( package->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1123) //      fprintf( stderr, "%s/%s:%s:%s:%s:%s:%s\n", package->group, package->name, package->version, strproc( package->procedure ), strprio( package->priority, 0 ),
11c606a6 (kx 2023-04-11 01:18:34 +0300 1124) //                                                 package->description, package->tarball );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1125) //    else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1126) //      fprintf( stderr, "%s:%s:%s:%s:%s:%s\n", package->name, package->version, strproc( package->procedure ), strprio( package->priority, 0 ),
11c606a6 (kx 2023-04-11 01:18:34 +0300 1127) //                                              package->description, package->tarball );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1128) //  }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1129) //}
11c606a6 (kx 2023-04-11 01:18:34 +0300 1130) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1131) //static void print_packages( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1132) //{
11c606a6 (kx 2023-04-11 01:18:34 +0300 1133) //  dlist_foreach( packages, _print_packages, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1134) //}
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)   End of package functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1139)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1140) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1141) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1142) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1143)   Return status functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1144)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1145) static struct pkgrc *pkgrc_alloc( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1146) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1147)   struct pkgrc *pkgrc = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1148) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1149)   pkgrc = (struct pkgrc *)malloc( sizeof( struct pkgrc ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1150)   if( !pkgrc ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1151)   bzero( (void *)pkgrc, sizeof( struct pkgrc ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1152) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1153)   return pkgrc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1154) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1155) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1156) static void pkgrc_free( struct pkgrc *pkgrc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1157) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1158)   if( pkgrc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1159)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1160)     if( pkgrc->name )    { free( pkgrc->name );    pkgrc->name    = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1161)     if( pkgrc->version ) { free( pkgrc->version ); pkgrc->version = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1162)     if( pkgrc->group )   { free( pkgrc->group );   pkgrc->group   = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1163) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1164)     free( pkgrc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1165)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1166) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1167) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1168) static void __pkgrc_free_func( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1169) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1170)   struct pkgrc *pkgrc = (struct pkgrc *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1171)   if( pkgrc ) { pkgrc_free( pkgrc ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1172) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1173) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1174) static void free_pkgrcl( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1175) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1176)   if( pkgrcl ) { dlist_free( pkgrcl, __pkgrc_free_func ); pkgrcl = NULL; }
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 add_pkgrc( struct pkgrc *pkgrc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1180) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1181)   pkgrcl = dlist_append( pkgrcl, (void *)pkgrc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1182) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1183) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1184) static struct pkgrc *find_pkgrc( struct dlist *list, pid_t pid )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1185) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1186)   if( !list ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1187) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1188)   while( list && list->data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1189)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1190)     if( ((struct pkgrc *)list->data)->pid == pid ) { return (struct pkgrc *)list->data; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1191)     list = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1192)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1193) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1194)   return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1195) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1196) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1197) static void __remove_success_pkgrc( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1198) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1199)   struct pkgrc *pkgrc = (struct pkgrc *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1200) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1201)   if( pkgrc && pkgrc->status == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1202)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1203)     pkgrcl = dlist_remove( pkgrcl, (const void *)data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1204)     pkgrc_free( pkgrc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1205)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1206) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1207) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1208) static void cleanup_pkgrcl( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1209) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1210)   dlist_foreach( pkgrcl, __remove_success_pkgrc, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1211) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1212) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1213) static void _print_pkgrcl( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1214) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1215)   struct pkgrc *pkgrc = (struct pkgrc *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1216) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1217)   if( pkgrc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1218)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1219)     if( pkgrc->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1220)       fprintf( stderr, "%s/%s:%s:%d\n", pkgrc->group, pkgrc->name, pkgrc->version, pkgrc->status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1221)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1222)       fprintf( stderr, "%s:%s:%d\n", pkgrc->name, pkgrc->version, pkgrc->status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1223)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1224) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1225) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1226) static void return_codes_list( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1227) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1228)   if( pkgrcl )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1229)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1230)     dlist_foreach( pkgrcl, _print_pkgrcl, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1231)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1232) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1233) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1234)   End of return status functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1235)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1236) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1237) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1238) /*******************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1239)   remove spaces at end of line:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1240)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1241) //static void skip_eol_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1242) //{
11c606a6 (kx 2023-04-11 01:18:34 +0300 1243) //  char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1244) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1245) //  if( !s || *s == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1246) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1247) //  p = s + strlen( s ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1248) //  while( isspace( *p ) ) { *p-- = '\0'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1249) //}
11c606a6 (kx 2023-04-11 01:18:34 +0300 1250) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1251) //static char *skip_lead_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1252) //{
11c606a6 (kx 2023-04-11 01:18:34 +0300 1253) //  char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1254) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1255) //  if( !s || *s == '\0' ) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1256) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1257) //  p = s; while( isspace( *p ) ) { ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1258) //
11c606a6 (kx 2023-04-11 01:18:34 +0300 1259) //  return( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1260) //}
11c606a6 (kx 2023-04-11 01:18:34 +0300 1261) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1262) static char *trim( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1263) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1264)   char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1265) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1266)   if( !s || *s == '\0' ) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1267) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1268)   p = s + strlen( s ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1269)   while( isspace( *p ) ) { *p-- = '\0'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1270)   p = s; while( isspace( *p ) ) { ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1271) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1272)   return( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1273) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1274) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1275) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1276) static void read_pkglist_file( const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1277) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1278)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1279)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1280)   int   lnum = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1281) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1282)   FILE *fp   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1283) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1284)   if( !fname || (*fname == '\0') ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1285) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1286)   fp = fopen( fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1287)   if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1288)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1289)     FATAL_ERROR( "Cannot open '%s' PKGLIST file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1290)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1291) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1292)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1293)   if( !line ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1294)   bzero( (void *)line, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1295) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1296)   while( (ln = fgets( line, PATH_MAX, fp )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1297)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1298)     char *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1299)     char *name = NULL, *vers = NULL, *desc = NULL, *ball = NULL, *proc = NULL, *prio = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1300) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1301)     ++lnum;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1302) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1303)     ln[strlen(ln) - 1] = '\0';  /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1304)     ln = trim( ln ); /* remove leading and trailing spaces */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1305) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1306)     if( *ln == '#' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1307)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1308)       if( !strncmp( ln, "# required:", 11 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1309)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1310)         char *n = NULL, *v = NULL, *g = NULL, *q = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1311)         char *rq = ln + 11;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1312)         rq = trim( rq );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1313) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1314)         n = rq;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1315)         if( (q = index( (const char *)n, '/' )) ) { *q = '\0'; g = n; n = ++q; g = trim( g ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1316)         if( (q = index( (const char *)n, '=' )) ) { *q = '\0'; v = ++q; n = trim( n ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1317)         v = trim( v );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1318) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1319)         if( n && v  )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1320)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1321)           struct pkg *pkg = pkg_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1322) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1323)           pkg->name    = xstrdup( (const char *)n );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1324)           pkg->version = xstrdup( (const char *)v );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1325)           if( g )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1326)             pkg->group = xstrdup( (const char *)g );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1327) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1328)           add_required( pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1329)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1330)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1331)       continue; /* skip commented lines */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1332)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1333) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1334)     name = ln;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1335)     if( (p = index( (const char *)name, ':' )) ) { *p = '\0'; vers = ++p; name = trim( name ); } else continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1336)     if( (p = index( (const char *)vers, ':' )) ) { *p = '\0'; desc = ++p; vers = trim( vers ); } else continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1337)     if( (p = index( (const char *)desc, ':' )) ) { *p = '\0'; ball = ++p; desc = trim( desc ); } else continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1338)     if( (p = index( (const char *)ball, ':' )) ) { *p = '\0'; proc = ++p; ball = trim( ball ); } else continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1339)     if( (p = index( (const char *)proc, ':' )) ) { *p = '\0'; prio = ++p; proc = trim( proc ); } else continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1340)     prio = trim( prio );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1341) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1342)     if( name && vers && desc && ball && proc && prio )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1343)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1344)       char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1345)       struct package *package = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1346)       char  *group = index( (const char *)ball, '/' );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1347)       enum _priority priority = OPTIONAL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1348) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1349)       /*******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1350)         Package priority:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1351)        */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1352)       if( strlen( (const char*)prio ) > 2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1353)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1354)         char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1355) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1356)         to_lowercase( prio );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1357)         if( (match = strstr( prio, "req" )) && match == prio ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1358)           priority = REQUIRED;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1359)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1360)         else if( (match = strstr( prio, "rec" )) && match == prio ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1361)           priority = RECOMMENDED;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1362)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1363)         else if( (match = strstr( prio, "opt" )) && match == prio ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1364)           priority = OPTIONAL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1365)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1366)         else if( (match = strstr( prio, "sk" )) && match == prio ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1367)           priority = SKIP;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1368)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1369)         else {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1370)           FATAL_ERROR( "%s: %d: Unknown '%s' priority value", basename( pkglist_fname ), lnum, prio );
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)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1374)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1375)         FATAL_ERROR( "%s: %d: Unknown '%s' priority value", basename( pkglist_fname ), lnum, prio );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1376)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1377) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1378)       if( priority > install_priority ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1379) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1380)       buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1381)       if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1382)       bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1383) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1384)       package = package_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1385) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1386)       package->name        = xstrdup( (const char *)name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1387)       package->version     = xstrdup( (const char *)vers );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1388)       package->description = xstrdup( (const char *)desc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1389) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1390)       (void)sprintf( buf, "%s/%s", (const char *)srcdir, (const char *)ball );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1391)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1392)         enum _input_type type = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1393)         char             uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1394) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1395)         type = check_package_file( &uncompress, (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1396)         if( type != IFMT_PKG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1397)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1398)           FATAL_ERROR( "Unknown format of '%s' package file", (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1399)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1400)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1401)       package->tarball     = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1402) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1403)       free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1404) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1405)       package->priority = priority;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1406) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1407)       /********************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1408)         Install procedure:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1409)        */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1410)       if( strlen( (const char*)proc ) > 5 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1411)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1412)         char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1413) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1414)         to_lowercase( proc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1415)         if( (match = strstr( proc, "install" )) && match == proc ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1416)           package->procedure = INSTALL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1417)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1418)         else if( (match = strstr( proc, "update" )) && match == proc ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1419)           package->procedure = UPDATE;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1420)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1421)         else {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1422)           FATAL_ERROR( "%s: %d: Unknown '%s' procedure value", basename( pkglist_fname ), lnum, proc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1423)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1424)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1425)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1426)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1427)         FATAL_ERROR( "%s: %d: Unknown '%s' procedure value", basename( pkglist_fname ), lnum, proc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1428)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1429) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1430)       if( group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1431)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1432)         *group = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1433)         group = ball;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1434)         package->group = xstrdup( (const char *)group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1435)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1436) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1437)       add_package( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1438)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1439) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1440)   } /* End of while( ln = fgets( line ) ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1441) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1442)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1443)   fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1444) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1445) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1446) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1447) static void check_requires( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1448) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1449)   if( requires )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1450)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1451)     exit_status = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1452) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1453)     fprintf( stdout, "\nThe input '%s' has the list of %d required packages.\n\n", basename( pkglist_fname ), dlist_length( requires ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1454) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1455)     if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1456)     free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1457)     exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1458)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1459) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1460) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1461) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1462) static DIALOG_LISTITEM *alloc_select_items( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1463) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1464)   DIALOG_LISTITEM *items   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1465)   int i = 0, num = dlist_length( packages );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1466)   struct dlist *list = packages, *next = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1467) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1468)   items = (DIALOG_LISTITEM *)malloc( (num + 1) * sizeof(DIALOG_LISTITEM) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1469)   if( !items )  { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1470)   bzero( (void *)items, (num + 1) * sizeof(DIALOG_LISTITEM) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1471) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1472)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1473)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1474)     struct package *package = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1475) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1476)     next = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1477)     package = (struct package *)list->data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1478)     if( package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1479)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1480) #define COLUMN_LENGHT  23         /* 22 symbols for name + " [UP] " */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1481) #define NAME_LENGHT    (COLUMN_LENGHT - 7) /* strlen(" [UP] ") + 1; */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1482) #define UPDATE_SUFFIX  " [UP] "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1483) #define INSTALL_SUFFIX " [in] "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1484) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1485)       char *name = (char *)malloc( (size_t)COLUMN_LENGHT );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1486)       if( !name ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1487)       bzero( (void *)name, (size_t)COLUMN_LENGHT );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1488) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1489)       if( strlen( package->name ) > (size_t)NAME_LENGHT )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1490)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1491)         (void)strncpy( name, (const char *)package->name, NAME_LENGHT - 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1492)         (void)strcat( name, ".." );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1493)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1494)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1495)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1496)         (void)strcpy( name, (const char *)package->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1497)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1498) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1499)       if( package->procedure == UPDATE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1500)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1501)         int p = strlen( name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1502)         while( p < NAME_LENGHT ) { name[p] = ' '; ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1503)         name[p] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1504)         (void)strcat( name, UPDATE_SUFFIX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1505)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1506)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1507)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1508)         int p = strlen( name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1509)         /* while( p < (COLUMN_LENGHT - 1) ) { name[p] = ' '; ++p; } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1510)         while( p < NAME_LENGHT ) { name[p] = ' '; ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1511)         name[p] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1512)         (void)strcat( name, INSTALL_SUFFIX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1513)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1514) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1515)       items[i].name = name;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1516)       items[i].text = xstrdup( (const char *)package->description );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1517)       if( package->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1518)         items[i].help = xstrdup( (const char *)package->group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1519)       items[i].state = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1520)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1521)     ++i;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1522)     list = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1523)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1524)   return items;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1525) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1526) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1527) static void free_select_items( DIALOG_LISTITEM *items )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1528) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1529)   DIALOG_LISTITEM *p = items;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1530) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1531)   if( !p ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1532) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1533)   while( p->name ) { free( p->name ); free( p->text ); if( p->help ) free( p->help ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1534) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1535)   free( items );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1536) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1537) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1538) static void remove_unselected_packages( DIALOG_LISTITEM *items )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1539) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1540)   DIALOG_LISTITEM *p   = items;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1541)   struct dlist    *rem = NULL, *list = NULL, *next = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1542)   int              n   = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1543) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1544)   if( !p ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1545) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1546)   while( p->name )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1547)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1548)     /* copy packages list item to the local list: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1549)     if( !p->state ) { list = dlist_append( list, dlist_nth_data( packages, n ) ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1550)     ++p; ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1551)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1552) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1553)   /****************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1554)     remove items of the local list from packages list:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1555)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1556)   rem = list;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1557)   while( rem )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1558)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1559)     next = dlist_next( rem );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1560)     packages = dlist_remove( packages, rem->data );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1561)     rem = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1562)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1563) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1564)   /***************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1565)     free unselected packages:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1566)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1567)   dlist_free( list, __package_free_func );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1568) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1569) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1570) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1571) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1572) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1573)   Progress functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1574)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1575) static void show_install_con_progress( const char *title, int percent )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1576) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1577) #define GAUGE_LENGTH  68
11c606a6 (kx 2023-04-11 01:18:34 +0300 1578)   size_t  prefix = strlen( title ) + 2; /* title + ' [' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1579)   size_t  suffix = 6;                   /* '] 100%' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1580)   size_t  length = prefix  + GAUGE_LENGTH + suffix;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1581)   int     i, ctx = GAUGE_LENGTH * percent / 100;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1582) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1583)   if( percent <   0 ) percent = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1584)   if( percent > 100 ) percent = 100;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1585) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1586)   printf( "\033[1A" );               /* move the cursor up 1 line   */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1587)   printf( "\033[%dD", (int)length ); /* move cursor to start of line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1588)   printf( "%s [", title );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1589) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1590)   for( i = 0; i < ctx; ++i )     { fprintf( stdout, "\u2588" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1591)   for( ; i < GAUGE_LENGTH; ++i ) { fprintf( stdout, " " );      }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1592) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1593)   printf( "] %3d%%\n", percent );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1594)   fflush( stdout );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1595) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1596) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1597) static void show_progress( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1598) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1599)   const char *title   = "Install:";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1600)   const char *message = "\n"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1601)                         "Please wait for install all specified packages:\n"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1602)                         "\n\n";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1603) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1604)   if( install_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1605)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1606) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1607)     show_install_dlg_progress( 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1608) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1609)     fprintf( stdout, "%s", message );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1610)     show_install_con_progress( title, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1611) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1612)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1613)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1614)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1615)     fprintf( stdout, "%s", message );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1616)     show_install_con_progress( title, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1617)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1618) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1619) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1620) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1621) static void update_progress( int percent )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1622) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1623)   const char *title   = "Install:";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1624) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1625)   if( install_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1626)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1627) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1628)     show_install_dlg_progress( percent );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1629) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1630)     show_install_con_progress( title, percent );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1631) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1632)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1633)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1634)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1635)     show_install_con_progress( title, percent );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1636)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1637) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1638) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1639) static void stop_progress( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1640) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1641)   const char *title   = "Install:";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1642) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1643)   if( install_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1644)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1645) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1646)     show_install_dlg_progress( 100 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1647) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1648)     show_install_con_progress( title, 100 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1649)     fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1650) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1651)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1652)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1653)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1654)     show_install_con_progress( title, 100 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1655)     fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1656)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1657) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1658) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1659)   End of progress functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1660)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1661) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1662) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1663) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1664) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1665)   Install functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1666)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1667) static void install_package( struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1668) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1669)   int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1670)   char *cmd = NULL, *opt = NULL, *out = "> /dev/null 2>&1";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1671) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1672)   if( !package ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1673) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1674)   opt = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1675)   if( !opt ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1676)   bzero( (void *)opt, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1677)   opt[0] = ' ';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1678) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1679)   if( gpgck ) (void)sprintf( opt, "--gpg-verify " );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1680)   if( (install_mode != CONSOLE) && !parallel && !progress ) (void)strcat( opt, "--info-dialog " );
a745159c (kx 2023-10-23 21:39:58 +0300 1681)   if( parallel ) (void)strcat( opt, "--disable-chrefs " );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1682)   if( (install_mode == CONSOLE) && !parallel && !progress ) out = " ";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1683) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1684)   cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1685)   if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1686)   bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1687) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1688)   len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1689)                   "%s/%s-package %s --priority=%s --root=%s %s %s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1690)                   selfdir, strproc( package->procedure ), opt,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1691)                   strprio( package->priority, 1 ),
11c606a6 (kx 2023-04-11 01:18:34 +0300 1692)                   root, package->tarball, out );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1693)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1694)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1695)     FATAL_ERROR( "Cannot install %s-%s package", package->name, package->version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1696)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1697)   if( parallel )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1698)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1699)     struct pkgrc *pkgrc = pkgrc_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1700) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1701)     pkgrc->name    = xstrdup( (const char *)package->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1702)     pkgrc->version = xstrdup( (const char *)package->version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1703)     if( package->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1704)       pkgrc->group = xstrdup( (const char *)package->group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1705)     pkgrc->pid     = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1706) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1707)     add_pkgrc( pkgrc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1708)     ++__child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1709)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1710)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1711)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1712)     pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1713)     int  rc = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1714) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1715)     p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1716)     rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1717)     if( rc != 0 && rc != 31 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1718)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1719)       FATAL_ERROR( "Cannot install '%s-%s' package", package->name, package->version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1720)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1721)     ++__successful;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1722)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1723) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1724)   free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1725)   free( opt );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1726) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1727) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1728) static void _serial_install_package( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1729) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1730)   struct package *package = (struct package *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1731)   int    percent;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1732) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1733)   if( package ) { install_package( package ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1734) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1735)   if( progress )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1736)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1737)     percent = ( __successful < __all ) ? __successful * 100 / __all : 100;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1738)     update_progress( percent );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1739)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1740) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1741) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1742) static void serial_install_packages( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1743) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1744)   if( progress )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1745)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1746)     show_progress();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1747)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1748) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1749)   dlist_foreach( packages, _serial_install_package, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1750) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1751)   if( progress )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1752)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1753)     stop_progress();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1754)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1755) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1756) 
a745159c (kx 2023-10-23 21:39:58 +0300 1757) static int __install_count( void )
a745159c (kx 2023-10-23 21:39:58 +0300 1758) {
a745159c (kx 2023-10-23 21:39:58 +0300 1759)   struct dlist *list = packages, *next = NULL;
a745159c (kx 2023-10-23 21:39:58 +0300 1760)   int ret = 0;
a745159c (kx 2023-10-23 21:39:58 +0300 1761) 
a745159c (kx 2023-10-23 21:39:58 +0300 1762)   while( list )
a745159c (kx 2023-10-23 21:39:58 +0300 1763)   {
a745159c (kx 2023-10-23 21:39:58 +0300 1764)     struct package *package = NULL;
a745159c (kx 2023-10-23 21:39:58 +0300 1765) 
a745159c (kx 2023-10-23 21:39:58 +0300 1766)     next = dlist_next( list );
a745159c (kx 2023-10-23 21:39:58 +0300 1767)     package = (struct package *)list->data;
a745159c (kx 2023-10-23 21:39:58 +0300 1768)     if( package && !strncmp( "install", strproc( package->procedure ), 7 )  )
a745159c (kx 2023-10-23 21:39:58 +0300 1769)     {
a745159c (kx 2023-10-23 21:39:58 +0300 1770)       ++ret;
a745159c (kx 2023-10-23 21:39:58 +0300 1771)     }
a745159c (kx 2023-10-23 21:39:58 +0300 1772)     list = next;
a745159c (kx 2023-10-23 21:39:58 +0300 1773)   }
a745159c (kx 2023-10-23 21:39:58 +0300 1774) 
a745159c (kx 2023-10-23 21:39:58 +0300 1775)   return ret;
a745159c (kx 2023-10-23 21:39:58 +0300 1776) }
a745159c (kx 2023-10-23 21:39:58 +0300 1777) 
a745159c (kx 2023-10-23 21:39:58 +0300 1778) static int __update_count( void )
a745159c (kx 2023-10-23 21:39:58 +0300 1779) {
a745159c (kx 2023-10-23 21:39:58 +0300 1780)   struct dlist *list = packages, *next = NULL;
a745159c (kx 2023-10-23 21:39:58 +0300 1781)   int ret = 0;
a745159c (kx 2023-10-23 21:39:58 +0300 1782) 
a745159c (kx 2023-10-23 21:39:58 +0300 1783)   while( list )
a745159c (kx 2023-10-23 21:39:58 +0300 1784)   {
a745159c (kx 2023-10-23 21:39:58 +0300 1785)     struct package *package = NULL;
a745159c (kx 2023-10-23 21:39:58 +0300 1786) 
a745159c (kx 2023-10-23 21:39:58 +0300 1787)     next = dlist_next( list );
a745159c (kx 2023-10-23 21:39:58 +0300 1788)     package = (struct package *)list->data;
a745159c (kx 2023-10-23 21:39:58 +0300 1789)     if( package && !strncmp( "update", strproc( package->procedure ), 6 )  )
a745159c (kx 2023-10-23 21:39:58 +0300 1790)     {
a745159c (kx 2023-10-23 21:39:58 +0300 1791)       ++ret;
a745159c (kx 2023-10-23 21:39:58 +0300 1792)     }
a745159c (kx 2023-10-23 21:39:58 +0300 1793)     list = next;
a745159c (kx 2023-10-23 21:39:58 +0300 1794)   }
a745159c (kx 2023-10-23 21:39:58 +0300 1795) 
a745159c (kx 2023-10-23 21:39:58 +0300 1796)   return ret;
a745159c (kx 2023-10-23 21:39:58 +0300 1797) }
a745159c (kx 2023-10-23 21:39:58 +0300 1798) 
a745159c (kx 2023-10-23 21:39:58 +0300 1799) static int __nstreams( void )
a745159c (kx 2023-10-23 21:39:58 +0300 1800) {
a745159c (kx 2023-10-23 21:39:58 +0300 1801)   int ret    = 1;
a745159c (kx 2023-10-23 21:39:58 +0300 1802)   int nprocs = get_nprocs();
a745159c (kx 2023-10-23 21:39:58 +0300 1803) 
a745159c (kx 2023-10-23 21:39:58 +0300 1804)   if( nprocs > 4 )
a745159c (kx 2023-10-23 21:39:58 +0300 1805)   {
a745159c (kx 2023-10-23 21:39:58 +0300 1806)     ret = nprocs / 2;
a745159c (kx 2023-10-23 21:39:58 +0300 1807)   }
a745159c (kx 2023-10-23 21:39:58 +0300 1808) 
a745159c (kx 2023-10-23 21:39:58 +0300 1809)   return ret;
a745159c (kx 2023-10-23 21:39:58 +0300 1810) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1811) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1812) static void *install_process( void *args )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1813) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1814)   struct dlist *list = packages, *next = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1815) 
a745159c (kx 2023-10-23 21:39:58 +0300 1816)   int nstreams = __nstreams();
a745159c (kx 2023-10-23 21:39:58 +0300 1817) 
a745159c (kx 2023-10-23 21:39:58 +0300 1818)   /*********************************************
a745159c (kx 2023-10-23 21:39:58 +0300 1819)     install packages with procedure == install:
a745159c (kx 2023-10-23 21:39:58 +0300 1820)    */
a745159c (kx 2023-10-23 21:39:58 +0300 1821)   while( list )
a745159c (kx 2023-10-23 21:39:58 +0300 1822)   {
a745159c (kx 2023-10-23 21:39:58 +0300 1823)     struct package *package = NULL;
a745159c (kx 2023-10-23 21:39:58 +0300 1824) 
a745159c (kx 2023-10-23 21:39:58 +0300 1825)     next = dlist_next( list );
a745159c (kx 2023-10-23 21:39:58 +0300 1826)     package = (struct package *)list->data;
a745159c (kx 2023-10-23 21:39:58 +0300 1827)     if( package && !strncmp( "install", strproc( package->procedure ), 7 ) )
a745159c (kx 2023-10-23 21:39:58 +0300 1828)     {
a745159c (kx 2023-10-23 21:39:58 +0300 1829)       install_package( package );
a745159c (kx 2023-10-23 21:39:58 +0300 1830)     }
a745159c (kx 2023-10-23 21:39:58 +0300 1831)     list = next;
a745159c (kx 2023-10-23 21:39:58 +0300 1832) 
a745159c (kx 2023-10-23 21:39:58 +0300 1833)     /* wait for available CPU: */
a745159c (kx 2023-10-23 21:39:58 +0300 1834)     while( (__child - __terminated) > nstreams ) usleep( START_USEC_FOR_CHILD );
a745159c (kx 2023-10-23 21:39:58 +0300 1835)   }
a745159c (kx 2023-10-23 21:39:58 +0300 1836) 
a745159c (kx 2023-10-23 21:39:58 +0300 1837)   return NULL;
a745159c (kx 2023-10-23 21:39:58 +0300 1838) }
a745159c (kx 2023-10-23 21:39:58 +0300 1839) 
a745159c (kx 2023-10-23 21:39:58 +0300 1840) static void *update_process( void *args )
a745159c (kx 2023-10-23 21:39:58 +0300 1841) {
a745159c (kx 2023-10-23 21:39:58 +0300 1842)   struct dlist *list = packages, *next = NULL;
a745159c (kx 2023-10-23 21:39:58 +0300 1843) 
a745159c (kx 2023-10-23 21:39:58 +0300 1844)   int nstreams = __nstreams();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1845) 
a745159c (kx 2023-10-23 21:39:58 +0300 1846)   /*********************************************
a745159c (kx 2023-10-23 21:39:58 +0300 1847)     install packages with procedure == update:
a745159c (kx 2023-10-23 21:39:58 +0300 1848)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1849)   while( list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1850)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1851)     struct package *package = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1852) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1853)     next = dlist_next( list );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1854)     package = (struct package *)list->data;
a745159c (kx 2023-10-23 21:39:58 +0300 1855)     if( package && !strncmp( "update", strproc( package->procedure ), 6 )  )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1856)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1857)       install_package( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1858)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1859)     list = next;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1860) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1861)     /* wait for available CPU: */
a745159c (kx 2023-10-23 21:39:58 +0300 1862)     while( (__child - __terminated) > nstreams ) usleep( START_USEC_FOR_CHILD );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1863)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1864) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1865)   return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1866) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1867) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1868) static void parallel_install_packages( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1869) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1870)   pthread_t install_process_id;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1871)   int       status;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1872) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1873)   /* Start the parallel installation process: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1874)   status = pthread_create( &install_process_id, NULL, install_process, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1875)   if( status != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1876)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1877)     FATAL_ERROR( "Cannot start parallel installation process" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1878)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1879)   (void)pthread_detach( install_process_id );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1880) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1881) 
a745159c (kx 2023-10-23 21:39:58 +0300 1882) static void parallel_update_packages( void )
a745159c (kx 2023-10-23 21:39:58 +0300 1883) {
a745159c (kx 2023-10-23 21:39:58 +0300 1884)   pthread_t install_process_id;
a745159c (kx 2023-10-23 21:39:58 +0300 1885)   int       status;
a745159c (kx 2023-10-23 21:39:58 +0300 1886) 
a745159c (kx 2023-10-23 21:39:58 +0300 1887)   /* Start the parallel installation process: */
a745159c (kx 2023-10-23 21:39:58 +0300 1888)   status = pthread_create( &install_process_id, NULL, update_process, NULL );
a745159c (kx 2023-10-23 21:39:58 +0300 1889)   if( status != 0 )
a745159c (kx 2023-10-23 21:39:58 +0300 1890)   {
a745159c (kx 2023-10-23 21:39:58 +0300 1891)     FATAL_ERROR( "Cannot start parallel installation process" );
a745159c (kx 2023-10-23 21:39:58 +0300 1892)   }
a745159c (kx 2023-10-23 21:39:58 +0300 1893)   (void)pthread_detach( install_process_id );
a745159c (kx 2023-10-23 21:39:58 +0300 1894) }
a745159c (kx 2023-10-23 21:39:58 +0300 1895) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1896) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1897)   End of install functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1898)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1899) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1900) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1901) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1902) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1903) static void dialogrc( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1904) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1905)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1906)   char  *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1907) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1908)   tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1909)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1910)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1911) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1912)   /* imagine that the utility is in /sbin directory: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1913)   (void)sprintf( &tmp[0], "%s/../usr/share/%s/.dialogrc", selfdir, PACKAGE_NAME );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1914)   if( stat( (const char *)&tmp[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1915)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1916)     /* finaly assume that /usr/sbin is a sbindir: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1917)     (void)sprintf( &tmp[0], "%s/../../usr/share/%s/.dialogrc", selfdir, PACKAGE_NAME );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1918)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1919) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1920)   setenv( "DIALOGRC", (const char *)&tmp[0], 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1921) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1922)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1923) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1924) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1925) static char *get_curdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1926) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1927)   char *cwd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1928) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1929)   cwd = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1930)   if( !cwd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1931)   bzero( (void *)cwd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1932) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1933)   if( getcwd( cwd, (size_t)PATH_MAX ) != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1934)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1935)     char *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1936)     remove_trailing_slash( cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1937)     p = xstrdup( (const char *)cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1938)     free( cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1939)     return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1940)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1941)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1942)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1943)     FATAL_ERROR( "Cannot get absolute path to current directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1944)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1945) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1946)   return (char *)NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1947) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1948) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1949) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1950) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1951)   Get directory where this program is placed:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1952)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1953) char *get_selfdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1954) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1955)   char    *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1956)   ssize_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1957) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1958)   buf = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1959)   if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1960)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1961)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1962)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1963) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1964)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1965)   len = readlink( "/proc/self/exe", buf, (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1966)   if( len > 0 && len < PATH_MAX )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1967)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1968)     char *p = xstrdup( (const char *)dirname( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1969)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1970)     return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1971)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1972)   FATAL_ERROR( "Cannot determine self directory. Please mount /proc filesystem" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1973) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1974) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1975) void set_stack_size( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1976) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1977)   const rlim_t   stack_size = 16 * 1024 * 1024; /* min stack size = 16 MB */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1978)   struct rlimit  rl;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1979)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1980) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1981)   ret = getrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1982)   if( ret == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1983)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1984)     if( rl.rlim_cur < stack_size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1985)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1986)       rl.rlim_cur = stack_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1987)       ret = setrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1988)       if( ret != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1989)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1990)         fprintf(stderr, "setrlimit returned result = %d\n", ret);
11c606a6 (kx 2023-04-11 01:18:34 +0300 1991)         FATAL_ERROR( "Cannot set stack size" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1992)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1993)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1994)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1995) }
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) int main( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1999) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2000)   gid_t  gid;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2001) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2002)   set_signal_handlers();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2003) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2004)   gid = getgid();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2005)   setgroups( 1, &gid );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2006) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2007)   ncpus = get_nprocs();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2008) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2009)   fatal_error_hook = fatal_error_actions;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2010) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2011)   selfdir = get_selfdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2012)   curdir  = get_curdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2013)   dialogrc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2014) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2015)   errlog = stderr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2016) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2017)   program = basename( argv[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2018)   get_args( argc, argv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2019) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2020)   /* set_stack_size(); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2021) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2022)   tmpdir = _mk_tmpdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2023)   if( !tmpdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2024)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2025)     FATAL_ERROR( "Cannot create temporary directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2026)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2027) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2028)   /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2029)     Fill requires and packages lists, check package tarballs,
11c606a6 (kx 2023-04-11 01:18:34 +0300 2030)     skip unnesessary packages according to --priority option:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2031)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2032)   read_pkglist_file( (const char *)pkglist_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2033) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2034)   /* check only the list of requires in the input PKGLIST: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2035)   if( rqck ) check_requires();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2036) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2037) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2038)   if( install_mode == MENUDIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2039)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2040)     int  status = 0, num   = dlist_length( packages );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2041)     DIALOG_LISTITEM *items = alloc_select_items();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2042) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2043)     status = select_packages_box( items, num, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2044)     if( !status )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2045)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2046)       remove_unselected_packages( items );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2047)       free_select_items( items );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2048)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2049)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2050)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2051)       /* Abort installation: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2052)       if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2053)       free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2054) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2055)       exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2056)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2057)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2058) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 2059) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2060) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2061)   if( parallel )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2062)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2063)     /************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2064)       parallel installation:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2065)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2066)     int percent = 0;
a745159c (kx 2023-10-23 21:39:58 +0300 2067)     int __all_install = __install_count();
a745159c (kx 2023-10-23 21:39:58 +0300 2068)     int __all_update  = __update_count();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2069) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2070)     __all  = dlist_length( packages );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2071)     __done = 0; __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2072) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2073)     __terminated = 0; __successful = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2074) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2075)     show_progress();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2076) 
a745159c (kx 2023-10-23 21:39:58 +0300 2077)     /*********************************************
a745159c (kx 2023-10-23 21:39:58 +0300 2078)       install packages with procedure == install:
a745159c (kx 2023-10-23 21:39:58 +0300 2079)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2080)     parallel_install_packages();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2081) 
a745159c (kx 2023-10-23 21:39:58 +0300 2082)     while( !__done )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2083)     {
a745159c (kx 2023-10-23 21:39:58 +0300 2084)       percent = ( __terminated < __all ) ? __terminated * 100 / __all : 100;
a745159c (kx 2023-10-23 21:39:58 +0300 2085) 
a745159c (kx 2023-10-23 21:39:58 +0300 2086)       update_progress( percent );
a745159c (kx 2023-10-23 21:39:58 +0300 2087)       usleep( WAIT_USEC_FOR_CHILD );
a745159c (kx 2023-10-23 21:39:58 +0300 2088)     }
a745159c (kx 2023-10-23 21:39:58 +0300 2089) 
a745159c (kx 2023-10-23 21:39:58 +0300 2090)     __done = 0; __child = 0;
a745159c (kx 2023-10-23 21:39:58 +0300 2091) 
a745159c (kx 2023-10-23 21:39:58 +0300 2092)     if( __all_update )
a745159c (kx 2023-10-23 21:39:58 +0300 2093)     {
a745159c (kx 2023-10-23 21:39:58 +0300 2094)       /*********************************************
a745159c (kx 2023-10-23 21:39:58 +0300 2095)         install packages with procedure == update:
a745159c (kx 2023-10-23 21:39:58 +0300 2096)        */
a745159c (kx 2023-10-23 21:39:58 +0300 2097)       parallel_update_packages();
a745159c (kx 2023-10-23 21:39:58 +0300 2098) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2099)       while( !__done )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2100)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2101)         percent = ( __terminated < __all ) ? __terminated * 100 / __all : 100;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2102) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2103)         update_progress( percent );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2104)         usleep( WAIT_USEC_FOR_CHILD );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2105)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2106) 
a745159c (kx 2023-10-23 21:39:58 +0300 2107)       __done = 0; __child = 0;
a745159c (kx 2023-10-23 21:39:58 +0300 2108)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2109) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2110)     stop_progress();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2111) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2112)     if( __successful < __terminated ) { percent = __successful * 100 / __terminated; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2113)     else                              { percent = 100; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2114) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2115)     __terminated = 0; __successful = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2116) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2117)     if( install_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2118)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2119) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2120)       char *msg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2121) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2122)       msg = (char *)malloc( (size_t)80 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2123)       if( !msg ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2124)       bzero( (void *)msg, 80 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2125) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2126)       (void)sprintf( msg, "\nSuccessfully installed %d%% of %d specified packages.\n", percent, __all );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2127) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2128)       (void)info_box( " \\Z0INSTALL PACKAGES\\Zn ", msg, 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2129) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2130)       free( msg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2131) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2132)       fprintf( stdout, "\nSuccessfully installed %d%% of %d specified packages.\n\n", percent, __all );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2133) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 2134)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2135)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2136)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2137)       fprintf( stdout, "\nSuccessfully installed %d%% of %d specified packages.\n\n", percent, __all );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2138)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2139) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2140)     cleanup_pkgrcl();  /* remove successfully installed packages from return codes list */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2141)     if( pkgrcl && error_pkgs_list )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2142)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2143)       return_codes_list();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2144)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2145)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2146)   else
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)       serial installation:
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)     __successful = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2153)     __all        = dlist_length( packages );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2154) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2155)     serial_install_packages();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2156) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2157)     if( install_mode != CONSOLE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2158)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2159) #if defined( HAVE_DIALOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2160)       info_box( " \\Z4INSTALL PACKAGES\\Zn ",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2161)                 "\nAll of specified packages have been installed.\n", 5, 0, 0 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2162) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2163)       fprintf( stdout, "\nAll of specified packages have been installed.\n\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2164) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 2165)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2166)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2167)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2168)       fprintf( stdout, "\nAll of specified packages have been installed.\n\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2169)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2170) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2171)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2172) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2173)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2174)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2175) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2176)   exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2177) }