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 <fcntl.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   29) #include <linux/limits.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   30) #include <alloca.h>   /* alloca(3)   */
11c606a6 (kx 2023-04-11 01:18:34 +0300   31) #include <string.h>   /* strdup(3)   */
11c606a6 (kx 2023-04-11 01:18:34 +0300   32) #include <libgen.h>   /* basename(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300   33) #include <ctype.h>    /* tolower(3)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300   34) #include <errno.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   35) #include <time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   36) #include <sys/time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   37) #include <pwd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   38) #include <grp.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   39) #include <stdarg.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   40) #include <unistd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   41) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   42) #include <math.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   43) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   44) #include <sys/resource.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   45) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   46) #include <signal.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   47) #if !defined SIGCHLD && defined SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   48) # define SIGCHLD SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   49) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300   50) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   51) #define _GNU_SOURCE
11c606a6 (kx 2023-04-11 01:18:34 +0300   52) #include <getopt.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   53) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   54) #include <msglog.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   55) #include <wrapper.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   56) #include <system.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   57) #include <dlist.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   58) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   59) #define PROGRAM_NAME "make-package"
11c606a6 (kx 2023-04-11 01:18:34 +0300   60) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   61) #include <defs.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   62) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   63) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   64) char *program = PROGRAM_NAME;
11c606a6 (kx 2023-04-11 01:18:34 +0300   65) char *destination = NULL, *srcdir = NULL, *flavour = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   66)      *tmpdir = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   67) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   68) FILE   *rlinks  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   69) size_t  pkgsize = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300   70) int     nfiles  = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300   71) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   72) const char *txz_suffix = ".txz";
11c606a6 (kx 2023-04-11 01:18:34 +0300   73) char  compress = 'J';
11c606a6 (kx 2023-04-11 01:18:34 +0300   74) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   75) #if defined( HAVE_GPG2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300   76) char *gnupghome = NULL, *passphrase = NULL, *key_id = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   77) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300   78) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   79) int   exit_status = EXIT_SUCCESS; /* errors counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300   80) char *selfdir     = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   81) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   82) int   mkgroupdir  = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300   83) int   linkadd     = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300   84) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   85) static char           *pkgname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   86)                        *pkgver = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   87)                          *arch = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   88)                    *distroname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   89)                     *distrover = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   90)                         *group = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   91)             *short_description = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   92)                           *url = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   93)                       *license = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   94)             *uncompressed_size = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   95)                   *total_files = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   96) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   97) struct dlist *filelist = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   98) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   99) static void create_file_list( void );
11c606a6 (kx 2023-04-11 01:18:34 +0300  100) static void free_file_list( void );
11c606a6 (kx 2023-04-11 01:18:34 +0300  101) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  102) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  103) #define FREE_PKGINFO_VARIABLES() \
11c606a6 (kx 2023-04-11 01:18:34 +0300  104)   if( pkgname )           { free( pkgname );           } pkgname = NULL;            \
11c606a6 (kx 2023-04-11 01:18:34 +0300  105)   if( pkgver )            { free( pkgver );            } pkgver = NULL;             \
11c606a6 (kx 2023-04-11 01:18:34 +0300  106)   if( arch )              { free( arch );              } arch = NULL;               \
11c606a6 (kx 2023-04-11 01:18:34 +0300  107)   if( distroname )        { free( distroname );        } distroname = NULL;         \
11c606a6 (kx 2023-04-11 01:18:34 +0300  108)   if( distrover )         { free( distrover );         } distrover = NULL;          \
11c606a6 (kx 2023-04-11 01:18:34 +0300  109)   if( group )             { free( group );             } group = NULL;              \
11c606a6 (kx 2023-04-11 01:18:34 +0300  110)   if( short_description ) { free( short_description ); } short_description = NULL;  \
11c606a6 (kx 2023-04-11 01:18:34 +0300  111)   if( url )               { free( url );               } url = NULL;                \
11c606a6 (kx 2023-04-11 01:18:34 +0300  112)   if( license )           { free( license );           } license = NULL;            \
11c606a6 (kx 2023-04-11 01:18:34 +0300  113)   if( uncompressed_size ) { free( uncompressed_size ); } uncompressed_size = NULL;  \
11c606a6 (kx 2023-04-11 01:18:34 +0300  114)   if( total_files )       { free( total_files );       } total_files = NULL
11c606a6 (kx 2023-04-11 01:18:34 +0300  115) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  116) void free_resources()
11c606a6 (kx 2023-04-11 01:18:34 +0300  117) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  118)   if( srcdir )        { free( srcdir );        srcdir        = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  119)   if( destination )   { free( destination );   destination   = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  120)   if( flavour )       { free( flavour );       flavour       = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  121)   if( filelist )      { free_file_list();      filelist      = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  122) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  123) #if defined( HAVE_GPG2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  124)   if( gnupghome )     { free( gnupghome );     gnupghome     = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  125)   if( passphrase )    { free( passphrase );    passphrase    = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  126)   if( key_id )        { free( key_id );        key_id        = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  127) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  128) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  129)   if( selfdir )       { free( selfdir );       selfdir       = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  130) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  131)   FREE_PKGINFO_VARIABLES();
11c606a6 (kx 2023-04-11 01:18:34 +0300  132) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  133) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  134) void usage()
11c606a6 (kx 2023-04-11 01:18:34 +0300  135) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  136)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  137) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  138)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  139)   fprintf( stdout, "Usage: %s [options] <srcpkgdir>\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  140)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  141)   fprintf( stdout, "Create PACKAGE from SRCPKGDIR where package is installed. The source\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  142)   fprintf( stdout, "directory should content the package service files:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  143)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  144)   fprintf( stdout, "  .PKGINFO, .INSTALL, .DESCRIPTION, and .REQUIRES (if applicable)\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  145)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  146)   fprintf( stdout, "The '.PKGINFO' file is obligatory and should content declarations of\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  147)   fprintf( stdout, "following variables:  pkgname, pkgver, arch,  distroname, distrover.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  148)   fprintf( stdout, "Also in the .PKGINFO file  can be defined additional and recommended\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  149)   fprintf( stdout, "variables: group, short_description, url, license.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  150)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  151)   fprintf( stdout, "Options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  152)   fprintf( stdout, "  -h,--help                  Display this information.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  153)   fprintf( stdout, "  -v,--version               Display the version of %s utility.\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  154)   fprintf( stdout, "  -d,--destination=<DIR>     Target directory to save output PACKAGE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  155)   fprintf( stdout, "  -m,--mkgroupdir            Create GROUP subdirectory in the PACKAGE\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  156)   fprintf( stdout, "                             target directory.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  157)   fprintf( stdout, "  -l,--linkadd={y|n}         Create .RESTORELINKS scrypt (default yes).\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  158)   fprintf( stdout, "  -f,--flavour=<subdir>      The name of additional subdirectory in the\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  159)   fprintf( stdout, "                             GROUP directory to save target PACKAGE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  160)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  161) #if defined( HAVE_GPG2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  162)   fprintf( stdout, "OpenPGP options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  163)   fprintf( stdout, "  -g,--gnupghome=<DIR>       Set the name of the GnuPG home directory\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  164)   fprintf( stdout, "                             to <DIR>. If this option is not used it\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  165)   fprintf( stdout, "                             defaults to '~/.gnupg'. This also overrides\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  166)   fprintf( stdout, "                             the environment variable 'GNUPGHOME'.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  167)   fprintf( stdout, "  -p,--passphrase=<FILE>     File with passphrase of private certificate\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  168)   fprintf( stdout, "                             for signing package. For example:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  169)   fprintf( stdout, "                                ~/.gnupg/.passphrase\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  170)   fprintf( stdout, "                             Passphrase should be placed in the first\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  171)   fprintf( stdout, "                             line of the file (the new-line symbol at\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  172)   fprintf( stdout, "                             end of passphrase is allowed). File must\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  173)   fprintf( stdout, "                             have access mode 600.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  174)   fprintf( stdout, "  -k,--key-id=<USER-ID>      Use USER-ID to sign package, for example,\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  175)   fprintf( stdout, "                             --key-id=0xA5ED710298807270\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  176)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  177) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  178)   fprintf( stdout, "Compression options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  179)   fprintf( stdout, "  -J,--xz                    Filter the package archive through xz(1).\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  180)   fprintf( stdout, "  -j,--bzip2                 Filter the package archive through bzip2(1).\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  181)   fprintf( stdout, "  -z,--gzip                  Filter the package archive through gzip(1).\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  182)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  183) #if defined( HAVE_GPG2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  184)   fprintf( stdout, "  If one of arguments:  passphrase or key-id  is not specified, then\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  185)   fprintf( stdout, "  signature will not be created and utility doesn't return any error\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  186)   fprintf( stdout, "  code.  If error occurs during the creation of a package signature,\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  187)   fprintf( stdout, "  the utility returns error code, but continue to create the package\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  188)   fprintf( stdout, "  (in this case the signature will not be created).\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  189)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  190) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  191)   fprintf( stdout, "Parameter:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  192)   fprintf( stdout, "  <srcpkgdir>                Directory wich contains source package\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  193)   fprintf( stdout, "                             and package service files.\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  194)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  195) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  196)   exit( EXIT_FAILURE );
11c606a6 (kx 2023-04-11 01:18:34 +0300  197) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  198) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  199) void to_lowercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  200) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  201)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  202)   while( p && *p ) { int c = *p; *p = tolower( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  203) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  204) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  205) void to_uppercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  206) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  207)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  208)   while( p && *p ) { int c = *p; *p = toupper( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  209) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  210) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  211) void version()
11c606a6 (kx 2023-04-11 01:18:34 +0300  212) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  213)   char *upper = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  214) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  215)   upper = (char *)alloca( strlen( program ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  216) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  217)   strcpy( (char *)upper, (const char *)program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  218)   to_uppercase( upper );
11c606a6 (kx 2023-04-11 01:18:34 +0300  219) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  220)   fprintf( stdout, "%s (%s) %s\n", program, upper, PROGRAM_VERSION );
11c606a6 (kx 2023-04-11 01:18:34 +0300  221) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  222)   fprintf( stdout, "Copyright (C) 2019 Andrey V.Kosteltsev.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  223)   fprintf( stdout, "This is free software.   There is NO warranty; not even\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  224)   fprintf( stdout, "for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  225)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  226) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  227)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  228)   exit( EXIT_SUCCESS );
11c606a6 (kx 2023-04-11 01:18:34 +0300  229) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  230) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  231) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  232) static void remove_trailing_slash( char *dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  233) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  234)   char *s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  235) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  236)   if( !dir || dir[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  237) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  238)   s = dir + strlen( dir ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  239)   while( *s == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  240)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  241)     *s = '\0'; --s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  242)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  243) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  244) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  245) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  246) static int _mkdir_p( const char *dir, const mode_t mode )
11c606a6 (kx 2023-04-11 01:18:34 +0300  247) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  248)   char  *buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  249)   char  *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  250)   struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  251) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  252)   if( !dir ) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  253) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  254)   buf = (char *)alloca( strlen( dir ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  255)   strcpy( buf, dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  256) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  257)   remove_trailing_slash( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  258) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  259)   /* check if path exists and is a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  260)   if( stat( buf, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  261)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  262)     if( S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  263)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  264)       return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  265)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  266)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  267) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  268)   /* mkdir -p */
11c606a6 (kx 2023-04-11 01:18:34 +0300  269)   for( p = buf + 1; *p; ++p )
11c606a6 (kx 2023-04-11 01:18:34 +0300  270)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  271)     if( *p == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  272)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  273)       *p = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  274)       /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  275)       if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  276)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  277)         /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  278)         if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  279)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  280)           return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  281)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  282)       } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  283)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  284)         /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  285)         return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  286)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  287)       *p = '/';
11c606a6 (kx 2023-04-11 01:18:34 +0300  288)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  289)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  290) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  291)   /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  292)   if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  293)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  294)     /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  295)     if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  296)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  297)       return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  298)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  299)   } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  300)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  301)     /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  302)     return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  303)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  304) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  305)   return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  306) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  307) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  308) static void _rm_tmpdir( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300  309) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  310)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300  311)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300  312)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  313) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  314)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  315)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300  316) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  317)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  318)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  319)     return; /* stat returns error code; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  320)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  321) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  322)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  323)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  324)     return; /* dirpath is not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  325)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  326) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  327)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  328)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  329)     return; /* Cannot open direcroty; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  330)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  331) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  332)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  333) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  334)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300  335)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  336) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  337)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  338)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300  339) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  340)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300  341)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  342)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  343)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  344)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  345) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  346)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  347)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  348)       if( S_ISDIR(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  349)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  350)         /* recursively remove a nested directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  351)         _rm_tmpdir( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  352)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  353)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  354)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  355)         /* remove a file object */
11c606a6 (kx 2023-04-11 01:18:34 +0300  356)         (void)unlink( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  357)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  358)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  359)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300  360) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  361)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  362) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  363)   /* remove the devastated directory and close the object of this directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  364)   (void)rmdir( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  365) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  366)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  367) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  368) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  369) static char *_mk_tmpdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  370) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  371)   char   *buf = NULL, *p, *tmp = "/tmp";
11c606a6 (kx 2023-04-11 01:18:34 +0300  372)   size_t  len = 0, size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  373) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  374)   (void)umask( S_IWGRP | S_IWOTH ); /* octal 022 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  375) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  376)   /* Get preferred directory for tmp files */
11c606a6 (kx 2023-04-11 01:18:34 +0300  377)   if( (p = getenv( "TMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  378)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  379)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  380)   else if( (p = getenv( "TEMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  381)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  382)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  383) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  384)   size = strlen( tmp ) + strlen( DISTRO_NAME ) + strlen( program ) + 12;
11c606a6 (kx 2023-04-11 01:18:34 +0300  385) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  386)   buf = (char *)malloc( size );
11c606a6 (kx 2023-04-11 01:18:34 +0300  387)   if( !buf ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  388) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  389)   len = snprintf( buf, size, (const char *)"%s/%s/%s-%.7u", tmp, DISTRO_NAME, program, getpid() );
11c606a6 (kx 2023-04-11 01:18:34 +0300  390)   if( len == 0 || len == size - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  391)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  392)     free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  393)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  394) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  395)   _rm_tmpdir( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  396) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  397)   if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  398)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  399)     return buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  400)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  401) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  402)   free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  403) }
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) void fatal_error_actions( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  407) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  408)   logmsg( errlog, MSG_NOTICE, "Free resources on FATAL error..." );
11c606a6 (kx 2023-04-11 01:18:34 +0300  409)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  410)   free_resources();
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) void sigint( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  414) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  415)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  416) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  417)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  418)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  419) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  420) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  421) static void set_signal_handlers()
11c606a6 (kx 2023-04-11 01:18:34 +0300  422) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  423)   struct sigaction  sa;
11c606a6 (kx 2023-04-11 01:18:34 +0300  424)   sigset_t          set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  425) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  426)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  427)   sa.sa_handler = sigint;          /* TERM, INT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  428)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  429)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  430)   sigaddset( &set, SIGTERM );
11c606a6 (kx 2023-04-11 01:18:34 +0300  431)   sigaddset( &set, SIGINT );
11c606a6 (kx 2023-04-11 01:18:34 +0300  432)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  433)   sigaction( SIGTERM, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  434)   sigaction( SIGINT, &sa,  NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  435) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  436)   memset( &sa, 0, sizeof( sa ) );  /* ignore SIGPIPE */
11c606a6 (kx 2023-04-11 01:18:34 +0300  437)   sa.sa_handler = SIG_IGN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  438)   sa.sa_flags = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  439)   sigaction( SIGPIPE, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  440) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  441)   /* System V fork+wait does not work if SIGCHLD is ignored */
11c606a6 (kx 2023-04-11 01:18:34 +0300  442)   signal( SIGCHLD, SIG_DFL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  443) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  444) 
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) void get_args( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300  448) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  449) #if defined( HAVE_GPG2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  450)   const char* short_options = "hvmd:l:f:g:p:k:Jjz";
11c606a6 (kx 2023-04-11 01:18:34 +0300  451) #else
11c606a6 (kx 2023-04-11 01:18:34 +0300  452)   const char* short_options = "hvmd:l:f:Jjz";
11c606a6 (kx 2023-04-11 01:18:34 +0300  453) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  454) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  455)   const struct option long_options[] =
11c606a6 (kx 2023-04-11 01:18:34 +0300  456)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  457)     { "help",        no_argument,       NULL, 'h' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  458)     { "version",     no_argument,       NULL, 'v' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  459)     { "destination", required_argument, NULL, 'd' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  460)     { "mkgroupdir",  no_argument,       NULL, 'm' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  461)     { "linkadd",     required_argument, NULL, 'l' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  462)     { "flavour",     required_argument, NULL, 'f' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  463) #if defined( HAVE_GPG2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  464)     { "gnupghome",   required_argument, NULL, 'g' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  465)     { "passphrase",  required_argument, NULL, 'p' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  466)     { "key-id",      required_argument, NULL, 'k' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  467) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  468)     { "xz",          no_argument,       NULL, 'J' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  469)     { "bzip2",       no_argument,       NULL, 'j' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  470)     { "gzip",        no_argument,       NULL, 'z' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  471)     { NULL,          0,                 NULL,  0  }
11c606a6 (kx 2023-04-11 01:18:34 +0300  472)   };
11c606a6 (kx 2023-04-11 01:18:34 +0300  473) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  474)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  475)   int option_index = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  476) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  477)   while( (ret = getopt_long( argc, argv, short_options, long_options, &option_index )) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  478)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  479)     switch( ret )
11c606a6 (kx 2023-04-11 01:18:34 +0300  480)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  481)       case 'h':
11c606a6 (kx 2023-04-11 01:18:34 +0300  482)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  483)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  484)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  485)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  486)       case 'v':
11c606a6 (kx 2023-04-11 01:18:34 +0300  487)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  488)         version();
11c606a6 (kx 2023-04-11 01:18:34 +0300  489)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  490)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  491) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  492)       case 'd':
11c606a6 (kx 2023-04-11 01:18:34 +0300  493)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  494)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  495)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  496)           destination = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  497)           remove_trailing_slash( destination );
11c606a6 (kx 2023-04-11 01:18:34 +0300  498)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  499)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  500)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  501)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  502)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  503)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  504)       case 'm':
11c606a6 (kx 2023-04-11 01:18:34 +0300  505)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  506)         mkgroupdir = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  507)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  508)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  509) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  510)       case 'J':
11c606a6 (kx 2023-04-11 01:18:34 +0300  511)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  512)         compress = 'J';
11c606a6 (kx 2023-04-11 01:18:34 +0300  513)         txz_suffix = ".txz";
11c606a6 (kx 2023-04-11 01:18:34 +0300  514)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  515)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  516)       case 'j':
11c606a6 (kx 2023-04-11 01:18:34 +0300  517)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  518)         compress = 'j';
11c606a6 (kx 2023-04-11 01:18:34 +0300  519)         txz_suffix = ".tbz";
11c606a6 (kx 2023-04-11 01:18:34 +0300  520)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  521)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  522)       case 'z':
11c606a6 (kx 2023-04-11 01:18:34 +0300  523)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  524)         compress = 'z';
11c606a6 (kx 2023-04-11 01:18:34 +0300  525)         txz_suffix = ".tgz";
11c606a6 (kx 2023-04-11 01:18:34 +0300  526)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  527)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  528) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  529)       case 'l':
11c606a6 (kx 2023-04-11 01:18:34 +0300  530)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  531)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  532)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  533)           char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  534)           size_t len = strlen( optarg ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  535) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  536)           buf = (char *)malloc( len );
11c606a6 (kx 2023-04-11 01:18:34 +0300  537)           if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  538)           bzero( (void *)buf, len );
11c606a6 (kx 2023-04-11 01:18:34 +0300  539) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  540)           (void)strcpy( buf, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  541)           to_lowercase( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  542)           if( !strncmp( (const char *)&buf[0], "n", 1 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  543)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  544)             linkadd = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  545)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  546)           free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  547)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  548)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  549)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  550)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  551)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  552)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  553)       case 'f':
11c606a6 (kx 2023-04-11 01:18:34 +0300  554)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  555)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  556)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  557)           char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  558)           size_t len = strlen( optarg ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  559) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  560)           buf = (char *)malloc( len );
11c606a6 (kx 2023-04-11 01:18:34 +0300  561)           if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  562)           bzero( (void *)buf, len );
11c606a6 (kx 2023-04-11 01:18:34 +0300  563) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  564)           (void)strcpy( buf, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  565)           to_lowercase( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  566) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  567)           flavour = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  568)           free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  569)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  570)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  571)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  572)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  573)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  574)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  575) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  576) #if defined( HAVE_GPG2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  577)       case 'g':
11c606a6 (kx 2023-04-11 01:18:34 +0300  578)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  579)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  580)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  581)           struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  582)           char  *buf  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  583)           char  *home = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  584) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  585)           bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  586) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  587)           buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  588)           if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  589)           bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  590) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  591)           if( *optarg == '~' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  592)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  593)             home = getenv( "HOME" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  594)             if( home )
11c606a6 (kx 2023-04-11 01:18:34 +0300  595)             {
11c606a6 (kx 2023-04-11 01:18:34 +0300  596)               (void)sprintf( buf, "%s/%s", home, (const char *)((char *)optarg + 2) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  597)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300  598)             else
11c606a6 (kx 2023-04-11 01:18:34 +0300  599)             {
11c606a6 (kx 2023-04-11 01:18:34 +0300  600)               FATAL_ERROR( "Cannot get HOME directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  601)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300  602)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  603)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300  604)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  605)             (void)strcpy( buf, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  606)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  607) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  608)           if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  609)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  610)             FATAL_ERROR( "Cannot access '%s' GnuPG home directory: %s", buf, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  611)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  612)           if( !S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  613)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  614)             FATAL_ERROR( "The GNUPGHOME '%s' is not a directory", buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  615)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  616) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  617)           remove_trailing_slash( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  618)           gnupghome = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  619)           free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  620)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  621)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  622)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  623)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  624)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  625)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  626)       case 'p':
11c606a6 (kx 2023-04-11 01:18:34 +0300  627)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  628)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  629)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  630)           struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  631)           char  *buf  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  632)           char  *home = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  633) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  634)           bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  635) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  636)           buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  637)           if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  638)           bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  639) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  640)           if( *optarg == '~' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  641)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  642)             home = getenv( "HOME" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  643)             if( home )
11c606a6 (kx 2023-04-11 01:18:34 +0300  644)             {
11c606a6 (kx 2023-04-11 01:18:34 +0300  645)               (void)sprintf( buf, "%s/%s", home, (const char *)((char *)optarg + 2) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  646)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300  647)             else
11c606a6 (kx 2023-04-11 01:18:34 +0300  648)             {
11c606a6 (kx 2023-04-11 01:18:34 +0300  649)               FATAL_ERROR( "Cannot get HOME directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  650)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300  651)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  652)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300  653)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  654)             (void)strcpy( buf, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  655)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  656) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  657)           if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  658)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  659)             FATAL_ERROR( "Cannot access '%s' passphrase source file: %s", basename( buf ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  660)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  661)           if( !S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  662)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  663)             FATAL_ERROR( "The passphrase '%s' is not a regular file", basename( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  664)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  665) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  666)           passphrase = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  667)           free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  668)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  669)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  670)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  671)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  672)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  673)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  674)       case 'k':
11c606a6 (kx 2023-04-11 01:18:34 +0300  675)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  676)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  677)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  678)           key_id = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  679)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  680)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  681)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  682)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  683)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  684)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  685) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300  686) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  687)       case '?': default:
11c606a6 (kx 2023-04-11 01:18:34 +0300  688)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  689)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  690)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  691)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  692)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  693)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  694) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  695)   /* last command line argument is the PACKAGE source directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  696)   if( optind < argc )
11c606a6 (kx 2023-04-11 01:18:34 +0300  697)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  698)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  699)     char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  700) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  701)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  702) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  703)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  704)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  705)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  706) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  707)     (void)strcpy( buf, (const char *)argv[optind] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  708)     remove_trailing_slash( (char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  709) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  710)     if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  711)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  712)       FATAL_ERROR( "Cannot access '%s' PACKAGE source directory: %s", basename( buf ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  713)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  714) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  715)     if( ! S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  716)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  717)       FATAL_ERROR( "The PACKAGE source '%s' is not a directory", basename( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  718)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  719) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  720)     /* Add .PKGINFO to the input dir name: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  721)     (void)strcat( buf, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  722)     if( stat( (const char *)&buf[0], &st ) == -1 ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  723)       FATAL_ERROR( "The defined SRCPKGDIR doesn't contain a valid package" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  724)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  725)     *(strstr( buf, "/.PKGINFO" )) = '\0'; /* restore tmpdir in tmp[] buffer */
11c606a6 (kx 2023-04-11 01:18:34 +0300  726) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  727)     /* Add .DESCRIPTION to the input dir name: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  728)     (void)strcat( buf, "/.DESCRIPTION" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  729)     if( stat( (const char *)&buf[0], &st ) == -1 ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  730)       FATAL_ERROR( "The defined SRCPKGDIR doesn't contain package '.DESCRIPTION' file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  731)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  732)     *(strstr( buf, "/.DESCRIPTION" )) = '\0'; /* restore tmpdir in tmp[] buffer */
11c606a6 (kx 2023-04-11 01:18:34 +0300  733) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  734)     /* Add .INSTALL to the input dir name: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  735)     (void)strcat( buf, "/.INSTALL" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  736)     if( stat( (const char *)&buf[0], &st ) == -1 ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  737)       FATAL_ERROR( "The defined SRCPKGDIR doesn't contain package '.INSTALL' script" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  738)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  739)     *(strstr( buf, "/.INSTALL" )) = '\0'; /* restore tmpdir in tmp[] buffer */
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)     srcdir = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  743)     if( srcdir == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  744)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  745)       usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  746)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  747) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  748)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  749)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  750)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  751)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  752)     usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  753)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  754) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  755)   if( destination == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  756)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  757)     char *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  758) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  759)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  760)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  761)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  762) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  763)     (void)strcpy( buf, (const char *)srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  764)     remove_trailing_slash( (char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  765) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  766)     destination = xstrdup( (const char *)dirname( (char *)&buf[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  767) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  768)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  769)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  770) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  771) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  772) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  773) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  774)   Especialy for pkginfo lines.
11c606a6 (kx 2023-04-11 01:18:34 +0300  775)   Remove leading spaces and take non-space characters only:
11c606a6 (kx 2023-04-11 01:18:34 +0300  776)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  777) static char *skip_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  778) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  779)   char *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  780) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  781)   if( !s || *s == '\0' ) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  782) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  783)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  784) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  785)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  786)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  787) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  788)   if( *p == '\0' ) return (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  789) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  790)   return( xstrdup( (const char *)p ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  791) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  792) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  793) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  794)   remove spaces at end of line:
11c606a6 (kx 2023-04-11 01:18:34 +0300  795)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  796) static void skip_eol_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  797) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  798)   char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  799) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  800)   if( !s || *s == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  801) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  802)   p = s + strlen( s ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  803)   while( isspace( *p ) ) { *p-- = '\0'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  804) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  805) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  806) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  807) static void read_pkginfo( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  808) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  809)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  810)   char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  811)   FILE  *pkginfo;
11c606a6 (kx 2023-04-11 01:18:34 +0300  812) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  813)   bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  814) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  815)   buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  816)   if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  817)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  818) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  819)   (void)strcpy( buf, (const char *)srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  820)   (void)strcat( buf, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  821) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  822)   if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  823)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  824)     FATAL_ERROR( "Cannot access .PKGINFO file: %s", strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  825)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  826)   if( !S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  827)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  828)     FATAL_ERROR( "The '%s' is not a regular file", basename( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  829)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  830) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  831)   pkginfo = fopen( (const char *)&buf[0], "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  832)   if( !pkginfo )
11c606a6 (kx 2023-04-11 01:18:34 +0300  833)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  834)     FATAL_ERROR( "Cannot open '%s' file", basename( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  835)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  836) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  837)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  838)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  839)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  840) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  841)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  842)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300  843)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  844)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  845)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  846)   
11c606a6 (kx 2023-04-11 01:18:34 +0300  847)     while( (ln = fgets( line, PATH_MAX, pkginfo )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  848)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  849)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  850) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  851)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  852)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300  853) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  854)       if( (match = strstr( ln, "pkgname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  855)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  856)         if( p != NULL ) pkgname = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  857)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  858)       if( (match = strstr( ln, "pkgver" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  859)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  860)         if( p != NULL ) pkgver = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  861)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  862) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  863)       if( (match = strstr( ln, "group" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  864)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  865)         if( p != NULL ) group = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  866)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  867) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  868)       if( (match = strstr( ln, "arch" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  869)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  870)         if( p != NULL ) arch = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  871)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  872)       if( (match = strstr( ln, "distroname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  873)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  874)         if( p != NULL ) distroname = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  875)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  876)       if( (match = strstr( ln, "distrover" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  877)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  878)         if( p != NULL ) distrover = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  879)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  880) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  881)       if( (match = strstr( ln, "short_description" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  882)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  883)         if( p != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  884)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  885)           char *b =  index( p, '"'),
11c606a6 (kx 2023-04-11 01:18:34 +0300  886)                *e = rindex( p, '"');
11c606a6 (kx 2023-04-11 01:18:34 +0300  887)           if( b && e && ( b != e ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  888)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  889)             p = ++b; *e = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  890)             short_description = xstrdup( (const char *)p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  891)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  892)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  893)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  894)       if( (match = strstr( ln, "url" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  895)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  896)         if( p != NULL ) url = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  897)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  898)       if( (match = strstr( ln, "license" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  899)         char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  900)         if( p != NULL ) license = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  901)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  902)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  903) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  904)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300  905) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  906)     if( !pkgname || !pkgver || !arch || !distroname || !distrover )
11c606a6 (kx 2023-04-11 01:18:34 +0300  907)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  908)       FATAL_ERROR( "Invalid input .PKGINFO file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  909)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  910) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  911)     if( !url )     { url     = xstrdup( DISTRO_URL );     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  912)     if( !license ) { license = xstrdup( DISTRO_LICENSE ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  913)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  914) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  915)   fclose( pkginfo );
11c606a6 (kx 2023-04-11 01:18:34 +0300  916)   free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  917) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  918) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  919) static void tune_destinations( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  920) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  921)   if( mkgroupdir && group )
11c606a6 (kx 2023-04-11 01:18:34 +0300  922)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  923)     char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  924) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  925)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  926)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  927)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  928) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  929)     (void)strcpy( buf, (const char *)destination );
11c606a6 (kx 2023-04-11 01:18:34 +0300  930)     (void)strcat( buf, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  931)     (void)strcat( buf, (const char *)group );
11c606a6 (kx 2023-04-11 01:18:34 +0300  932)     if( flavour )
11c606a6 (kx 2023-04-11 01:18:34 +0300  933)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  934)       (void)strcat( buf, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  935)       (void)strcat( buf, (const char *)flavour );
11c606a6 (kx 2023-04-11 01:18:34 +0300  936)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  937) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  938)     if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  939)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  940)       FATAL_ERROR( "Cannot create target directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  941)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  942) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  943)     free( destination );
11c606a6 (kx 2023-04-11 01:18:34 +0300  944)     destination = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  945)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  946)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  947) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  948)   /* here we can allocate memory for output filenames */
11c606a6 (kx 2023-04-11 01:18:34 +0300  949) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  950) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  951) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  952)   .RESTORELINKS functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  953)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  954) static void start_restorelinks_file( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  955) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  956)   char *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  957) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  958)   tmp = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  959)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  960)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  961) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  962)   (void)sprintf( (char *)&tmp[0], "%s/%s", tmpdir, ".RESTORELINKS" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  963) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  964)   rlinks = fopen( (const char *)&tmp[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  965)   if( !rlinks )
11c606a6 (kx 2023-04-11 01:18:34 +0300  966)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  967)     FATAL_ERROR( "Cannot create '.RESTORELINKS' file"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  968)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  969)   free( tmp );
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) static void stop_restorelinks_file( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  973) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  974)   struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  975)   char  *tmp = NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  976)   int    len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  977) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  978)   fflush( rlinks ); fclose( rlinks );
11c606a6 (kx 2023-04-11 01:18:34 +0300  979) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  980)   tmp = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  981)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  982)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  983) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  984)   (void)sprintf( (char *)&tmp[0], "%s/%s", tmpdir, ".RESTORELINKS" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  985) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  986)   if( stat( tmp, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  987)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  988)     if( S_ISREG(sb.st_mode) && sb.st_size != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  989)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  990)       pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  991)       int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300  992) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  993)       cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  994)       if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  995)       bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  996) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  997)       len = snprintf( &cmd[0], PATH_MAX, "cp %s %s/ > /dev/null 2>&1", tmp, srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  998)       if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  999)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1000)         FATAL_ERROR( "Cannot create '.RESTORELINKS' file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1001)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1002)       p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1003)       rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1004)       if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1005)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1006)         FATAL_ERROR( "Cannot create '.RESTORELINKS' file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1007)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1008) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1009)       free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1010)     }
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)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1014) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1015) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1016) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1017) static void save_link( const char *name_in, const char *name_to, const char *name_is )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1018) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1019)   if( rlinks )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1020)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1021)     fprintf( rlinks, "( cd %s ; rm -rf %s )\n", name_in, name_is );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1022)     fprintf( rlinks, "( cd %s ; ln -sf %s %s )\n", name_in, name_to, name_is );
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1026) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1027)   End of .RESTORELINKS functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1028)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1029) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1030) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1031)   File list functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1032)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1033) static void _print_filelist_entry( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1034) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1035)   const char *path = (const char *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1036)   FILE *output = (FILE *)user_data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1037) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1038)   if( !output ) output = stdout;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1039) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1040)   fprintf( output, "%s\n", path );
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_filelist_entry( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1044) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1045)   if( data ) { free( data ); }
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 int _compare_fnames( const void *a, const void *b )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1049) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1050)   const char *s1 = (const char *)a;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1051)   const char *s2 = (const char *)b;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1052) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1053)   return strcmp( s1, s2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1054) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1055) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1056) static void _push_file( const char *name )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1057) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1058)   char *fname = (char *)name + strlen( srcdir ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1059)   filelist = dlist_append( filelist, (void *)xstrdup( (const char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1060) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1061) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1062) static void _push_dir( const char *name )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1063) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1064)   char *buf   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1065)   char *dname = (char *)name + strlen( srcdir ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1066) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1067)   buf = (char *)malloc( strlen( dname ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1068)   if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1069)   (void)sprintf( &buf[0], "%s/", dname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1070) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1071)   filelist = dlist_append( filelist, (void *)xstrdup( (const char *)&buf[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1072)   free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1073) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1074) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1075) static void _list_files( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1076) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1077)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1078)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1079)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1080) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1081)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1082)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1083) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1084)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1085)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1086)     FATAL_ERROR( "%s: Cannot stat source directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1087)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1088) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1089)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1090)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1091)     FATAL_ERROR( "%s: Source path is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1092)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1093) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1094)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1095)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1096)     FATAL_ERROR( "Canot access '%s' directory: %s", dirpath, strerror( errno ) );
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)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1100) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1101)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1102)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1103)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1104)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1105) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1106)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1107)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1108) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1109)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1110)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1111)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1112) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1113)     if( lstat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1114)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1115)       if( S_ISDIR(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1116)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1117)         _push_dir( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1118)         pkgsize += (size_t)entry_sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1119)         _list_files( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1120)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1121)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1122)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1123)         if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1124)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1125)           char *service = basename( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1126) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1127)           /* skip service files: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1128)           if( strcmp( service, ".DESCRIPTION"  ) &&
11c606a6 (kx 2023-04-11 01:18:34 +0300 1129)               strcmp( service, ".FILELIST"     ) &&
11c606a6 (kx 2023-04-11 01:18:34 +0300 1130)               strcmp( service, ".INSTALL"      ) &&
11c606a6 (kx 2023-04-11 01:18:34 +0300 1131)               strcmp( service, ".PKGINFO"      ) &&
11c606a6 (kx 2023-04-11 01:18:34 +0300 1132)               strcmp( service, ".REQUIRES"     ) &&
11c606a6 (kx 2023-04-11 01:18:34 +0300 1133)               strcmp( service, ".RESTORELINKS" )   )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1134)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1135)             _push_file( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1136)             pkgsize += (size_t)entry_sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1137)             ++nfiles;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1138)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1139)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1140)         if( S_ISBLK(entry_sb.st_mode)  ||
11c606a6 (kx 2023-04-11 01:18:34 +0300 1141)             S_ISCHR(entry_sb.st_mode)  ||
11c606a6 (kx 2023-04-11 01:18:34 +0300 1142)             S_ISFIFO(entry_sb.st_mode) ||
11c606a6 (kx 2023-04-11 01:18:34 +0300 1143)             S_ISSOCK(entry_sb.st_mode)   )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1144)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1145)           _push_file( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1146)           ++nfiles;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1147)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1148)         if( S_ISLNK(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1149)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1150)           if( linkadd )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1151)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1152)             char   *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1153)             ssize_t len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1154) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1155)             const char *in = (char *)dirpath + strlen( srcdir ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1156)             const char *is = (char *)path + strlen( dirpath ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1157) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1158)             buf = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1159)             if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1160)             bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1161) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1162)             if( (len = readlink( (const char *)path, buf, PATH_MAX - 1 )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1163)             {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1164)               FATAL_ERROR( "%s: Cannot read link: %s", is, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1165)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1166)             buf[len] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1167)             save_link( in, (const char *)&buf[0], is );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1168)             free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1169) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1170)             /* remove the link: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1171)             (void)unlink( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1172)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1173)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1174)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1175)             _push_file( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1176)             ++nfiles;
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1180)       } /* End if( S_ISDIR(entry_sb.st_mode) ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1181) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1182)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1183)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1184)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1185) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1186)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1187) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1188) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1189) static void create_file_list( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1190) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1191)   start_restorelinks_file();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1192)   _list_files( (const char *)srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1193)   stop_restorelinks_file();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1194) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1195)   if( filelist )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1196)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1197)     FILE *flist = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1198)     char *tmp   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1199) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1200)     tmp = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1201)     if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1202)     bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1203) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1204)     (void)sprintf( (char *)&tmp[0], "%s/%s", srcdir, ".FILELIST" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1205) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1206)     flist = fopen( (const char *)&tmp[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1207)     if( !flist )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1208)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1209)       FATAL_ERROR( "Cannot create '.FILELIST' file"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1210)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1211) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1212)     /*********************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1213)       save total number of files:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1214)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1215)     (void)sprintf( (char *)&tmp[0], "%d", nfiles );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1216)     total_files = xstrdup( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1217) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1218)     /*********************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1219)       save uncompressed package size:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1220)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1221)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1222)       int    nd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1223)       double sz = (double)pkgsize / (double)1024;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1224) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1225)       if( sz > (double)1048576 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1226)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1227)         sz = sz / (double)1048576;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1228)         /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1229)           NOTE:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1230)           ----
11c606a6 (kx 2023-04-11 01:18:34 +0300 1231)           Операция округления до одного знака после десятичной точки: sz = round(sz*10.0)/10.0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1232)           здесь не нужна; можно обойтись вычислением количества цифр, выводимых на печать с помощью
11c606a6 (kx 2023-04-11 01:18:34 +0300 1233)           формата '%.*g':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1234) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1235)           Количество десятичных цифр, необходимое для предстваления целой части числа + 1(одна)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1236)           десятичная цифра после десятичной точки. Формат %.*g не будет выводить дробную часть
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)          */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1240)         nd = (int)ceil(log10(floor(sz) + 1.0)) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1241)         (void)sprintf( (char *)&tmp[0], "%.*gG", nd, sz );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1242)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1243)       else if( sz > (double)1024 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1244)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1245)         sz = sz / (double)1024;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1246)         nd = (int)ceil(log10(floor(sz) + 1.0)) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1247)         (void)sprintf( (char *)&tmp[0], "%.*gM", nd, sz );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1248)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1249)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1250)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1251)         nd = (int)ceil(log10(floor(sz) + 1.0)) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1252)         (void)sprintf( (char *)&tmp[0], "%.*gK", nd, sz );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1253)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1254)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1255)     uncompressed_size = xstrdup( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1256) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1257)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1258) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1259)     filelist = dlist_sort( filelist, _compare_fnames );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1260)     dlist_foreach( filelist, _print_filelist_entry, flist );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1261) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1262)     fflush( flist );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1263)     fclose( flist );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1264)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1265)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1266)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1267)     FATAL_ERROR( "There are no files in the source package"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1268)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1269) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1270) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1271) static void free_file_list( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1272) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1273)   if( filelist ) { dlist_free( filelist, _free_filelist_entry ); filelist = NULL; }
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)   End of file list functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1277)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1278) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1279) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1280)   Description functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1281)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1282) static void get_short_description( char *buf, const char *line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1283) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1284)   char *s, *p, *q;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1285) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1286)   if( buf ) { buf[0] = '\0'; s = buf; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1287)   if( !line || line[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1288) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1289)   p = index( line, '(' );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1290)   q = index( line, ')' );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1291)   if( p && q && q > p )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1292)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1293)     ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1294)     while( *p && p < q )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1295)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1296)       *s = *p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1297)       ++p; ++s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1298)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1299)     *s = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1300)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1301)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1302)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1303)     /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1304)       If short description declaration is incorrect at first line
11c606a6 (kx 2023-04-11 01:18:34 +0300 1305)       of description; then we take whole first line of description:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1306)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1307)     p = index( line, ':' ); ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1308)     while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1309)     strcpy( buf, p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1310)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1311) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1312) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1313) static char *read_short_description( FILE *fh )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1314) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1315)   char *ret  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1316)   char *buf  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1317) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1318)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1319)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1320) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1321)   buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1322)   if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1323)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1324) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1325)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1326)   if( !line ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1327)   bzero( (void *)line, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1328) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1329)   /* Get short_description from PACKAGE DESCRIPTION */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1330)   ln = fgets( line, PATH_MAX, fh );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1331)   ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1332) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1333)   get_short_description( buf, (const char *)line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1334)   if( buf[0] != '\0' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1335)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1336)     ret = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1337)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1338)   free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1339) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1340)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1341) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1342) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1343) static void create_description_file( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1344) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1345)   struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1346)   char  *buf  = NULL, *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1347)   int    n = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1348) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1349)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1350)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1351) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1352)   FILE *srcdesc = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1353)   FILE *tmpdesc = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1354)   FILE *outdesc = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1355) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1356)   buf = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1357)   if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1358)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1359) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1360)   tmp = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1361)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1362)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1363) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1364)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1365)   if( !line ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1366)   bzero( (void *)line, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1367) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1368)   (void)sprintf( (char *)&tmp[0], "%s/%s", srcdir, ".DESCRIPTION" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1369) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1370)   if( stat( tmp, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1371)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1372)     if( S_ISREG(sb.st_mode) && sb.st_size != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1373)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1374)       srcdesc = fopen( (const char *)&tmp[0], "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1375)       if( !srcdesc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1376)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1377)         FATAL_ERROR( "Cannot read source '.DESCRIPTION' file"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1378)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1379)       bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1380) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1381)       (void)sprintf( (char *)&tmp[0], "%s/%s", tmpdir, ".DESCRIPTION" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1382)       tmpdesc = fopen( (const char *)&tmp[0], "w+" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1383)       if( !tmpdesc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1384)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1385)         FATAL_ERROR( "Cannot create output '.DESCRIPTION' file"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1386)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1387)       bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1388) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1389)       (void)sprintf( (char *)&tmp[0], "%s/%s-%s-%s-%s-%s.txt",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1390)                                        destination, pkgname, pkgver, arch, distroname, distrover );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1391)       outdesc = fopen( (const char *)&tmp[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1392)       if( !outdesc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1393)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1394)         FATAL_ERROR( "Cannot create output '.DESCRIPTION' file"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1395)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1396)       bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1397) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1398)       (void)sprintf( (char *)&buf[0], "%s:", pkgname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1399) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1400)       fprintf( outdesc, "\n/* begin *\n\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1401) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1402)       while( (ln = fgets( line, PATH_MAX, srcdesc )) && n < DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1403)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1404)         char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1405) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1406)         ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1407) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1408)         if( (match = strstr( (const char *)ln, (const char *)buf )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1409)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1410)           int mlen   = strlen( match ), plen = strlen( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1411)           int length = ( mlen > plen )  ? (mlen - plen - 1) : 0 ;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1412) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1413)           if( length > DESCRIPTION_LENGTH_OF_LINE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1414)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1415)             /* WARNING( "Package DESCRIPTION contains lines with length greater than %d characters", DESCRIPTION_LENGTH_OF_LINE ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1416)             match[plen + 1 + DESCRIPTION_LENGTH_OF_LINE] = '\0'; /* truncating description line  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1417)             skip_eol_spaces( match );                            /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1418)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1419) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1420)           fprintf( tmpdesc, "%s\n", match );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1421)           match += plen + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1422)           if( match[0] != '\0' ) { fprintf( outdesc, "   %s\n", match ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1423)           else                   { fprintf( outdesc, "\n" );             }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1424)           ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1425)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1426)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1427) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1428)       fprintf( outdesc, " * end */\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1429) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1430)       if( !short_description )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1431)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1432)         /* try to get short description from .DESCRIPTION file */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1433)         fseek( tmpdesc, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1434)         short_description = read_short_description( tmpdesc );
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)       fflush( tmpdesc ); fclose( tmpdesc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1438)       fflush( outdesc ); fclose( outdesc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1439)       fclose( srcdesc );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1440) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1441)       /* Copy tmpdesc file to the source package directory: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1442)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1443)         char *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1444) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1445)         bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1446)         (void)sprintf( (char *)&tmp[0], "%s/%s", tmpdir, ".DESCRIPTION" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1447) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1448)         if( stat( tmp, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1449)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1450)           if( S_ISREG(sb.st_mode) && sb.st_size != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1451)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1452)             pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1453)             int   rc, len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1454) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1455)             cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1456)             if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1457)             bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1458) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1459)             len = snprintf( &cmd[0], PATH_MAX, "cp %s %s/ > /dev/null 2>&1", tmp, srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1460)             if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1461)             {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1462)               FATAL_ERROR( "Cannot create output '.DESCRIPTION' file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1463)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1464)             p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1465)             rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1466)             if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1467)             {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1468)               FATAL_ERROR( "Cannot create output '.DESCRIPTION' file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1469)             }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1470) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1471)             free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1472)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1473)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1474)       } /* End of copy tmpdesc file. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1475)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1476)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1477) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1478)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1479)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1480)   free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1481) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1482) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1483)   End of description functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1484)  *********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1485) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1486) static void rewrite_pkginfo_file( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1487) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1488)   FILE *info = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1489)   char *tmp  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1490) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1491)   tmp = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1492)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1493)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1494) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1495)   (void)sprintf( (char *)&tmp[0], "%s/%s", srcdir, ".PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1496) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1497)   info = fopen( (const char *)&tmp[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1498)   if( !info )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1499)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1500)     FATAL_ERROR( "Cannot create '.PKGINFO' file"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1501)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1502) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1503)   if( pkgname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1504)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1505)     (void)sprintf( (char *)&tmp[0], "pkgname=%s\n", pkgname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1506)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1507)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1508)   if( pkgver )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1509)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1510)     (void)sprintf( (char *)&tmp[0], "pkgver=%s\n", pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1511)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1512)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1513)   if( arch )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1514)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1515)     (void)sprintf( (char *)&tmp[0], "arch=%s\n", arch );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1516)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1517)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1518)   if( distroname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1519)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1520)     (void)sprintf( (char *)&tmp[0], "distroname=%s\n", distroname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1521)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1522)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1523)   if( distrover )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1524)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1525)     (void)sprintf( (char *)&tmp[0], "distrover=%s\n", distrover );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1526)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1527)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1528)   if( group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1529)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1530)     (void)sprintf( (char *)&tmp[0], "group=%s\n", group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1531)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1532)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1533)   if( short_description )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1534)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1535)     (void)sprintf( (char *)&tmp[0], "short_description=\"%s\"\n", short_description );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1536)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1537)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1538)   if( url )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1539)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1540)     (void)sprintf( (char *)&tmp[0], "url=%s\n", url );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1541)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1542)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1543)   if( license )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1544)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1545)     (void)sprintf( (char *)&tmp[0], "license=%s\n", license );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1546)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1547)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1548)   if( uncompressed_size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1549)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1550)     (void)sprintf( (char *)&tmp[0], "uncompressed_size=%s\n", uncompressed_size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1551)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1552)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1553)   if( total_files )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1554)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1555)     (void)sprintf( (char *)&tmp[0], "total_files=%s\n", total_files );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1556)     fprintf( info, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1557)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1558) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1559)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1560) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1561)   fflush( info );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1562)   fclose( info );
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) static const char *fill_compressor( char *buffer, char compressor )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1566) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1567)   switch( compressor )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1568)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1569)     default:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1570)     case 'J':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1571)       (void)sprintf( buffer, "xz -9 --threads=%d -c", get_nprocs() );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1572)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1573)     case 'j':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1574)       (void)sprintf( buffer, "bzip2 -9 -c" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1575)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1576)     case 'z':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1577)       (void)sprintf( buffer, "gzip -9 -c" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1578)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1579)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1580)   return (const char *)buffer;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1581) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1582) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1583) static void create_package( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1584) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1585)   pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1586)   int   rc, len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1587) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1588)   char *tmp = NULL, *cwd = NULL, *dst = NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1589) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1590) #define tar_suffix ".tar"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1591) #define sha_suffix ".sha"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1592) #define asc_suffix ".asc"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1593) #define ACLS       "--acls"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1594) #define XATTRS     "--xattrs"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1595) #define HASHER     "sha256sum -b"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1596) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1597)   char compressor[64];
11c606a6 (kx 2023-04-11 01:18:34 +0300 1598)   (void)fill_compressor( (char *)&compressor[0], compress );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1599) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1600)   tmp = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1601)   if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1602)   bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1603) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1604)   cwd = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1605)   if( !cwd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1606)   bzero( (void *)cwd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1607) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1608)   dst = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1609)   if( !dst ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1610)   bzero( (void *)dst, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1611) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1612)   cmd = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1613)   if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1614)   bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1615) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1616)   /* absolute current directory path: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1617)   if( getcwd( cwd, (size_t)PATH_MAX ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1618)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1619)     FATAL_ERROR( "%s-%s-%s-%s-%s%s: Cannot create PACKAGE: %s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1620)                   pkgname, pkgver, arch, distroname, distrover, txz_suffix, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1621)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1622)   remove_trailing_slash( cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1623) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1624)   /****************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1625)     absolute destination path:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1626)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1627)   (void)sprintf( (char *)&tmp[0], "%s", destination );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1628)   if( tmp[0] != '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1629)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1630)     (void)sprintf( (char *)&dst[0], "%s/%s/%s", cwd, dirname( (char *)&tmp[0] ), basename( destination ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1631)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1632)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1633)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1634)     (void)sprintf( (char *)&dst[0], "%s", destination );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1635)   }
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)     change CWD to source package directory:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1639)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1640)   if( chdir( (const char *)srcdir ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1641)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1642)     FATAL_ERROR( "Cannot change CWD to the package source directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1643)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1644) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1645)   /************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1646)     Set mode 0755 for .INSTALL script:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1647)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1648)   (void)sprintf( (char *)&cmd[0], "chmod 0755 ./.INSTALL" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1649)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1650)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1651)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1652)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1653)     FATAL_ERROR( "Cannot make .INSTAL script executable" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1654)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1655) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1656)   /**********************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1657)     push package files into tarball:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1658)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1659)   len = snprintf( (char *)&cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1660)     "find ./ | sed 's,^\\./,,' | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1661)               "sed 's,\\.DESCRIPTION,,'  | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1662)               "sed 's,\\.FILELIST,,'     | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1663)               "sed 's,\\.INSTALL,,'      | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1664)               "sed 's,\\.PKGINFO,,'      | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1665)               "sed 's,\\.REQUIRES,,'     | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1666)               "sed 's,\\.RESTORELINKS,,' | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1667)               "tar --no-recursion %s %s -T - -cvf %s/%s-%s-%s-%s-%s%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1668)     ACLS, XATTRS, dst, pkgname, pkgver, arch, distroname, distrover, tar_suffix );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1669)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1670)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1671)     FATAL_ERROR( "Cannot push package files into tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1672)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1673)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1674)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1675)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1676)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1677)     FATAL_ERROR( "Cannot push package files into tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1678)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1679) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1680)   /**********************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1681)     push service files into tarball:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1682)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1683)   len = snprintf( (char *)&cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1684)     "find ./ -type f \\( -name '.DESCRIPTION' -o "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1685)                         "-name '.FILELIST'    -o "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1686)                         "-name '.INSTALL'     -o "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1687)                         "-name '.PKGINFO'     -o "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1688)                         "-name '.REQUIRES'    -o "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1689)                         "-name '.RESTORELINKS' \\) | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1690)               "sed 's,^\\./,,' | "
11c606a6 (kx 2023-04-11 01:18:34 +0300 1691)               "tar --no-recursion %s %s -T - --append -f %s/%s-%s-%s-%s-%s%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1692)     ACLS, XATTRS, dst, pkgname, pkgver, arch, distroname, distrover, tar_suffix );
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 push service files into tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1696)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1697)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1698)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1699)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1700)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1701)     FATAL_ERROR( "Cannot push service files into tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1702)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1703) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1704)   /**********************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1705)     push service files into tarball:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1706)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1707)   len = snprintf( (char *)&cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1708)     "cat %s/%s-%s-%s-%s-%s%s | %s > %s/%s-%s-%s-%s-%s%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1709)          dst, pkgname, pkgver, arch, distroname, distrover, tar_suffix,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1710)          compressor, dst, pkgname, pkgver, arch, distroname, distrover, txz_suffix );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1711)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1712)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1713)     FATAL_ERROR( "Cannot compress tarball" );
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 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1718)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1719)     FATAL_ERROR( "Cannot compress tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1720)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1721) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1722)   /******************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1723)     remove uncompressed tarball:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1724)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1725)   len = snprintf( (char *)&cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1726)     "rm -f %s/%s-%s-%s-%s-%s%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1727)          dst, pkgname, pkgver, arch, distroname, distrover, tar_suffix );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1728)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1729)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1730)     FATAL_ERROR( "Cannot remove umcompressed tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1731)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1732)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1733)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1734)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1735)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1736)     FATAL_ERROR( "Cannot remove umcompressed tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1737)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1738) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1739)   /***********************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1740)     NOTE:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1741)       To check SHA sum we can make use 'shasum' utility:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1742)       $ ( cd destination ; shasum --check filename.sha )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1743)       without explicitly indicated algorithm [-a 256].
11c606a6 (kx 2023-04-11 01:18:34 +0300 1744) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1745)     generate SHA-256 sum of tarball:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1746)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1747)   len = snprintf( (char *)&cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1748)     "%s %s/%s-%s-%s-%s-%s%s | sed 's,%s/,,' > %s/%s-%s-%s-%s-%s%s", HASHER,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1749)      dst, pkgname, pkgver, arch, distroname, distrover, txz_suffix,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1750)       dst, dst, pkgname, pkgver, arch, distroname, distrover, sha_suffix );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1751)   if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1752)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1753)     FATAL_ERROR( "Cannot generate SHA-256 sum of package tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1754)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1755)   p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1756)   rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1757)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1758)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1759)     FATAL_ERROR( "Cannot generate SHA-256 sum of package tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1760)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1761) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1762) #if defined( HAVE_GPG2 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1763)   /*******************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1764)     generate GPG ascii-signature:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1765)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1766)   if( !gnupghome )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1767)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1768)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1769)     char  *home = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1770) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1771)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1772) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1773)     home = getenv( "GNUPGHOME" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1774)     if( home )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1775)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1776)       (void)sprintf( tmp, "%s", home );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1777)       if( (stat( (const char *)&tmp[0], &st ) == 0) && S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1778)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1779)         gnupghome = xstrdup( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1780)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1781)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1782)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1783)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1784)       home = getenv( "HOME" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1785)       if( home )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1786)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1787)         (void)sprintf( tmp, "%s/.gnupg", home );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1788)         if( (stat( (const char *)&tmp[0], &st ) == 0) && S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1789)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1790)           gnupghome = xstrdup( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1791)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1792)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1793)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1794)     /* Check GNUPGHOME directory: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1795)     while( gnupghome )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1796)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1797)       (void)sprintf( tmp, "%s/%s", gnupghome, "private-keys-v1.d" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1798)       if( (stat( (const char *)&tmp[0], &st ) == -1) || !S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1799)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1800)         free( gnupghome ); gnupghome = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1801)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1802)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1803)       (void)sprintf( tmp, "%s/pubring.kbx", gnupghome );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1804)       if( (stat( (const char *)&tmp[0], &st ) == -1) || !S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1805)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1806)         free( gnupghome ); gnupghome = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1807)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1808)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1809)       (void)sprintf( tmp, "%s/trustdb.gpg", gnupghome );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1810)       if( (stat( (const char *)&tmp[0], &st ) == -1) || !S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1811)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1812)         free( gnupghome ); gnupghome = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1813)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1814)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1815)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1816)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1817)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1818)   if( gnupghome && passphrase && key_id )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1819)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1820)     (void)sprintf( tmp, "%s/%s", tmpdir, ".gnupg" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1821)     if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1822)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1823)       FATAL_ERROR( "Cannot create temporary GnuPG home directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1824)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1825) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1826)     len = snprintf( (char *)&cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1827)       "chmod 700 %s ;"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1828)       " cp %s/trustdb.gpg %s/ ;"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1829)       " cp %s/pubring.kbx %s/ ;"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1830)       " cp -r %s/private-keys-v1.d %s/",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1831)       tmp,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1832)       gnupghome, tmp,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1833)       gnupghome, tmp,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1834)       gnupghome, tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1835)     if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1836)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1837)       FATAL_ERROR( "Cannot prepare temporary GnuPG home for signing" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1838)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1839)     p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1840)     rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1841)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1842)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1843)       ERROR( "Cannot prepare temporary GnuPG home for signing" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1844)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1845) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1846)     len = snprintf( (char *)&cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1847)       "cat %s | GNUPGHOME=%s gpg2 -u %s --batch --passphrase-fd=0"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1848)                " --pinentry-mode=loopback"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1849)                " --armor --yes --emit-version"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1850)                " --comment %s-%s"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1851)                " -o %s/%s-%s-%s-%s-%s%s"
11c606a6 (kx 2023-04-11 01:18:34 +0300 1852)                " --detach-sign %s/%s-%s-%s-%s-%s%s 2>/dev/null 1>/dev/null",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1853)       passphrase, tmp, key_id,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1854)       pkgname, pkgver,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1855)       dst, pkgname, pkgver, arch, distroname, distrover, asc_suffix,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1856)       dst, pkgname, pkgver, arch, distroname, distrover, txz_suffix );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1857)     if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1858)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1859)       FATAL_ERROR( "Cannot generate GPG signature of package tarball" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1860)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1861)     p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1862)     rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1863)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1864)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1865)       ERROR( "Cannot generate GPG signature of package tarball" );
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) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 1869) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1870)   /******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1871)     change CWD back:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1872)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1873)   if( chdir( (const char *)&cwd[0] ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1874)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1875)     FATAL_ERROR( "Cannot change CWD back" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1876)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1877) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1878)   fprintf( stdout, "\n%s package %s/%s-%s-%s-%s-%s%s has been created.\n\n",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1879)                       DISTRO_CAPTION,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1880)                         destination, pkgname, pkgver, arch, distroname, distrover, txz_suffix );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1881) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1882)   free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1883)   free( dst );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1884)   free( cwd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1885)   free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1886) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1887) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1888) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1889) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1890) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1891)   Get directory where this program is placed:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1892)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1893) char *get_selfdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1894) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1895)   char    *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1896)   ssize_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1897) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1898)   buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1899)   if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1900)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1901)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1902)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1903) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1904)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1905)   len = readlink( "/proc/self/exe", buf, (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1906)   if( len > 0 && len < PATH_MAX )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1907)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1908)     char *p = xstrdup( (const char *)dirname( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1909)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1910)     return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1911)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1912)   FATAL_ERROR( "Cannot determine self directory. Please mount /proc filesystem" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1913) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1914) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1915) void set_stack_size( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1916) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1917)   const rlim_t   stack_size = 16 * 1024 * 1024; /* min stack size = 16 MB */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1918)   struct rlimit  rl;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1919)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1920) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1921)   ret = getrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1922)   if( ret == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1923)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1924)     if( rl.rlim_cur < stack_size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1925)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1926)       rl.rlim_cur = stack_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1927)       ret = setrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1928)       if( ret != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1929)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1930)         fprintf(stderr, "setrlimit returned result = %d\n", ret);
11c606a6 (kx 2023-04-11 01:18:34 +0300 1931)         FATAL_ERROR( "Cannot set stack size" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1932)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1933)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1934)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1935) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1936) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1937) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1938) int main( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1939) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1940)   gid_t  gid;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1941) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1942)   set_signal_handlers();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1943) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1944)   gid = getgid();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1945)   setgroups( 1, &gid );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1946) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1947)   fatal_error_hook = fatal_error_actions;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1948) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1949)   selfdir = get_selfdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1950) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1951)   errlog = stderr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1952) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1953)   program = basename( argv[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1954)   get_args( argc, argv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1955) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1956)   /* set_stack_size(); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1957) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1958)   tmpdir = _mk_tmpdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1959)   if( !tmpdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1960)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1961)     FATAL_ERROR( "Cannot create temporary directory" );
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)   read_pkginfo();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1965)   tune_destinations();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1966)   create_file_list();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1967)   create_description_file();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1968)   /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1969)     NOTE:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1970)       rewrite_pkginfo_file() should be called after create_description_file()
11c606a6 (kx 2023-04-11 01:18:34 +0300 1971)       because if there is no short description in the source .PKGINFO file
11c606a6 (kx 2023-04-11 01:18:34 +0300 1972)       then we can try to get the short description from the first line of
11c606a6 (kx 2023-04-11 01:18:34 +0300 1973)       .DESCRIPTION file (between opening and closing round brackets).
11c606a6 (kx 2023-04-11 01:18:34 +0300 1974)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1975)   rewrite_pkginfo_file();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1976)   create_package();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1977) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1978) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1979)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1980)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1981) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1982)   exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1983) }