Radix cross Linux package tools

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

3 Commits   0 Branches   2 Tags
11c606a6 (kx 2023-04-11 01:18:34 +0300    1) 
11c606a6 (kx 2023-04-11 01:18:34 +0300    2) /**********************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300    3) 
11c606a6 (kx 2023-04-11 01:18:34 +0300    4)   Copyright 2019 Andrey V.Kosteltsev
11c606a6 (kx 2023-04-11 01:18:34 +0300    5) 
11c606a6 (kx 2023-04-11 01:18:34 +0300    6)   Licensed under the Radix.pro License, Version 1.0 (the "License");
11c606a6 (kx 2023-04-11 01:18:34 +0300    7)   you may not use this file  except  in compliance with the License.
11c606a6 (kx 2023-04-11 01:18:34 +0300    8)   You may obtain a copy of the License at
11c606a6 (kx 2023-04-11 01:18:34 +0300    9) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   10)      https://radix.pro/licenses/LICENSE-1.0-en_US.txt
11c606a6 (kx 2023-04-11 01:18:34 +0300   11) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   12)   Unless required by applicable law or agreed to in writing, software
11c606a6 (kx 2023-04-11 01:18:34 +0300   13)   distributed under the License is distributed on an "AS IS" BASIS,
11c606a6 (kx 2023-04-11 01:18:34 +0300   14)   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11c606a6 (kx 2023-04-11 01:18:34 +0300   15)   implied.
11c606a6 (kx 2023-04-11 01:18:34 +0300   16) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   17)  **********************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300   18) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   19) #include <config.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   20) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   21) #include <stdlib.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   22) #include <stdio.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   23) #include <sys/types.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   24) #include <stdint.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   25) #include <dirent.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   26) #include <sys/stat.h> /* chmod(2)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   27) #include <sys/file.h> /* flock(2)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   28) #include <fcntl.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   29) #include <linux/limits.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   30) #include <alloca.h>   /* alloca(3)   */
11c606a6 (kx 2023-04-11 01:18:34 +0300   31) #include <string.h>   /* strdup(3)   */
11c606a6 (kx 2023-04-11 01:18:34 +0300   32) #include <strings.h>  /* index(3)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300   33) #include <libgen.h>   /* basename(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300   34) #include <ctype.h>    /* tolower(3)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300   35) #include <errno.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   36) #include <time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   37) #include <sys/time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   38) #include <pwd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   39) #include <grp.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   40) #include <stdarg.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   41) #include <unistd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   42) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   43) #include <math.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   44) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   45) #include <sys/wait.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   46) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   47) #include <sys/resource.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   48) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   49) #include <signal.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   50) #if !defined SIGCHLD && defined SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   51) # define SIGCHLD SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   52) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300   53) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   54) #define _GNU_SOURCE
11c606a6 (kx 2023-04-11 01:18:34 +0300   55) #include <getopt.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   56) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   57) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   58) #include <msglog.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   59) #include <wrapper.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   60) #include <system.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   61) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   62) #include <dlist.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   63) #include <pkglist.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   64) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   65) #define PROGRAM_NAME "make-pkglist"
11c606a6 (kx 2023-04-11 01:18:34 +0300   66) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   67) #include <defs.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   68) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   69) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   70) char *program = PROGRAM_NAME;
11c606a6 (kx 2023-04-11 01:18:34 +0300   71) char *srcdir = NULL, *pkglist_fname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   72)      *tmpdir = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   73) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   74) char *srclist_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   75) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   76) struct srcpkg_fname
11c606a6 (kx 2023-04-11 01:18:34 +0300   77) {
11c606a6 (kx 2023-04-11 01:18:34 +0300   78)   char *name;
11c606a6 (kx 2023-04-11 01:18:34 +0300   79)   int   line;
11c606a6 (kx 2023-04-11 01:18:34 +0300   80) };
11c606a6 (kx 2023-04-11 01:18:34 +0300   81) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   82) struct dlist *srcpkg_fnames = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   83) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   84) int   exit_status = EXIT_SUCCESS; /* errors counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300   85) char *selfdir     = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   86) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   87) int __done = 0, __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300   88) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   89) enum _output_format {
11c606a6 (kx 2023-04-11 01:18:34 +0300   90)   OFMT_LIST = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300   91)   OFMT_JSON,
11c606a6 (kx 2023-04-11 01:18:34 +0300   92) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   93)   OFMT_UNKNOWN
11c606a6 (kx 2023-04-11 01:18:34 +0300   94) } output_format = OFMT_LIST;
11c606a6 (kx 2023-04-11 01:18:34 +0300   95) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   96) enum _tree_format tree_format = TFMT_BIN;
11c606a6 (kx 2023-04-11 01:18:34 +0300   97) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   98) enum _input_type {
11c606a6 (kx 2023-04-11 01:18:34 +0300   99)   IFMT_PKG = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300  100)   IFMT_LOG,
11c606a6 (kx 2023-04-11 01:18:34 +0300  101) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  102)   IFMT_UNKNOWN
11c606a6 (kx 2023-04-11 01:18:34 +0300  103) } input_format = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  104) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  105) enum _priority priority = REQUIRED;
11c606a6 (kx 2023-04-11 01:18:34 +0300  106) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  107) /***************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  108)   Exclude declarations:
11c606a6 (kx 2023-04-11 01:18:34 +0300  109)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  110) static struct dlist *exclude = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  111) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  112) static void add_exclude( const char *name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  113) static void free_exclude( void );
11c606a6 (kx 2023-04-11 01:18:34 +0300  114) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  115) static void read_exclude_list( const char *optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  116) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  117)   End of exclude declarstions.
11c606a6 (kx 2023-04-11 01:18:34 +0300  118)  ***************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  119) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  120) /***************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  121)   Source file names functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  122)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  123) static struct srcpkg_fname *srcpkg_fname_alloc( const char *name, int line )
11c606a6 (kx 2023-04-11 01:18:34 +0300  124) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  125)   struct srcpkg_fname *fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  126) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  127)   fname = (struct srcpkg_fname *)malloc( sizeof( struct srcpkg_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  128)   if( !fname ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  129) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  130)   fname->name = xstrdup( name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  131)   fname->line = line;
11c606a6 (kx 2023-04-11 01:18:34 +0300  132) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  133)   return fname;
11c606a6 (kx 2023-04-11 01:18:34 +0300  134) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  135) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  136) static void srcpkg_fname_free( struct srcpkg_fname *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  137) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  138)   if( fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  139)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  140)     if( fname->name ) { free( fname->name ); fname->name    = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  141)     free( fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  142)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  143) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  144) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  145) static void __srcpkg_fname_free_func( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300  146) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  147)   struct srcpkg_fname *fname = (struct srcpkg_fname *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300  148)   if( fname ) { srcpkg_fname_free( fname ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  149) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  150) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  151) static void free_srcpkg_fnames( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  152) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  153)   if( srcpkg_fnames ) { dlist_free( srcpkg_fnames, __srcpkg_fname_free_func ); srcpkg_fnames = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  154) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  155) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  156) static void add_srcpkg_fname( struct srcpkg_fname *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  157) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  158)   if( fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  159)     srcpkg_fnames = dlist_append( srcpkg_fnames, (void *)fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  160) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  161) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  162)   End of source file names functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300  163)  ***************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  164) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  165) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  166) void free_resources()
11c606a6 (kx 2023-04-11 01:18:34 +0300  167) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  168)   if( selfdir )        { free( selfdir );        selfdir        = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  169)   if( srcdir )         { free( srcdir );         srcdir         = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  170)   if( srclist_fname )  { free( srclist_fname );  srclist_fname  = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  171)   if( pkglist_fname )  { free( pkglist_fname );  pkglist_fname  = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  172) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  173)   free_exclude();
11c606a6 (kx 2023-04-11 01:18:34 +0300  174) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  175)   free_tarballs();
11c606a6 (kx 2023-04-11 01:18:34 +0300  176)   free_packages();
11c606a6 (kx 2023-04-11 01:18:34 +0300  177)   free_srcpkg_fnames();
11c606a6 (kx 2023-04-11 01:18:34 +0300  178)   free_srcpkgs();
11c606a6 (kx 2023-04-11 01:18:34 +0300  179) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  180) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  181) void usage()
11c606a6 (kx 2023-04-11 01:18:34 +0300  182) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  183)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  184) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  185)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  186)   fprintf( stdout, "Usage: %s [options] <pkglist>\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  187)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  188)   fprintf( stdout, "Create Packages List in the installation order from set of PKGLOGs\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  189)   fprintf( stdout, "or  set of PACKAGEs placed in the source directory.  If the source\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  190)   fprintf( stdout, "directory is not defined then directory of <pkglist>  will be used\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  191)   fprintf( stdout, "as source PACKAGE directory.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  192)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  193)   fprintf( stdout, "Options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  194)   fprintf( stdout, "  -h,--help                     Display this information.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  195)   fprintf( stdout, "  -v,--version                  Display the version of %s utility.\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  196)   fprintf( stdout, "  -s,--source=<DIR|pkg|log>     Setup Database packages directory or directory\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  197)   fprintf( stdout, "                                where set of PACKAGEs is placed.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  198)   fprintf( stdout, "                                If the source argument is a PACKAGE or PKGLOG\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  199)   fprintf( stdout, "                                file, then the source directory will be represented\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  200)   fprintf( stdout, "                                as the base directory of the source file excluding\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  201)   fprintf( stdout, "                                the group directory if defined.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  202)   fprintf( stdout, "  -F,--files-from=<FILE>        Get file names of PACKAGEs or PKGLOGs from FILE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  203)   fprintf( stdout, "                                Each line of the FILE must contain a path to the\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  204)   fprintf( stdout, "                                PACKAGE or PKGLOG file relative to the directory\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  205)   fprintf( stdout, "                                specified by option --source.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  206)   fprintf( stdout, "  -e,--exclude=<pname|plist>    Ignore package with <pname> or the comma\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  207)   fprintf( stdout, "                                separated list of package names.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  208)   fprintf( stdout, "  -i,--iformat=<pkg|log>        Input format: PACKAGEs or PKGLOGs.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  209)   fprintf( stdout, "  -o,--oformat=<list|json>      Output format: LIST or JSON.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  210) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  211)   fprintf( stdout, "  -t,--tformat=<dag|bin>        Tree format: DAG or BIN (default BIN).\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  212) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  213)   fprintf( stdout, "  -m,--minimize                 Create .min.json files. Applicable\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  214)   fprintf( stdout, "                                for JSON output format.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  215) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  216)   fprintf( stdout, "  -p,--prioriy=<PRIORITY>       Default install priority: REQ|REC|OPT|SKP.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  217)   fprintf( stdout, "  -w,--hardware=<HARDWARE>      Hardware Name used for JSON output format.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  218)   fprintf( stdout, "  -H,--htmlroot=<HTMLROOT>      Optional Requires tree HTMLROOT name used\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  219)   fprintf( stdout, "                                for JSON output format.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  220) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  221)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  222)   fprintf( stdout, "Parameter:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  223)   fprintf( stdout, "  <pkglist>                     Output PKGLIST file name or a target\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  224)   fprintf( stdout, "                                directory to save output PKGLIST.\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  225)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  226)   fprintf( stdout, "If HTMLROOT is not defined by option --htmlroot then HTMLROOT will be set\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  227)   fprintf( stdout, "as basename of target <pkglist> file in lower case without extension.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  228)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  229) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  230)   exit( EXIT_FAILURE );
11c606a6 (kx 2023-04-11 01:18:34 +0300  231) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  232) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  233) void to_lowercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  234) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  235)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  236)   while( p && *p ) { int c = *p; *p = tolower( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  237) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  238) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  239) void to_uppercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  240) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  241)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  242)   while( p && *p ) { int c = *p; *p = toupper( c ); ++p; }
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) void version()
11c606a6 (kx 2023-04-11 01:18:34 +0300  246) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  247)   char *upper = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  248) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  249)   upper = (char *)alloca( strlen( program ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  250) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  251)   strcpy( (char *)upper, (const char *)program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  252)   to_uppercase( upper );
11c606a6 (kx 2023-04-11 01:18:34 +0300  253) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  254)   fprintf( stdout, "%s (%s) %s\n", program, upper, PROGRAM_VERSION );
11c606a6 (kx 2023-04-11 01:18:34 +0300  255) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  256)   fprintf( stdout, "Copyright (C) 2019 Andrey V.Kosteltsev.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  257)   fprintf( stdout, "This is free software.   There is NO warranty; not even\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  258)   fprintf( stdout, "for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  259)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  260) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  261)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  262)   exit( EXIT_SUCCESS );
11c606a6 (kx 2023-04-11 01:18:34 +0300  263) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  264) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  265) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  266) static void remove_trailing_slash( char *dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  267) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  268)   char *s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  269) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  270)   if( !dir || dir[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  271) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  272)   s = dir + strlen( dir ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  273)   while( *s == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  274)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  275)     *s = '\0'; --s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  276)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  277) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  278) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  279) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  280) static int _mkdir_p( const char *dir, const mode_t mode )
11c606a6 (kx 2023-04-11 01:18:34 +0300  281) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  282)   char  *buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  283)   char  *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  284)   struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  285) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  286)   if( !dir ) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  287) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  288)   buf = (char *)alloca( strlen( dir ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  289)   strcpy( buf, dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  290) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  291)   remove_trailing_slash( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  292) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  293)   /* check if path exists and is a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  294)   if( stat( buf, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  295)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  296)     if( S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  297)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  298)       return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  299)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  300)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  301) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  302)   /* mkdir -p */
11c606a6 (kx 2023-04-11 01:18:34 +0300  303)   for( p = buf + 1; *p; ++p )
11c606a6 (kx 2023-04-11 01:18:34 +0300  304)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  305)     if( *p == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  306)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  307)       *p = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  308)       /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  309)       if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  310)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  311)         /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  312)         if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  313)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  314)           return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  315)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  316)       } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  317)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  318)         /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  319)         return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  320)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  321)       *p = '/';
11c606a6 (kx 2023-04-11 01:18:34 +0300  322)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  323)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  324) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  325)   /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  326)   if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  327)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  328)     /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  329)     if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  330)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  331)       return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  332)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  333)   } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  334)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  335)     /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  336)     return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  337)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  338) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  339)   return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  340) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  341) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  342) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  343) static void _rm_tmpdir( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300  344) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  345)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300  346)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300  347)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  348) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  349)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  350)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300  351) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  352)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  353)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  354)     return; /* stat returns error code; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  355)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  356) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  357)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  358)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  359)     return; /* dirpath is not a directory */
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)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  363)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  364)     return; /* Cannot open direcroty; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  365)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  366) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  367)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  368) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  369)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300  370)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  371) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  372)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  373)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300  374) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  375)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300  376)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  377)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  378)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  379)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  380) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  381)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  382)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  383)       if( S_ISDIR(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  384)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  385)         /* recursively remove a nested directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  386)         _rm_tmpdir( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  387)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  388)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  389)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  390)         /* remove a file object */
11c606a6 (kx 2023-04-11 01:18:34 +0300  391)         (void)unlink( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  392)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  393)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  394)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300  395) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  396)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  397) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  398)   /* remove the devastated directory and close the object of this directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  399)   (void)rmdir( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  400) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  401)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  402) }
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) static char *_mk_tmpdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  406) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  407)   char   *buf = NULL, *p, *tmp = "/tmp";
11c606a6 (kx 2023-04-11 01:18:34 +0300  408)   size_t  len = 0, size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  409) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  410)   (void)umask( S_IWGRP | S_IWOTH ); /* octal 022 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  411) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  412)   /* Get preferred directory for tmp files */
11c606a6 (kx 2023-04-11 01:18:34 +0300  413)   if( (p = getenv( "TMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  414)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  415)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  416)   else if( (p = getenv( "TEMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  417)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  418)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  419) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  420)   size = strlen( tmp ) + strlen( DISTRO_NAME ) + strlen( program ) + 12;
11c606a6 (kx 2023-04-11 01:18:34 +0300  421) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  422)   buf = (char *)malloc( size );
11c606a6 (kx 2023-04-11 01:18:34 +0300  423)   if( !buf ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  424) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  425)   len = snprintf( buf, size, (const char *)"%s/%s/%s-%.7u", tmp, DISTRO_NAME, program, getpid() );
11c606a6 (kx 2023-04-11 01:18:34 +0300  426)   if( len == 0 || len == size - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  427)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  428)     free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  429)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  430) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  431)   _rm_tmpdir( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  432) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  433)   if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  434)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  435)     return buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  436)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  437) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  438)   free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  439) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  440) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  441) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  442) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  443) void fatal_error_actions( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  444) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  445)   logmsg( errlog, MSG_NOTICE, "Free resources on FATAL error..." );
11c606a6 (kx 2023-04-11 01:18:34 +0300  446)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  447)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  448) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  449) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  450) void sigint( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  451) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  452)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  453) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  454)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  455)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  456) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  457) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  458) void sigchld( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  459) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  460)   pid_t  pid = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  461)   int    status;
11c606a6 (kx 2023-04-11 01:18:34 +0300  462) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  463)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  464) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  465)   while( (pid = waitpid( -1, &status, WNOHANG )) > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  466)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  467)     ; /* One of children with 'pid' is terminated */
11c606a6 (kx 2023-04-11 01:18:34 +0300  468) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  469)     if( WIFEXITED( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  470)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  471)       if( (int) WEXITSTATUS (status) > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  472)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  473)         ++exit_status; /* printf( "Child %d returned non zero status: %d\n", pid, (int)WEXITSTATUS (status) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  474)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  475)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  476)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  477)         ; /* printf( "Child %d terminated with status: %d\n", pid, (int)WEXITSTATUS (status) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  478)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  479)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  480)     else if( WIFSIGNALED( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  481)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  482)       ++exit_status; /* printf( "Child %d terminated on signal: %d\n", pid,  WTERMSIG( status ) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  483)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  484)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  485)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  486)       ++exit_status; /* printf( "Child %d terminated on unknown reason\n", pid ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  487)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  488) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  489)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  490) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  491)   if( pid == -1 && errno == ECHILD )
11c606a6 (kx 2023-04-11 01:18:34 +0300  492)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  493)     /* No child processes: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  494)     __done = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  495)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  496)   return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  497) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  498) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  499) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  500) static void set_signal_handlers()
11c606a6 (kx 2023-04-11 01:18:34 +0300  501) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  502)   struct sigaction  sa;
11c606a6 (kx 2023-04-11 01:18:34 +0300  503)   sigset_t          set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  504) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  505)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  506)   sa.sa_handler = sigint;          /* TERM, INT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  507)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  508)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  509)   sigaddset( &set, SIGTERM );
11c606a6 (kx 2023-04-11 01:18:34 +0300  510)   sigaddset( &set, SIGINT );
11c606a6 (kx 2023-04-11 01:18:34 +0300  511)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  512)   sigaction( SIGTERM, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  513)   sigaction( SIGINT, &sa,  NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  514) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  515)   /* System V fork+wait does not work if SIGCHLD is ignored */
11c606a6 (kx 2023-04-11 01:18:34 +0300  516)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  517)   sa.sa_handler = sigchld;         /* CHLD */
11c606a6 (kx 2023-04-11 01:18:34 +0300  518)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  519)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  520)   sigaddset( &set, SIGCHLD );
11c606a6 (kx 2023-04-11 01:18:34 +0300  521)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  522)   sigaction( SIGCHLD, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  523) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  524)   memset( &sa, 0, sizeof( sa ) );  /* ignore SIGPIPE */
11c606a6 (kx 2023-04-11 01:18:34 +0300  525)   sa.sa_handler = SIG_IGN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  526)   sa.sa_flags = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  527)   sigaction( SIGPIPE, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  528) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  529) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  530) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  531) static enum _input_type check_input_file( char *uncompress, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  532) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  533)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  534)   size_t pkglog_size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  535)   unsigned char buf[8];
11c606a6 (kx 2023-04-11 01:18:34 +0300  536)   int rc, fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300  537) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  538)   /* SIGNATURES: https://www.garykessler.net/library/file_sigs.html */
11c606a6 (kx 2023-04-11 01:18:34 +0300  539) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  540)   if( uncompress )
11c606a6 (kx 2023-04-11 01:18:34 +0300  541)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  542)     *uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  543)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  544) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  545)   if( stat( fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  546)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  547)     FATAL_ERROR( "Cannot access %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  548)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  549) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  550)   pkglog_size = st.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300  551) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  552)   if( (fd = open( fname, O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  553)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  554)     FATAL_ERROR( "Cannot open %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  555)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  556) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  557)   rc = (int)read( fd, (void *)&buf[0], 7 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  558)   if( rc != 7 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  559)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  560)     close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  561)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  562)   buf[7] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  563) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  564)   /* TEXT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  565)   if( !strncmp( (const char *)&buf[0], "PACKAGE", 7 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  566)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  567)     close( fd ); return IFMT_LOG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  568)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  569) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  570)   /* GZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  571)   if( buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x08 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  572)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  573)     if( uncompress ) { *uncompress = 'x'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  574)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  575)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  576) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  577)   /* BZ2 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  578)   if( buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  579)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  580)     if( uncompress ) { *uncompress = 'j'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  581)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  582)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  583) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  584)   /* XZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  585)   if( buf[0] == 0xFD && buf[1] == 0x37 && buf[2] == 0x7A &&
11c606a6 (kx 2023-04-11 01:18:34 +0300  586)       buf[3] == 0x58 && buf[4] == 0x5A && buf[5] == 0x00   )
11c606a6 (kx 2023-04-11 01:18:34 +0300  587)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  588)     if( uncompress ) { *uncompress = 'J'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  589)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  590)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  591) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  592)   if( pkglog_size > 262 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  593)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  594)     if( lseek( fd, 257, SEEK_SET ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  595)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  596)       FATAL_ERROR( "Cannot check signature of %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  597)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  598)     rc = (int)read( fd, &buf[0], 5 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  599)     if( rc != 5 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  600)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  601)       FATAL_ERROR( "Cannot read signature of %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  602)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  603)     /* TAR */
11c606a6 (kx 2023-04-11 01:18:34 +0300  604)     if( buf[0] == 0x75 && buf[1] == 0x73 && buf[2] == 0x74 && buf[3] == 0x61 && buf[4] == 0x72 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  605)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  606)       close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  607)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  608)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  609) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  610)   close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  611) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  612) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  613) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  614) void get_args( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300  615) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  616)   const char* short_options = "hvme:s:F:o:i:t:p:w:H:";
11c606a6 (kx 2023-04-11 01:18:34 +0300  617) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  618)   const struct option long_options[] =
11c606a6 (kx 2023-04-11 01:18:34 +0300  619)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  620)     { "help",        no_argument,       NULL, 'h' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  621)     { "version",     no_argument,       NULL, 'v' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  622)     { "minimize",    no_argument,       NULL, 'm' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  623)     { "exclude",     required_argument, NULL, 'e' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  624)     { "source",      required_argument, NULL, 's' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  625)     { "files-from",  required_argument, NULL, 'F' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  626)     { "oformat",     required_argument, NULL, 'o' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  627)     { "iformat",     required_argument, NULL, 'i' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  628)     { "tformat",     required_argument, NULL, 't' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  629)     { "priority",    required_argument, NULL, 'p' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  630)     { "hardware",    required_argument, NULL, 'w' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  631)     { "htmlroot",    required_argument, NULL, 'H' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  632)     { NULL,          0,                 NULL,  0  }
11c606a6 (kx 2023-04-11 01:18:34 +0300  633)   };
11c606a6 (kx 2023-04-11 01:18:34 +0300  634) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  635)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  636)   int option_index = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  637) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  638)   while( (ret = getopt_long( argc, argv, short_options, long_options, &option_index )) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  639)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  640)     switch( ret )
11c606a6 (kx 2023-04-11 01:18:34 +0300  641)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  642)       case 'h':
11c606a6 (kx 2023-04-11 01:18:34 +0300  643)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  644)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  645)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  646)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  647)       case 'v':
11c606a6 (kx 2023-04-11 01:18:34 +0300  648)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  649)         version();
11c606a6 (kx 2023-04-11 01:18:34 +0300  650)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  651)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  652)       case 'm':
11c606a6 (kx 2023-04-11 01:18:34 +0300  653)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  654)         minimize = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  655)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  656)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  657) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  658)       case 'e':
11c606a6 (kx 2023-04-11 01:18:34 +0300  659)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  660)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  661)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  662)           read_exclude_list( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  663)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  664)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  665)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  666)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  667)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  668)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  669) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  670)       case 's':
11c606a6 (kx 2023-04-11 01:18:34 +0300  671)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  672)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  673)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  674)           srcdir = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  675)           remove_trailing_slash( srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  676)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  677)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  678)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  679)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  680)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  681)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  682)       case 'F':
11c606a6 (kx 2023-04-11 01:18:34 +0300  683)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  684)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  685)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  686)           srclist_fname = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  687)           remove_trailing_slash( srclist_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  688)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  689)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  690)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  691)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  692)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  693)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  694)       case 'o':
11c606a6 (kx 2023-04-11 01:18:34 +0300  695)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  696)         char *fmt = (char *)alloca( strlen( optarg ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  697) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  698)         strcpy( (char *)fmt, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  699)         to_lowercase( fmt );
11c606a6 (kx 2023-04-11 01:18:34 +0300  700) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  701)         if(      !strcmp( fmt, "list" ) ) { output_format = OFMT_LIST; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  702)         else if( !strcmp( fmt, "json" ) ) { output_format = OFMT_JSON; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  703)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  704)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  705)           ERROR( "Invalid output format: %s", fmt );
11c606a6 (kx 2023-04-11 01:18:34 +0300  706)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  707)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  708)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  709)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  710)       case 'i':
11c606a6 (kx 2023-04-11 01:18:34 +0300  711)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  712)         char *fmt = (char *)alloca( strlen( optarg ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  713) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  714)         strcpy( (char *)fmt, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  715)         to_lowercase( fmt );
11c606a6 (kx 2023-04-11 01:18:34 +0300  716) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  717)         if(      !strcmp( fmt, "pkg" ) ) { input_format = IFMT_PKG; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  718)         else if( !strcmp( fmt, "log" ) ) { input_format = IFMT_LOG; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  719)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  720)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  721)           ERROR( "Invalid input format: %s", fmt );
11c606a6 (kx 2023-04-11 01:18:34 +0300  722)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  723)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  724)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  725)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  726)       case 't':
11c606a6 (kx 2023-04-11 01:18:34 +0300  727)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  728)         char *fmt = (char *)alloca( strlen( optarg ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  729) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  730)         strcpy( (char *)fmt, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  731)         to_lowercase( fmt );
11c606a6 (kx 2023-04-11 01:18:34 +0300  732) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  733)         if(      !strcmp( fmt, "bin" ) ) { tree_format = TFMT_BIN; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  734)         else if( !strcmp( fmt, "dag" ) ) { tree_format = TFMT_DAG; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  735)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  736)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  737)           ERROR( "Invalid tree format: %s", fmt );
11c606a6 (kx 2023-04-11 01:18:34 +0300  738)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  739)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  740)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  741)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  742)       case 'p':
11c606a6 (kx 2023-04-11 01:18:34 +0300  743)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  744)         char *p = (char *)alloca( strlen( optarg ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  745) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  746)         strcpy( (char *)p, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  747)         to_lowercase( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  748) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  749)         if(      !strcmp( p, "required" )    || !strcmp( p, "req" ) ) { priority = REQUIRED;    }
11c606a6 (kx 2023-04-11 01:18:34 +0300  750)         else if( !strcmp( p, "recommended" ) || !strcmp( p, "rec" ) ) { priority = RECOMMENDED; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  751)         else if( !strcmp( p, "optional" )    || !strcmp( p, "opt" ) ) { priority = OPTIONAL;    }
11c606a6 (kx 2023-04-11 01:18:34 +0300  752)         else if( !strcmp( p, "skip" )        || !strcmp( p, "skp" ) ) { priority = SKIP;        }
11c606a6 (kx 2023-04-11 01:18:34 +0300  753)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  754)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  755)           ERROR( "Invalid default install priority: %s", p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  756)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  757)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  758)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  759)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  760)       case 'w':
11c606a6 (kx 2023-04-11 01:18:34 +0300  761)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  762)         char *hw = (char *)alloca( strlen( optarg ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  763) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  764)         strcpy( (char *)hw, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  765)         to_lowercase( hw );
11c606a6 (kx 2023-04-11 01:18:34 +0300  766) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  767)         hardware = xstrdup( (const char *)hw );
11c606a6 (kx 2023-04-11 01:18:34 +0300  768)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  769)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  770)       case 'H':
11c606a6 (kx 2023-04-11 01:18:34 +0300  771)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  772)         char *root = (char *)alloca( strlen( optarg ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  773) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  774)         strcpy( (char *)root, (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  775)         to_lowercase( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  776) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  777)         htmlroot = xstrdup( (const char *)root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  778)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  779)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  780) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  781)       case '?': default:
11c606a6 (kx 2023-04-11 01:18:34 +0300  782)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  783)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  784)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  785)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  786)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  787)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  788) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  789) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  790)   /* last command line argument is the output PKGLIST file */
11c606a6 (kx 2023-04-11 01:18:34 +0300  791)   if( optind < argc )
11c606a6 (kx 2023-04-11 01:18:34 +0300  792)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  793)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  794)     char   *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  795)     size_t  hrl = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  796) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  797)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  798) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  799)     if( htmlroot ) { hrl = strlen( htmlroot ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  800) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  801)     buf = (char *)malloc( strlen( (const char *)argv[optind] ) + hrl + 10 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  802)     if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300  803)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  804)       FATAL_ERROR( "Cannot allocate memory" );
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)     (void)strcpy( buf, (const char *)argv[optind++] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  808)     remove_trailing_slash( (char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  809) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  810)     stat( (const char *)&buf[0], &st ); /* Do not check return status */
11c606a6 (kx 2023-04-11 01:18:34 +0300  811) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  812)     if( S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  813)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  814)       if( ! srcdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  815)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  816)         srcdir = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  817)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  818)       /* Add .pkglist or .json to the output dir name: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  819)       if( htmlroot )
11c606a6 (kx 2023-04-11 01:18:34 +0300  820)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  821)         (void)strcat( buf, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  822)         (void)strcat( buf, htmlroot );
11c606a6 (kx 2023-04-11 01:18:34 +0300  823) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  824)         if( output_format == OFMT_LIST )
11c606a6 (kx 2023-04-11 01:18:34 +0300  825)           (void)strcat( buf, ".pkglist" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  826)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  827)           (void)strcat( buf, ".json" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  828)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  829)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  830)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  831)         if( output_format == OFMT_LIST )
11c606a6 (kx 2023-04-11 01:18:34 +0300  832)           (void)strcat( buf, "/.pkglist" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  833)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  834)           (void)strcat( buf, "/.json" );
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)     if( !hardware )
11c606a6 (kx 2023-04-11 01:18:34 +0300  839)       hardware = xstrdup( "unknown" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  840) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  841)     /* Check output directory; set srcdir and htmlroot if needed */
11c606a6 (kx 2023-04-11 01:18:34 +0300  842)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  843)       char   *d, *f, *fname;
11c606a6 (kx 2023-04-11 01:18:34 +0300  844)       size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  845) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  846)       if( !rindex( (const char *)&buf[0], '/' ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  847)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  848)         d = ".";
11c606a6 (kx 2023-04-11 01:18:34 +0300  849)         f = (char *)&buf[0];
11c606a6 (kx 2023-04-11 01:18:34 +0300  850)         len = strlen( f ) + 3;
11c606a6 (kx 2023-04-11 01:18:34 +0300  851)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  852)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  853)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  854)         f = basename( (char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  855)         d =  dirname( (char *)&buf[0] ); /* dirname() cuts the filename from buf[] */
11c606a6 (kx 2023-04-11 01:18:34 +0300  856)         len = strlen( d ) + strlen( f ) + 2;
11c606a6 (kx 2023-04-11 01:18:34 +0300  857)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  858) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  859)       fname = (char *)alloca( len );
11c606a6 (kx 2023-04-11 01:18:34 +0300  860)       (void)sprintf( fname, "%s/%s", d, f );
11c606a6 (kx 2023-04-11 01:18:34 +0300  861) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  862)       if( stat( (const char *)d, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  863)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  864)         FATAL_ERROR( "Cannot access output '%s' directory: %s", d, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  865)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  866) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  867)       pkglist_fname = xstrdup( (const char *)fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  868)       if( pkglist_fname == NULL ) { usage(); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  869) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  870)       if( !srcdir ) { srcdir = xstrdup( (const char *)d ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  871) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  872)       if( !htmlroot )
11c606a6 (kx 2023-04-11 01:18:34 +0300  873)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  874)         char *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  875)         if( (p = rindex( (const char *)f, '.' )) && p != f )
11c606a6 (kx 2023-04-11 01:18:34 +0300  876)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  877)           *p = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  878)           to_lowercase( f );
11c606a6 (kx 2023-04-11 01:18:34 +0300  879)           htmlroot = xstrdup( (const char *)f );
11c606a6 (kx 2023-04-11 01:18:34 +0300  880)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  881)         else if( *f != '.' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  882)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  883)           to_lowercase( f );
11c606a6 (kx 2023-04-11 01:18:34 +0300  884)           htmlroot = xstrdup( (const char *)f );
11c606a6 (kx 2023-04-11 01:18:34 +0300  885)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  886)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  887)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  888)           htmlroot = xstrdup( (const char *)hardware );
11c606a6 (kx 2023-04-11 01:18:34 +0300  889)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  890)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  891)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  892) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  893)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  894)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  895)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  896)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  897)     usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  898)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  899) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  900) 
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)   Exclude functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  904)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  905) static void add_exclude( const char *name )
11c606a6 (kx 2023-04-11 01:18:34 +0300  906) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  907)   exclude = dlist_append( exclude, (void *)xstrdup( name ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  908) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  909) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  910) static void __free_exclude( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300  911) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  912)   if( data ) { free( data ); }
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) static void free_exclude( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  916) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  917)   if( exclude ) { dlist_free( exclude, __free_exclude ); exclude = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  918) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  919) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  920) static int __compare_exclude( const void *a, const void *b )
11c606a6 (kx 2023-04-11 01:18:34 +0300  921) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  922)   return strncmp( (const char *)a, (const char *)b, (size_t)strlen((const char *)b) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  923) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  924) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  925) static const char *find_exclude( const char *name )
11c606a6 (kx 2023-04-11 01:18:34 +0300  926) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  927)   struct dlist *node = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  928) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  929)   if( !exclude || !name ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  930) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  931)   node = dlist_find_data( exclude, __compare_exclude, (const void *)name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  932)   if( node )
11c606a6 (kx 2023-04-11 01:18:34 +0300  933)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  934)     return (const char *)node->data;
11c606a6 (kx 2023-04-11 01:18:34 +0300  935)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  936) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  937)   return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  938) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  939) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  940) static void read_exclude_list( const char *optarg )
11c606a6 (kx 2023-04-11 01:18:34 +0300  941) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  942)   char *name = NULL, *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  943) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  944)   name = p = (char *)optarg;
11c606a6 (kx 2023-04-11 01:18:34 +0300  945) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  946)   if( !p || *p == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  947) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  948)   while( *p == ',' ) { *p = '\0'; ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  949)   name = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  950) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  951)   while( p && *p != '\0' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  952)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  953)     ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  954) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  955)     if( *p == ',' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  956)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  957)       while( *p == ',' ) { *p = '\0'; ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  958)       if( name && *name != '\0' ) { add_exclude( (const char *)name ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  959)       name = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  960)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  961) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  962)     if( *p == '\0' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  963)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  964)       if( name && *name != '\0' ) { add_exclude( (const char *)name ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  965)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  966)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  967) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  968) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  969)   End of exclude functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300  970)  ***************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  971) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  972) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  973) /***************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  974)   Extract functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  975)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  976) static void _extract_pkglog( const char *group, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  977) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  978)   enum _input_type  type = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  979)   char              uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  980) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  981)   type = check_input_file( &uncompress, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  982) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  983)   if( type == IFMT_PKG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  984)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  985)     int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  986)     char *tmp= NULL, *cmd = NULL, *tgz = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  987) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  988)     tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  989)     if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  990)     bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  991) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  992)     if( group ) { (void)sprintf( &tmp[0], "%s/%s", tmpdir, group ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  993)     else        { (void)sprintf( &tmp[0], "%s", tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  994) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  995)     if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  996)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  997)       ERROR( "Cannot save PKGLOG from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  998)       free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  999)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1000)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1001) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1002)     cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1003)     if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1004)     bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1005) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1006)     len = snprintf( &cmd[0], PATH_MAX, "%s/pkglog -d %s %s > /dev/null 2>&1", selfdir, tmp, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1007)     if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1008)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1009)       FATAL_ERROR( "Cannot get PKGLOG from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1010)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1011)     (void)sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1012)     ++__child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1013) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1014)     tgz = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1015)     if( !tgz ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1016)     bzero( (void *)tgz, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1017)     (void)sprintf( &tgz[0], "%s/%s", group, basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1018)     add_tarball( (char *)&tgz[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1019) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1020)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1021)     free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1022)     free( tgz );
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) static void _search_packages( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1027) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1028)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1029)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1030)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1031) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1032)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1033)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1034) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1035)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1036)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1037)     FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1038)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1039) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1040)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1041)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1042)     FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1043)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1044) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1045)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1046)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1047)     FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1048)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1049) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1050)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1051) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1052)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1053)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1054)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1055)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1056) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1057)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1058)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1059) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1060)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1061)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1062)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1063) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1064)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1065)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1066)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1067)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1068)         _extract_pkglog( grp, (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1069)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1070)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1071)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1072)         _search_packages( (const char *)path, (const char *)entry->d_name );
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)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1076)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1077) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1078)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1079) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1080) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1081) /**************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1082)   extract_pkglogs() - returns number of extracted PKGLOGS
11c606a6 (kx 2023-04-11 01:18:34 +0300 1083)                       or 0 if no packages found in the srcdir.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1084)                       The exit_status has been set.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1085)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1086) int extract_pkglogs( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1087) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1088)   int ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1089) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1090)   __done = 0; __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1091) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1092)   _search_packages( (const char *)srcdir, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1093) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1094)   if( __child > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1095)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1096)     while( !__done ) usleep( 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1097)     ret = __child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1098)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1099) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1100)   __done = 0; __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1101) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1102)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1103) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1104) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1105)   End of Extract functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1106)  ***************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1107) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1108) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1109) /***************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1110)   Copy functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1111)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1112) static void _copy_pkglog( const char *group, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1113) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1114)   enum _input_type  type = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1115)   char              uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1116) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1117)   type = check_input_file( &uncompress, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1118) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1119)   if( type == IFMT_LOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1120)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1121)     int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1122)     char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1123) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1124)     tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1125)     if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1126)     bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1127) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1128)     if( group ) { (void)sprintf( &tmp[0], "%s/%s", tmpdir, group ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1129)     else        { (void)sprintf( &tmp[0], "%s", tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1130) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1131)     if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1132)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1133)       ERROR( "Cannot copy '%s' PKGLOG file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1134)       free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1135)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1136)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1137) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1138)     cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1139)     if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1140)     bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1141) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1142)     len = snprintf( &cmd[0], PATH_MAX, "cp %s %s/ > /dev/null 2>&1", fname, tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1143)     if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1144)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1145)       FATAL_ERROR( "Cannot copy %s PKGLOG file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1146)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1147)     (void)sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1148)     ++__child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1149) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1150)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1151)     free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1152)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1153) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1154) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1155) static void _search_pkglogs( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1156) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1157)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1158)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1159)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1160) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1161)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1162)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1163) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1164)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1165)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1166)     FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1167)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1168) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1169)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1170)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1171)     FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1172)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1173) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1174)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1175)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1176)     FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
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)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1180) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1181)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1182)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1183)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1184)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1185) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1186)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1187)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1188) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1189)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1190)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1191)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1192) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1193)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1194)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1195)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1196)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1197)         _copy_pkglog( grp, (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1198)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1199)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1200)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1201)         _search_pkglogs( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1202)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1203)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1204)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1205)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1206) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1207)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1208) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1209) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1210) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1211)   copy_pkglogs() - returns number of copied PKGLOGS
11c606a6 (kx 2023-04-11 01:18:34 +0300 1212)                    or 0 if no packages found in the srcdir.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1213)                    The exit_status has been set.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1214)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1215) int copy_pkglogs( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1216) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1217)   int ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1218) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1219)   __done = 0; __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1220) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1221)   _search_pkglogs( (const char *)srcdir, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1222) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1223)   if( __child > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1224)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1225)     while( !__done ) usleep( 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1226)     ret = __child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1227)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1228) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1229)   __done = 0; __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1230) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1231)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1232) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1233) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1234)   Enf of Copy functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1235)  ***************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 1236) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1237) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1238) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1239)   Remove leading spaces and take non-space characters only:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1240)   (Especialy for pkginfo lines)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1241)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1242) static char *skip_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1243) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1244)   char *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1245) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1246)   if( !s || *s == '\0' ) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1247) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1248)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1249) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1250)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1251)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1252) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1253)   if( *p == '\0' ) return (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1254) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1255)   return( xstrdup( (const char *)p ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1256) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1257) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1258) /*******************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1259)   remove spaces at end of line:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1260)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1261) static void skip_eol_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1262) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1263)   char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1264) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1265)   if( !s || *s == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1266) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1267)   p = s + strlen( s ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1268)   while( isspace( *p ) ) { *p-- = '\0'; }
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 size_t read_usize( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1272) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1273)   size_t  size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1274)   size_t  mult = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1275)   double  sz = 0.0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1276) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1277)   char    suffix;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1278)   char   *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1279) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1280)   if( !s || *s == '\0' ) return size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1281) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1282)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1283) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1284)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1285)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1286) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1287)   if( *p == '\0' ) return size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1288) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1289)   --q;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1290)   suffix = *q;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1291)   switch( suffix )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1292)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1293)     /* by default size calculates in KiB - 1024 Bytes (du -s -h .) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1294)     case 'G':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1295)     case 'g':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1296)       mult = 1024 * 1024;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1297)       *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1298)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1299)     case 'M':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1300)     case 'm':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1301)       mult = 1024;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1302)       *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1303)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1304)     case 'K':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1305)     case 'k':
11c606a6 (kx 2023-04-11 01:18:34 +0300 1306)       *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1307)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1308)     default:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1309)       break;
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)   if( sscanf( p, "%lg", &sz ) != 1 ) return size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1313) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1314)   return (size_t)round( sz * (double)mult );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1315) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1316) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1317) static int read_total_files( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1318) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1319)   int   n = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1320)   char *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1321) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1322)   if( !s || *s == '\0' ) return n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1323) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1324)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1325) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1326)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1327)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1328) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1329)   if( *p == '\0' ) return n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1330) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1331)   if( sscanf( p, "%u", &n ) != 1 ) return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1332) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1333)   return n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1334) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1335) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1336) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1337) static struct pkg *input_package( const char *pkginfo_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1338) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1339)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1340)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1341) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1342)   FILE *pkginfo = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1343) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1344)   struct pkg *pkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1345)   char *pkgname = NULL, *pkgver = NULL, *group = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1346) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1347)   if( pkginfo_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1348)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1349)     pkginfo = fopen( (const char *)pkginfo_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1350)     if( !pkginfo )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1351)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1352)       FATAL_ERROR( "Cannot open %s file", pkginfo_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1353)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1354)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1355) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1356)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1357)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1358)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1359)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1360)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1361) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1362)   while( (ln = fgets( line, PATH_MAX, pkginfo )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1363)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1364)     char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1365) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1366)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1367)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1368) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1369)     if( (match = strstr( ln, "pkgname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1370)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1371)       if( p != NULL ) pkgname = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1372)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1373)     if( (match = strstr( ln, "pkgver" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1374)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1375)       if( p != NULL ) pkgver = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1376)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1377)     if( (match = strstr( ln, "group" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1378)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1379)       if( p != NULL ) group = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1380)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1381)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1382) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1383)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1384) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1385)   if( pkgname && pkgver )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1386)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1387)     pkg = pkg_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1388)     if( pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1389)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1390)       if( group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1391)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1392)         pkg->group = group;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1393)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1394)       pkg->name    = pkgname;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1395)       pkg->version = pkgver;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1396)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1397) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1398)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1399)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1400)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1401)     if( group )      free( group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1402)     if( pkgname )    free( pkgname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1403)     if( pkgver )     free( pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1404) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1405)     FATAL_ERROR( "Invalid input .PKGINFO file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1406)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1407) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1408)   fclose( pkginfo );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1409) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1410)   return( pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1411) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1412) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1413) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1414) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1415) static void get_short_description( char *buf, const char *line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1416) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1417)   char *s, *p, *q;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1418) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1419)   if( buf ) { buf[0] = '\0'; s = buf; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1420)   if( !line || line[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1421) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1422)   p = index( line, '(' );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1423)   q = index( line, ')' );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1424)   if( p && q && q > p )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1425)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1426)     ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1427)     while( *p && p < q )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1428)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1429)       *s = *p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1430)       ++p; ++s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1431)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1432)     *s = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1433)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1434)   else
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)       If short description declaration is incorrect at first line
11c606a6 (kx 2023-04-11 01:18:34 +0300 1438)       of description; then we take whole first line of description:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1439)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1440)     p = index( line, ':' ); ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1441)     while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1442)     strcpy( buf, p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1443)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1444) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1445) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1446) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1447) static int get_references_section( int *start, int *stop, unsigned int *cnt, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1448) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1449)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1450) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1451)   if( !start || !stop || !cnt ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1452) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1453)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1454)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1455)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1456)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1457) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1458)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1459)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1460)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1461)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1462)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1463) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1464)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1465)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1466) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1467)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1468)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1469)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1470) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1471)       if( (match = strstr( ln, "REFERENCE COUNTER:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1472)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1473)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1474)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1475) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1476)         /* Get reference counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1477)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1478)           unsigned int count;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1479)           int          rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1480) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1481)           ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1482)           skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1483) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1484)           rc = sscanf( ln, "REFERENCE COUNTER: %u", &count );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1485)           if( rc == 1 && cnt != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1486)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1487)             *cnt = count;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1488)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1489)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1490)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1491)       if( (match = strstr( ln, "REQUIRES:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1492)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1493)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1494)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1495)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1496) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1497)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1498)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1499) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1500)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1501) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1502)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1503) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1504)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1505)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1506) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1507)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1508) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1509) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1510) static int get_requires_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1511) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1512)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1513) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1514)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1515) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1516)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1517)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1518)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1519)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1520) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1521)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1522)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1523)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1524)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1525)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1526) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1527)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1528)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1529) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1530)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1531)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1532)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1533) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1534)       if( (match = strstr( ln, "REQUIRES:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1535)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1536)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1537)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1538)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1539)       if( (match = strstr( ln, "PACKAGE DESCRIPTION:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1540)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1541)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1542)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1543)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1544) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1545)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1546)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1547) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1548)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1549) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1550)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1551) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1552)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1553)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1554) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1555)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1556) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1557) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1558) static int get_description_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1559) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1560)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1561) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1562)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1563) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1564)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1565)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1566)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1567)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1568) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1569)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1570)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1571)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1572)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1573)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1574) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1575)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1576)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1577) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1578)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1579)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1580)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1581) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1582)       if( (match = strstr( ln, "PACKAGE DESCRIPTION:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1583)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1584)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1585)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1586)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1587)       if( (match = strstr( ln, "RESTORE LINKS:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1588)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1589)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1590)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1591)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1592) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1593)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1594)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1595) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1596)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1597) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1598)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1599) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1600)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1601)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1602) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1603)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1604) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1605) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1606) static int get_restore_links_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1607) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1608)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1609) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1610)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1611) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1612)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1613)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1614)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1615)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1616) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1617)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1618)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1619)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1620)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1621)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1622) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1623)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1624)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1625) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1626)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1627)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1628)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1629) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1630)       if( (match = strstr( ln, "RESTORE LINKS:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1631)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1632)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1633)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1634)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1635)       if( (match = strstr( ln, "INSTALL SCRIPT:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1636)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1637)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1638)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1639)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1640) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1641)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1642)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1643) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1644)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1645) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1646)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1647) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1648)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1649)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1650) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1651)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1652) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1653) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1654) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1655) static int get_install_script_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1656) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1657)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1658) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1659)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1660) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1661)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1662)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1663)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1664)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1665) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1666)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1667)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1668)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1669)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1670)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1671) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1672)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1673)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1674) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1675)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1676)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1677)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1678) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1679)       if( (match = strstr( ln, "INSTALL SCRIPT:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1680)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1681)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1682)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1683)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1684)       if( (match = strstr( ln, "FILE LIST:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1685)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1686)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1687)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1688)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1689) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1690)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1691)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1692) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1693)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1694) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1695)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1696) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1697)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1698)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1699) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1700)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1701) }
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) static int get_file_list_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1705) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1706)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1707) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1708)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1709) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1710)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1711)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1712)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1713)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1714) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1715)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1716)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1717)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1718)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1719)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1720) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1721)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1722)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1723) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1724)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1725)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1726)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1727) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1728)       if( (match = strstr( ln, "FILE LIST:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1729)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1730)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1731)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1732)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1733) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1734)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1735)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1736) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1737)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1738) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1739)     ret = ( found == 1 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1740) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1741)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1742)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1743) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1744)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1745) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1746) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1747) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1748) int read_pkginfo( FILE *log, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1749) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1750)   int ret = -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1751) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1752)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1753)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1754) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1755)   char           *pkgname_pattern = "PACKAGE NAME:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1756)                   *pkgver_pattern = "PACKAGE VERSION:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1757)                     *arch_pattern = "ARCH:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1758)               *distroname_pattern = "DISTRO:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1759)                *distrover_pattern = "DISTRO VERSION:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1760)                    *group_pattern = "GROUP:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1761)                      *url_pattern = "URL:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1762)                  *license_pattern = "LICENSE:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1763)        *uncompressed_size_pattern = "UNCOMPRESSED SIZE:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1764)              *total_files_pattern = "TOTAL FILES:";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1765) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1766) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1767)   if( !log || !package ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1768) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1769)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1770)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1771)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1772)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1773)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1774) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1775)   ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1776) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1777)   while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1778)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1779)     char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1780) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1781)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1782)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1783) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1784)     if( (match = strstr( ln, pkgname_pattern )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1785)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1786)       package->pkginfo->name = skip_spaces( ln + strlen( pkgname_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1787)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1788)     if( (match = strstr( ln, pkgver_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1789)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1790)       package->pkginfo->version = skip_spaces( ln + strlen( pkgver_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1791)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1792)     if( (match = strstr( ln, arch_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1793)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1794)       package->pkginfo->arch = skip_spaces( ln + strlen( arch_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1795)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1796)     if( (match = strstr( ln, distroname_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1797)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1798)       package->pkginfo->distro_name = skip_spaces( ln + strlen( distroname_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1799)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1800)     if( (match = strstr( ln, distrover_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1801)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1802)       package->pkginfo->distro_version = skip_spaces( ln + strlen( distrover_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1803)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1804)     if( (match = strstr( ln, group_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1805)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1806)       package->pkginfo->group = skip_spaces( ln + strlen( group_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1807)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1808)     if( (match = strstr( ln, url_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1809)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1810)       package->pkginfo->url = skip_spaces( ln + strlen( url_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1811)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1812)     if( (match = strstr( ln, license_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1813)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1814)       package->pkginfo->license = skip_spaces( ln + strlen( license_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1815)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1816)     if( (match = strstr( ln, uncompressed_size_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1817)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1818)       package->pkginfo->uncompressed_size = read_usize( ln + strlen( uncompressed_size_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1819)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1820)     if( (match = strstr( ln, total_files_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1821)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1822)       package->pkginfo->total_files = read_total_files( ln + strlen( total_files_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1823)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1824) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1825)     if( (match = strstr( ln, "PACKAGE DESCRIPTION:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1826)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1827)       char *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1828) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1829)       buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1830)       if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1831)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1832)         FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1833)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1834) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1835)       /* Get short_description from PACKAGE DESCRIPTION */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1836)       ln = fgets( line, PATH_MAX, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1837)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1838) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1839)       bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1840)       get_short_description( buf, (const char *)line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1841)       if( buf[0] != '\0' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1842)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1843)         package->pkginfo->short_description = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1844)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1845)       free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1846)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1847) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1848)   } /* End of while() */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1849) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1850)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1851) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1852)   if( package->pkginfo->name           == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1853)   if( package->pkginfo->version        == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1854)   if( package->pkginfo->arch           == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1855)   if( package->pkginfo->distro_name    == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1856)   if( package->pkginfo->distro_version == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1857)   /* group can be equal to NULL */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1858) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1859)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1860) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1861)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1862) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1863) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1864) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1865) static unsigned int read_references( FILE *log, int start, unsigned int *cnt, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1866) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1867)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1868)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1869)   char *p = NULL, *group = NULL, *name = NULL, *version = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1870)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1871) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1872)   unsigned int counter, pkgs = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1873) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1874)   struct pkg *pkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1875) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1876)   if( !log || !cnt || *cnt == 0 || !package ) return pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1877) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1878)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1879)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1880)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1881)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1882)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1883) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1884)   counter = *cnt;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1885) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1886)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1887) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1888)   n = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1889)   while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1890)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1891)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1892)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1893) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1894)     if( strstr( ln, "REQUIRES:" ) ) break; /* if cnt greater than real number of references */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1895) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1896)     if( n < counter )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1897)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1898)       if( (p = index( (const char *)ln, '=' )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1899)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1900)         *p = '\0'; version = ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1901)         if( (p = index( (const char *)ln, '/' )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1902)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1903)           *p = '\0'; name = ++p; group = (char *)&ln[0];
11c606a6 (kx 2023-04-11 01:18:34 +0300 1904)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1905)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1906)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1907)           name  = (char *)&ln[0]; group = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1908)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1909) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1910)         pkg = pkg_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1911) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1912)         if( group ) pkg->group = xstrdup( (const char *)group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1913)         pkg->name    = xstrdup( (const char *)name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1914)         pkg->version = xstrdup( (const char *)version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1915) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1916)         add_reference( package, pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1917)         ++pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1918)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1919)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1920)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1921)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1922)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1923)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1924) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1925)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1926) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1927)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1928) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1929)   *cnt = pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1930) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1931)   return pkgs;
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) static unsigned int read_requires( FILE *log, int start, int stop, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1936) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1937)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1938)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1939)   char *p = NULL, *group = NULL, *name = NULL, *version = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1940)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1941) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1942)   unsigned int pkgs = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1943) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1944)   struct pkg *pkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1945) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1946)   if( !log || !package ) return pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1947) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1948)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1949)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1950)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1951)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1952)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1953) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1954)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1955) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1956)   if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1957)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1958)     ++n; /* skip section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1959) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1960)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1961)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1962)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1963)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1964) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1965)       if( strstr( ln, "PACKAGE DESCRIPTION:" ) ) break; /* if (stop - start - 1) greater than real number of requiress */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1966) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1967)       if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1968)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1969)         if( (p = index( (const char *)ln, '=' )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1970)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1971)           *p = '\0'; version = ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1972)           if( (p = index( (const char *)ln, '/' )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1973)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1974)             *p = '\0'; name = ++p; group = (char *)&ln[0];
11c606a6 (kx 2023-04-11 01:18:34 +0300 1975)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1976)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1977)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1978)             name  = (char *)&ln[0]; group = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1979)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1980) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1981)           pkg = pkg_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1982) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1983)           if( group ) pkg->group = xstrdup( (const char *)group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1984)           pkg->name    = xstrdup( (const char *)name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1985)           pkg->version = xstrdup( (const char *)version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1986) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1987)           add_required( package, pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1988)           ++pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1989)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1990) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1991)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1992)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1993)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1994) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1995)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1996) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1997)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1998) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1999)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2000) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2001)   return pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2002) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2003) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2004) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2005) static unsigned int read_description( FILE *log, int start, int stop, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2006) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2007)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2008)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2009)   char *pattern = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2010)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2011) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2012)   char  *tmp_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2013)   FILE  *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2014) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2015)   unsigned int lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2016) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2017)   if( !log || !package ) return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2018) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2019)   tmp_fname = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2020)   if( !tmp_fname ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2021) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2022)   bzero( (void *)tmp_fname, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2023)   (void)sprintf( (char *)&tmp_fname[0], "%s/.DESCRIPTION", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2024) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2025)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2026)   if( !line )    { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2027) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2028)   pattern = (char *)malloc( (size_t)strlen( package->pkginfo->name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2029)   if( !pattern ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2030) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2031)   (void)sprintf( pattern, "%s:", package->pkginfo->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2032) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2033) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2034)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2035) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2036)   if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2037)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2038)     ++n; /* skip section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2039) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2040)     tmp = fopen( (const char *)&tmp_fname[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2041)     if( !tmp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2042)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2043)       FATAL_ERROR( "Cannot create temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2044)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2045) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2046)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2047)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2048)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2049) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2050)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2051)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2052) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2053)       if( strstr( ln, "RESTORE LINKS:" ) ) break; /* if (stop - start - 1) greater than real number of lines */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2054) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2055)       if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2056)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2057)         /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 2058)           skip non-significant spaces at beginning of line
11c606a6 (kx 2023-04-11 01:18:34 +0300 2059)           and print lines started with 'pkgname:'
11c606a6 (kx 2023-04-11 01:18:34 +0300 2060)          */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2061)         if( (match = strstr( ln, pattern )) && lines < DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2062)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2063)           int mlen   = strlen( match ), plen = strlen( pattern );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2064)           int length = ( mlen > plen )  ? (mlen - plen - 1) : 0 ;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2065) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2066)           if( length > DESCRIPTION_LENGTH_OF_LINE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2067)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2068)             /* WARNING( "Package DESCRIPTION contains lines with length greater than %d characters", DESCRIPTION_LENGTH_OF_LINE ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2069)             match[plen + 1 + DESCRIPTION_LENGTH_OF_LINE] = '\0'; /* truncating description line  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2070)             skip_eol_spaces( match );                            /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2071)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2072)           fprintf( tmp, "%s\n", match );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2073)           ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2074)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2075) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2076)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2077)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2078)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2079) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2080)     if( lines < (unsigned int)DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2081)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2082)       /* WARNING( "Package DESCRIPTION contains less than %d lines", DESCRIPTION_NUMBER_OF_LINES ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2083)       while( lines < (unsigned int)DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2084)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2085)         fprintf( tmp, "%s\n", pattern );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2086)         ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2087)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2088)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2089) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2090)     fflush( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2091)     fclose( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2092) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2093)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2094) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2095)   free( pattern );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2096)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2097) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2098)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2099) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2100)   /* read temporary saved description */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2101)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2102)     struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2103)     size_t size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2104)     int    fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2105) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2106)     char  *desc = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2107) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2108)     if( stat( tmp_fname, &sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2109)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2110)       FATAL_ERROR( "Cannot stat temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2111)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2112)     size = (size_t)sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2113) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2114)     if( size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2115)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2116)       ssize_t rc = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2117) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2118)       desc = (char *)malloc( size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2119)       if( !desc ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2120)       bzero( (void *)desc, size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2121) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2122)       if( (fd = open( (const char *)&tmp_fname[0], O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2123)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2124)         FATAL_ERROR( "Canot access temporary %s file: %s", basename( (char *)&tmp_fname[0] ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2125)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2126) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2127)       rc = read( fd, (void *)desc, size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2128)       if( rc != (ssize_t)size ) { ERROR( "The %s file is not fully read", basename( (char *)&tmp_fname[0] ) ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2129) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2130)       package->description = desc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2131) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2132)       close( fd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2133)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2134) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2135)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2136) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2137)   (void)unlink( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2138)   free( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2139) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2140)   return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2141) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2142) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2143) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2144) static unsigned int read_restore_links( FILE *log, int start, int stop, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2145) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2146)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2147)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2148)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2149) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2150)   char  *tmp_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2151)   FILE  *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2152) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2153)   unsigned int lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2154) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2155)   if( !log || !package ) return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2156) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2157)   tmp_fname = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2158)   if( !tmp_fname ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2159) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2160)   bzero( (void *)tmp_fname, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2161)   (void)sprintf( (char *)&tmp_fname[0], "%s/.RESTORELINKS", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2162) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2163)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2164)   if( !line )    { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2165) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2166)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2167) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2168)   if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2169)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2170)     ++n; /* skip section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2171) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2172)     tmp = fopen( (const char *)&tmp_fname[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2173)     if( !tmp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2174)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2175)       FATAL_ERROR( "Cannot create temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2176)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2177) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2178)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2179)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2180)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2181)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2182) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2183)       if( strstr( ln, "INSTALL SCRIPT:" ) ) break; /* if (stop - start - 1) greater than real number of lines */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2184) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2185)       if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2186)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2187)         fprintf( tmp, "%s\n", ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2188)         ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2189)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2190)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2191)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2192) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2193)     fflush( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2194)     fclose( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2195) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2196)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2197) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2198)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2199) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2200)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2201) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2202)   /* read temporary saved description */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2203)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2204)     struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2205)     size_t size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2206)     int    fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2207) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2208)     char  *links = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2209) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2210)     if( stat( tmp_fname, &sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2211)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2212)       FATAL_ERROR( "Cannot stat temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2213)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2214)     size = (size_t)sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2215) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2216)     if( size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2217)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2218)       ssize_t rc = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2219) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2220)       links = (char *)malloc( size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2221)       if( !links ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2222)       bzero( (void *)links, size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2223) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2224)       if( (fd = open( (const char *)&tmp_fname[0], O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2225)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2226)         FATAL_ERROR( "Canot access temporary %s file: %s", basename( (char *)&tmp_fname[0] ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2227)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2228) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2229)       rc = read( fd, (void *)links, size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2230)       if( rc != (ssize_t)size ) { ERROR( "The %s file is not fully read", basename( (char *)&tmp_fname[0] ) ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2231) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2232)       package->restore_links = links;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2233) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2234)       close( fd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2235)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2236) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2237)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2238) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2239)   (void)unlink( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2240)   free( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2241) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2242)   return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2243) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2244) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2245) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2246) static unsigned int read_install_script( FILE *log, int start, int stop, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2247) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2248)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2249)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2250)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2251) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2252)   char  *tmp_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2253)   FILE  *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2254) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2255)   unsigned int lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2256) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2257)   if( !log || !package ) return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2258) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2259)   tmp_fname = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2260)   if( !tmp_fname ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2261) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2262)   bzero( (void *)tmp_fname, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2263)   (void)sprintf( (char *)&tmp_fname[0], "%s/.INSTALL", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2264) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2265)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2266)   if( !line )    { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2267) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2268)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2269) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2270)   if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2271)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2272)     ++n; /* skip section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2273) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2274)     tmp = fopen( (const char *)&tmp_fname[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2275)     if( !tmp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2276)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2277)       FATAL_ERROR( "Cannot create temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2278)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2279) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2280)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2281)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2282)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2283)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2284) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2285)       if( strstr( ln, "FILE LIST:" ) ) break; /* if (stop - start - 1) greater than real number of lines */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2286) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2287)       if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2288)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2289)         fprintf( tmp, "%s\n", ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2290)         ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2291)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2292)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2293)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2294) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2295)     fflush( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2296)     fclose( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2297) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2298)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2299) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2300)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2301) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2302)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2303) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2304)   /* read temporary saved description */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2305)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2306)     struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2307)     size_t size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2308)     int    fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2309) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2310)     char  *install = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2311) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2312)     if( stat( tmp_fname, &sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2313)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2314)       FATAL_ERROR( "Cannot stat temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2315)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2316)     size = (size_t)sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2317) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2318)     if( size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2319)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2320)       ssize_t rc = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2321) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2322)       install = (char *)malloc( size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2323)       if( !install ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2324)       bzero( (void *)install, size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2325) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2326)       if( (fd = open( (const char *)&tmp_fname[0], O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2327)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2328)         FATAL_ERROR( "Canot access temporary %s file: %s", basename( (char *)&tmp_fname[0] ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2329)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2330) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2331)       rc = read( fd, (void *)install, size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2332)       if( rc != (ssize_t)size ) { ERROR( "The %s file is not fully read", basename( (char *)&tmp_fname[0] ) ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2333) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2334)       package->install_script = install;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2335) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2336)       close( fd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2337)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2338) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2339)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2340) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2341)   (void)unlink( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2342)   free( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2343) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2344)   return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2345) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2346) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2347) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2348) static unsigned int read_file_list( FILE *log, int start, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2349) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2350)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2351)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2352)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2353) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2354)   unsigned int files = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2355) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2356)   if( !log || !package ) return files;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2357) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2358)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2359)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2360)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2361)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2362)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2363) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2364)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2365) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2366)   if( start )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2367)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2368)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2369)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2370)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2371)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2372) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2373)       add_file( package, (const char *)ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2374)       ++files;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2375)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2376) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2377)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2378) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2379)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2380) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2381)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2382) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2383)   return files;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2384) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2385) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2386) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2387) static void _read_pkglog( const char *group, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2388) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2389)   FILE *log   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2390)   char *bname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2391) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2392)   if( fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2393)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2394)     log = fopen( (const char *)fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2395)     if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2396)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2397)       FATAL_ERROR( "Cannot open %s file", fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2398)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2399)     bname = (char *)fname + strlen( tmpdir ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2400)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2401) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2402)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2403)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2404)     struct package *package = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2405)     int             rc, start, stop;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2406)     unsigned int    counter;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2407) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2408)     package = package_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2409) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2410)     if( read_pkginfo( log, package ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2411)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2412)       ERROR( "%s: Invalid PKGLOG file", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2413)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2414)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2415)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2416)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2417) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2418)     if( hardware ) package->hardware = xstrdup( (const char *)hardware );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2419)     if( tarballs ) /* find tarball and allocate package->tarball */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2420)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2421)       struct pkginfo *info = package->pkginfo;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2422)       const char     *tgz  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2423)       char           *buf  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2424)       struct stat     sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2425) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2426)       buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2427)       if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2428) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2429)       if( info->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2430)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2431)         (void)sprintf( buf, "%s/%s-%s-%s-%s-%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2432)                              info->group, info->name, info->version, info->arch,
11c606a6 (kx 2023-04-11 01:18:34 +0300 2433)                              info->distro_name, info->distro_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2434)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2435)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2436)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2437)         (void)sprintf( buf, "%s-%s-%s-%s-%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2438)                              info->name, info->version, info->arch,
11c606a6 (kx 2023-04-11 01:18:34 +0300 2439)                              info->distro_name, info->distro_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2440)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2441)       tgz = find_tarball( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2442)       if( tgz )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2443)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2444)         package->tarball = xstrdup( (const char *)tgz );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2445) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2446)         bzero( (void *)&buf[0], PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2447)         (void)sprintf( buf, "%s/%s", srcdir, tgz );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2448)         if( stat( buf, &sb ) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2449)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2450)           info->compressed_size = (size_t)sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2451)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2452)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2453)       free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2454)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2455)     package->procedure = INSTALL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2456)     package->priority  = priority;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2457) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2458)     if( package->pkginfo->group && group  && strcmp( package->pkginfo->group, group ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2459)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2460)       char *tgz;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2461) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2462)       if( package->tarball ) { tgz = package->tarball; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2463)       else                   { tgz = basename( (char *)fname ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2464) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2465)       WARNING( "%s: Should be moved into '%s' subdir", tgz, package->pkginfo->group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2466)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2467) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2468)     /******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2469)       read references:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2470)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2471)     rc = get_references_section( &start, &stop, &counter, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2472)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2473)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2474)       ERROR( "%s: PKGLOG doesn't contains REFERENCE COUNTER section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2475)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2476)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2477)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2478)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2479)     if( counter > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2480)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2481)       unsigned int pkgs = counter;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2482) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2483)       if( read_references( log, start, &counter, package ) != pkgs )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2484)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2485)         ERROR( "%s: Invalid REFERENCE COUNTER section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2486)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2487)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2488)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2489)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2490)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2491) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2492)     /******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2493)       read requires:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2494)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2495)     rc = get_requires_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2496)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2497)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2498)       ERROR( "%s: PKGLOG doesn't contains REQUIRES section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2499)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2500)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2501)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2502)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2503)     if( (stop - start) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2504)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2505)       unsigned int pkgs = (unsigned int)(stop - start - 1); /* -1 skips section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2506) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2507)       if( read_requires( log, start, stop, package ) != pkgs )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2508)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2509)         ERROR( "%s: Invalid REQUIRES section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2510)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2511)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2512)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2513)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2514)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2515) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2516)     /*******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2517)       read description:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2518)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2519)     rc = get_description_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2520)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2521)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2522)       ERROR( "%s: PKGLOG doesn't contains PACKAGE DESCRIPTION section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2523)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2524)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2525)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2526)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2527)     if( (stop - start) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2528)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2529)       if( read_description( log, start, stop, package ) != (unsigned int)DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2530)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2531)         ERROR( "%s: Invalid DESCRIPTION section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2532)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2533)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2534)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2535)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2536)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2537) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2538)     /*********************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2539)       read restore links:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2540)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2541)     rc = get_restore_links_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2542)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2543)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2544)       ERROR( "%s: PKGLOG doesn't contains RESTORE LINKS section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2545)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2546)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2547)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2548)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2549)     if( (stop - start) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2550)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2551)       (void)read_restore_links( log, start, stop, package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2552)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2553) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2554)     /*********************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2555)       read install script:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2556)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2557)     rc = get_install_script_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2558)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2559)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2560)       ERROR( "%s: PKGLOG doesn't contains INSTALL SCRIPT section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2561)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2562)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2563)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2564)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2565)     if( (stop - start) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2566)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2567)       (void)read_install_script( log, start, stop, package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2568)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2569) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2570)     /*****************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2571)       read file_list:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2572)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2573)     rc = get_file_list_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2574)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2575)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2576)       ERROR( "%s: PKGLOG doesn't contains FILE LIST section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2577)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2578)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2579)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2580)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2581)     if( start )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2582)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2583)       unsigned int files = read_file_list( log, start, package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2584)       if( files == (unsigned int)0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2585)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2586)         /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 2587)           Packages that do not contain regular files are ignored.
11c606a6 (kx 2023-04-11 01:18:34 +0300 2588)           For example, service package base/init-devices-1.2.3-s9xx-glibc-radix-1.1.txz
11c606a6 (kx 2023-04-11 01:18:34 +0300 2589)          */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2590)         if( ! DO_NOT_PRINTOUT_INFO )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2591)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2592)           INFO( "%s: PKGLOG contains empty FILE LIST section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2593)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2594)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2595)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2596)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2597)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2598)       package->pkginfo->total_files = (int)files;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2599)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2600) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2601)     /* Skip excluded package: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2602)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2603)       const char *name = find_exclude( (const char *)package->pkginfo->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2604) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2605)       if( name && !strcmp( name, package->pkginfo->name ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2606)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2607)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2608)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2609)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2610)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2611)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2612) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2613)     add_package( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2614) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2615)     ++__child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2616)     fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2617)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2618) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2619) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2620) static void _read_pkglogs( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2621) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2622)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2623)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2624)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2625) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2626)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2627)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2628) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2629)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2630)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2631)     FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2632)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2633) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2634)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2635)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2636)     FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2637)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2638) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2639)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2640)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2641)     FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2642)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2643) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2644)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2645) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2646)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 2647)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2648)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2649)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2650) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2651)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2652)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2653) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2654)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2655)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2656)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2657) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2658)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2659)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2660)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2661)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2662)         if( check_input_file( NULL, (const char *)path ) == IFMT_LOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2663)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2664)           _read_pkglog( grp, (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2665)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2666)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2667)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2668)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2669)         _read_pkglogs( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2670)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2671)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2672)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2673)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2674) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2675)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2676) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2677) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2678) int read_pkglogs( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2679) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2680)   int ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2681) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2682)   __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2683) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2684)   _read_pkglogs( (const char *)tmpdir, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2685) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2686)   ret = __child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2687) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2688)   __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2689) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2690)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2691) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2692) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2693) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2694) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2695) /*****************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2696)   Count slashes in file name:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2697)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2698) static int count_slashes( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2699) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2700)   int   cnt = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2701)   char *p   = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2702) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2703)   if( !s || *s == '\0' ) return cnt;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2704) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2705)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2706)   while( *p )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2707)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2708)     if( *p == '/' ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2709)       ++cnt;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2710)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2711)     ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2712)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2713) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2714)   return cnt;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2715) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2716) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2717) static void read_srcpkg_fnames( const char *flist )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2718) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2719)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2720)   FILE  *fp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2721) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2722)   if( !flist ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2723) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2724)   bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2725) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2726)   if( stat( flist, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2727)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2728)     FATAL_ERROR( "Cannot access input '%s' file or directory: %s", flist, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2729)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2730) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2731)   if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2732)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2733)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2734)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2735)     int   lnum = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2736) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2737)     fp = fopen( flist, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2738)     if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2739)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2740)       FATAL_ERROR( "Cannot open %s file", flist );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2741)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2742) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2743)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2744)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2745)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2746)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2747)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2748) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2749)     while( (ln = fgets( line, PATH_MAX, fp )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2750)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2751)       struct srcpkg_fname *fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2752) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2753)       ++lnum;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2754)       if( strlen( ln ) == 0 ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2755)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2756)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2757)       /* remove leading spaces: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2758)       while( (*ln == ' ' || *ln == '\t') && *ln != '\0' ) { ++ln; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2759)       /* skip comments and empty lines: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2760)       if( *ln == '\0' || *ln == '#' ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2761) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2762)       if( count_slashes( ln ) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2763)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2764)         FATAL_ERROR( "%s:%d: file name contains more than one slash symbols", flist, lnum );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2765)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2766) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2767)       if( ! isalpha( *ln ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2768)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2769)         FATAL_ERROR( "%s:%d: file path must be relative and start with a letter (as a group name)", flist, lnum );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2770)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2771) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2772)       fname = srcpkg_fname_alloc( (const char *)ln, lnum );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2773)       add_srcpkg_fname( fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2774)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2775) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2776)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2777)     fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2778)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2779)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2780)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2781)     FATAL_ERROR( "Source file names list '%s' is not a regular file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2782)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2783) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2784) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2785) static void check_srcfile( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2786) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2787)   struct srcpkg_fname *srcfile = (struct srcpkg_fname *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2788) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2789)   if( srcfile )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2790)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2791)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2792)     char *fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2793)     struct pkg *srcpkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2794) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2795)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2796) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2797)     fname = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2798)     if( !fname ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2799)     bzero( (void *)fname, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2800) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2801)     (void)sprintf( &fname[0], "%s/%s", srcdir, srcfile->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2802) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2803)     if( stat( (const char *)fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2804)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2805)       FATAL_ERROR( "%s:%d: Cannot access input '%s' file or directory: %s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2806)                     srcfile->name, srcfile->line, fname, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2807)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2808) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2809)     if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2810)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2811)       enum _input_type format = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2812) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2813)       pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2814)       int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2815) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2816)       int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2817)       char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2818) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2819)       tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2820)       if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2821)       bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2822) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2823)       (void)sprintf( &tmp[0], "%s", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2824)       if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2825)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2826)         FATAL_ERROR( "%s:%d: Cannot get PKGINFO from '%s' file",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2827)                       srcfile->name, srcfile->line, basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2828)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2829) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2830)       cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2831)       if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2832)       bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2833) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2834)       len = snprintf( &cmd[0], PATH_MAX, "%s/pkginfo -d %s -o pkginfo %s > /dev/null 2>&1", selfdir, tmp, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2835)       if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2836)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2837)         FATAL_ERROR( "%s:%d: Cannot get PKGINFO from %s file",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2838)                       srcfile->name, srcfile->line, basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2839)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2840)       p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2841)       rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2842)       if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2843)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2844)         FATAL_ERROR( "%s:%d: Cannot get PKGINFO from '%s' file",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2845)                       srcfile->name, srcfile->line, basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2846)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2847) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2848)       (void)strcat( tmp, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2849) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2850)       bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2851)       if( stat( (const char *)tmp, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2852)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2853)         FATAL_ERROR( "%s:%d: Cannot get PKGINFO from %s file: %s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2854)                       srcfile->name, srcfile->line, basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2855)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2856) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2857)       srcpkg = input_package( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2858)       bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2859)       if( srcpkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2860)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2861)         char *e = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2862) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2863)         if( srcpkg->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2864)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2865)           len = snprintf( &tmp[0], PATH_MAX, "%s/%s", srcpkg->group, basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2866)           if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2867)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2868)             FATAL_ERROR( "%s:%d: Cannot get PKGINFO from %s file",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2869)                           srcfile->name, srcfile->line, basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2870)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2871)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2872)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2873)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2874)           len = snprintf( &tmp[0], PATH_MAX, "%s", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2875)           if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2876)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2877)             FATAL_ERROR( "%s:%d: Cannot get PKGINFO from %s file",
11c606a6 (kx 2023-04-11 01:18:34 +0300 2878)                           srcfile->name, srcfile->line, basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2879)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2880)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2881) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2882)         add_srcpkg( srcpkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2883) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2884)         remove_trailing_slash( srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2885)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2886) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2887)       free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2888)       free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2889)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2890) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2891)     free( fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2892)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2893) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2894) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2895) static void check_srcdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2896) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2897)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2898)   char *fname = srcdir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2899)   struct pkg *srcpkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2900) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2901)   bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2902) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2903)   if( stat( (const char *)srcdir, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2904)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2905)     FATAL_ERROR( "Cannot access input '%s' file or directory: %s", srcdir, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2906)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2907) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2908)   if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2909)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2910)     enum _input_type format = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2911) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2912)     pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2913)     int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2914) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2915)     int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2916)     char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2917) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2918)     tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2919)     if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2920)     bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2921) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2922)     (void)sprintf( &tmp[0], "%s", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2923)     if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2924)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2925)       FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2926)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2927) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2928)     cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2929)     if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2930)     bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2931) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2932)     len = snprintf( &cmd[0], PATH_MAX, "%s/pkginfo -d %s -o pkginfo %s > /dev/null 2>&1", selfdir, tmp, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2933)     if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2934)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2935)       FATAL_ERROR( "Cannot get PKGINFO from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2936)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2937)     p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2938)     rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2939)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2940)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2941)       FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2942)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2943) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2944)     (void)strcat( tmp, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2945) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2946)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2947)     if( stat( (const char *)tmp, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2948)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2949)       FATAL_ERROR( "Cannot get PKGINFO from %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2950)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2951) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2952)     /* keep or set input file format: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2953)     format = check_input_file( NULL, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2954)     if( input_format == IFMT_UNKNOWN ) input_format = format;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2955) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2956)     srcpkg = input_package( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2957)     bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2958)     if( srcpkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2959)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2960)       char *e = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2961) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2962)       if( srcpkg->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2963)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2964)         len = snprintf( &tmp[0], PATH_MAX, "%s/%s", srcpkg->group, basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2965)         if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2966)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2967)           FATAL_ERROR( "Cannot get PKGINFO from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2968)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2969)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2970)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2971)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2972)         len = snprintf( &tmp[0], PATH_MAX, "%s", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2973)         if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2974)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2975)           FATAL_ERROR( "Cannot get PKGINFO from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2976)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2977)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2978) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2979)       add_srcpkg( srcpkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2980) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2981)       /* remove source file name (with group directory if defined) from srcdir path */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2982)       e = strstr( (const char *)srcdir, (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2983)       if( !e ) { e = strstr( (const char *)srcdir, (const char *)basename( (char *)fname ) ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2984)       *e = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 2985) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2986)       remove_trailing_slash( srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2987)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2988) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2989)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2990)     free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2991)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2992) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2993)   if( S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2994)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2995)     if( srclist_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2996)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2997)       read_srcpkg_fnames( srclist_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2998)       dlist_foreach( srcpkg_fnames, check_srcfile, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2999)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3000)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3001) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3002) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3003) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3004) static void _print_extern_requires( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3005) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3006)   struct pkg *pkg = (struct pkg *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3007) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3008)   if( pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3009)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3010)     if( pkg->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3011)       fprintf( stderr, "%s/%s:%s:%s\n", pkg->group, pkg->name, pkg->version, strproc( pkg->procedure ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3012)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 3013)       fprintf( stderr, "%s:%s:%s\n", pkg->name, pkg->version, strproc( pkg->procedure ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3014)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3015) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3016) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3017) static void print_extern_requires( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3018) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3019)   dlist_foreach( extern_requires, _print_extern_requires, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3020) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3021) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3022) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3023) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 3024)   Get directory where this program is placed:
11c606a6 (kx 2023-04-11 01:18:34 +0300 3025)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 3026) char *get_selfdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3027) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3028)   char    *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3029)   ssize_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3030) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3031)   buf = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3032)   if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3033)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3034)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3035)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3036) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3037)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3038)   len = readlink( "/proc/self/exe", buf, (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3039)   if( len > 0 && len < PATH_MAX )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3040)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3041)     char *p = xstrdup( (const char *)dirname( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3042)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3043)     return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3044)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3045)   FATAL_ERROR( "Cannot determine self directory. Please mount /proc filesystem" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3046) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3047) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3048) void set_stack_size( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3049) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3050)   const rlim_t   stack_size = 16 * 1024 * 1024; /* min stack size = 16 MB */
11c606a6 (kx 2023-04-11 01:18:34 +0300 3051)   struct rlimit  rl;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3052)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3053) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3054)   ret = getrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3055)   if( ret == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3056)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3057)     if( rl.rlim_cur < stack_size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3058)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3059)       rl.rlim_cur = stack_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3060)       ret = setrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3061)       if( ret != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3062)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3063)         fprintf(stderr, "setrlimit returned result = %d\n", ret);
11c606a6 (kx 2023-04-11 01:18:34 +0300 3064)         FATAL_ERROR( "Cannot set stack size" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3065)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3066)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3067)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3068) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3069) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3070) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3071) int main( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3072) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3073)   gid_t  gid;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3074) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3075)   set_signal_handlers();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3076) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3077)   gid = getgid();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3078)   setgroups( 1, &gid );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3079) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3080)   fatal_error_hook = fatal_error_actions;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3081) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3082)   selfdir = get_selfdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3083) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3084)   errlog = stderr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3085) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3086)   program = basename( argv[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3087)   get_args( argc, argv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3088) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3089)   /* set_stack_size(); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 3090) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3091)   tmpdir = _mk_tmpdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3092)   if( !tmpdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3093)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3094)     FATAL_ERROR( "Cannot create temporary directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3095)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3096) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3097)   /********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 3098)     Check if the --source argument is a file or directory:
11c606a6 (kx 2023-04-11 01:18:34 +0300 3099)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 3100)   check_srcdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3101) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3102)   /* Extract or Copy PKGLOGs into TMPDIR: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 3103)   if( input_format == IFMT_PKG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3104)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3105)     int pkgs = extract_pkglogs();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3106)     if( pkgs == 0 )       { FATAL_ERROR( "There are no packages in the '%s' directory", srcdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3107)     if( exit_status > 0 ) { FATAL_ERROR( "Cannot extract PKGLOG from some package" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3108)     if( ! DO_NOT_PRINTOUT_INFO )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3109)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3110)       INFO( "Found %d packages in the '%s' directory", pkgs, srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3111)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3112)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3113)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 3114)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3115)     int pkgs = copy_pkglogs();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3116)     if( pkgs == 0 )       { FATAL_ERROR( "There are no PKGLOG files in the '%s' directory", srcdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3117)     if( exit_status > 0 ) { FATAL_ERROR( "Cannot copy some PKGLOG file" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3118)     if( ! DO_NOT_PRINTOUT_INFO )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3119)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3120)       INFO( "Found %d PKGLOG files in the '%s' directory", pkgs, srcdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3121)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3122)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3123) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3124)   /* Read PKGLOGs from TMPDIR and create Double Linked List of PACKAGES: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 3125)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3126)     int pkgs = read_pkglogs();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3127)     if( pkgs == 0 )       { FATAL_ERROR( "There are no PKGLOG files in the '%s' directory", tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3128)     if( exit_status > 0 ) { FATAL_ERROR( "Cannot read some PKGLOG file" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3129)     if( ! DO_NOT_PRINTOUT_INFO )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3130)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3131)       /* INFO( "Found %d PKGLOG files in the '%s' directory", pkgs, tmpdir ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 3132)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3133)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3134) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3135)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3136)     int extern_pkgs = create_provides_list( srcpkgs );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3137)     if( output_format == OFMT_LIST )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3138)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3139)       print_provides_list( (const char *)pkglist_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3140)       if( extern_pkgs )
11c606a6 (kx 2023-04-11 01:18:34 +0300 3141)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 3142)         /* Output machine readable list of requires to stderr: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 3143)         print_extern_requires();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3144)         exit_status += 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 3145)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3146)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3147)     if( output_format == OFMT_JSON ) print_provides_tree( (const char *)pkglist_fname, tree_format );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3148)     free_provides_list();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3149)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3150) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3151)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 3152)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 3153) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 3154)   exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 3155) }