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 <sys/resource.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   44) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   45) #include <signal.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   46) #if !defined SIGCHLD && defined SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   47) # define SIGCHLD SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300   48) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300   49) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   50) #define _GNU_SOURCE
11c606a6 (kx 2023-04-11 01:18:34 +0300   51) #include <getopt.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   52) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   53) #include <msglog.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   54) #include <wrapper.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   55) #include <system.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   56) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   57) #define PROGRAM_NAME "chrefs"
11c606a6 (kx 2023-04-11 01:18:34 +0300   58) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   59) #include <defs.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300   60) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   61) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   62) char *program     = PROGRAM_NAME;
11c606a6 (kx 2023-04-11 01:18:34 +0300   63) char *destination = NULL, *operation = NULL, *pkglog_fname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   64)      *tmpdir = NULL, *requires_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   65) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   66) int   exit_status = EXIT_SUCCESS; /* errors counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300   67) char *selfdir     = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   68) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   69) char           *pkgname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   70)                 *pkgver = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   71)                   *arch = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   72)             *distroname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   73)              *distrover = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300   74)                  *group = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   75) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   76) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   77) /********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300   78)   *requires[] declarations:
11c606a6 (kx 2023-04-11 01:18:34 +0300   79)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300   80) struct package {
11c606a6 (kx 2023-04-11 01:18:34 +0300   81)   char *name;
11c606a6 (kx 2023-04-11 01:18:34 +0300   82)   char *version;
11c606a6 (kx 2023-04-11 01:18:34 +0300   83)   char *arch;
11c606a6 (kx 2023-04-11 01:18:34 +0300   84)   char *distro_name;
11c606a6 (kx 2023-04-11 01:18:34 +0300   85)   char *distro_version;
11c606a6 (kx 2023-04-11 01:18:34 +0300   86) };
11c606a6 (kx 2023-04-11 01:18:34 +0300   87) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   88) static struct package *create_package( char *name, char *version,
11c606a6 (kx 2023-04-11 01:18:34 +0300   89)                                        char *arch, char *distro_name,
11c606a6 (kx 2023-04-11 01:18:34 +0300   90)                                        char *distro_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300   91) static void free_package( struct package *pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300   92) static struct package **create_requires( size_t size );
11c606a6 (kx 2023-04-11 01:18:34 +0300   93) static void free_requires( struct package **requires );
11c606a6 (kx 2023-04-11 01:18:34 +0300   94) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300   95)   End of *requires[] declarations.
11c606a6 (kx 2023-04-11 01:18:34 +0300   96)  ********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300   97) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   98) struct package **requires = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   99) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  100) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  101) /********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  102)   LOCK FILE declarations:
11c606a6 (kx 2023-04-11 01:18:34 +0300  103)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  104) static int __lock_file( FILE *fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  105) static void __unlock_file( int fd );
11c606a6 (kx 2023-04-11 01:18:34 +0300  106) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  107)   End of LOCK FILE declarations.
11c606a6 (kx 2023-04-11 01:18:34 +0300  108)  ********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  109) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  110) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  111) #define FREE_PKGINFO_VARIABLES() \
11c606a6 (kx 2023-04-11 01:18:34 +0300  112)   if( pkgname )           { free( pkgname );           } pkgname    = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300  113)   if( pkgver )            { free( pkgver );            } pkgver     = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300  114)   if( arch )              { free( arch );              } arch       = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300  115)   if( distroname )        { free( distroname );        } distroname = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300  116)   if( distrover )         { free( distrover );         } distrover  = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300  117)   if( group )             { free( group );             } group      = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300  118)   if( requires )          { free_requires( requires ); } requires   = NULL
11c606a6 (kx 2023-04-11 01:18:34 +0300  119) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  120) void free_resources()
11c606a6 (kx 2023-04-11 01:18:34 +0300  121) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  122)   if( selfdir )        { free( selfdir );        selfdir        = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  123)   if( destination )    { free( destination );    destination    = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  124)   if( operation )      { free( operation );      operation      = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  125)   if( pkglog_fname )   { free( pkglog_fname );   pkglog_fname   = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  126)   if( requires_fname ) { free( requires_fname ); requires_fname = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  127) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  128)   FREE_PKGINFO_VARIABLES();
11c606a6 (kx 2023-04-11 01:18:34 +0300  129) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  130) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  131) void usage()
11c606a6 (kx 2023-04-11 01:18:34 +0300  132) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  133)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  134) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  135)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  136)   fprintf( stdout, "Usage: %s [options] <pkglog>\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  137)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  138)   fprintf( stdout, "Increment or Decrement reference counters in required PKGLOG files\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  139)   fprintf( stdout, "in the  Setup Database packages  directory, which is determined by\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  140)   fprintf( stdout, "option --destination  OR by the directory where the input <pkglog>\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  141)   fprintf( stdout, "file is located. If destination is defined then <pkglog> file name\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  142)   fprintf( stdout, "should be defined relative to destination.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  143)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  144)   fprintf( stdout, "Options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  145)   fprintf( stdout, "  -h,--help                     Display this information.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  146)   fprintf( stdout, "  -v,--version                  Display the version of %s utility.\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  147)   fprintf( stdout, "  -d,--destination=<DIR>        Setup Database packages directory.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  148)   fprintf( stdout, "  -o,--operation=<inc|dec>      Operation: Increment or Decrement.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  149)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  150)   fprintf( stdout, "Parameter:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  151)   fprintf( stdout, "  <pkglog>                      Input PKGLOG file (TEXT format).\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  152)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  153) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  154)   exit( EXIT_FAILURE );
11c606a6 (kx 2023-04-11 01:18:34 +0300  155) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  156) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  157) void to_lowercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  158) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  159)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  160)   while( p && *p ) { int c = *p; *p = tolower( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  161) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  162) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  163) void to_uppercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  164) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  165)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  166)   while( p && *p ) { int c = *p; *p = toupper( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  167) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  168) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  169) void version()
11c606a6 (kx 2023-04-11 01:18:34 +0300  170) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  171)   char *upper = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  172) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  173)   upper = (char *)alloca( strlen( program ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  174) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  175)   strcpy( (char *)upper, (const char *)program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  176)   to_uppercase( upper );
11c606a6 (kx 2023-04-11 01:18:34 +0300  177) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  178)   fprintf( stdout, "%s (%s) %s\n", program, upper, PROGRAM_VERSION );
11c606a6 (kx 2023-04-11 01:18:34 +0300  179) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  180)   fprintf( stdout, "Copyright (C) 2019 Andrey V.Kosteltsev.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  181)   fprintf( stdout, "This is free software.   There is NO warranty; not even\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  182)   fprintf( stdout, "for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  183)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  184) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  185)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  186)   exit( EXIT_SUCCESS );
11c606a6 (kx 2023-04-11 01:18:34 +0300  187) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  188) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  189) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  190) static void remove_trailing_slash( char *dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  191) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  192)   char *s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  193) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  194)   if( !dir || dir[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  195) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  196)   s = dir + strlen( dir ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  197)   while( *s == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  198)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  199)     *s = '\0'; --s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  200)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  201) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  202) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  203) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  204) static int _mkdir_p( const char *dir, const mode_t mode )
11c606a6 (kx 2023-04-11 01:18:34 +0300  205) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  206)   char  *buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  207)   char  *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  208)   struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  209) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  210)   if( !dir ) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  211) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  212)   buf = (char *)alloca( strlen( dir ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  213)   strcpy( buf, dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  214) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  215)   remove_trailing_slash( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  216) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  217)   /* check if path exists and is a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  218)   if( stat( buf, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  219)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  220)     if( S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  221)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  222)       return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  223)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  224)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  225) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  226)   /* mkdir -p */
11c606a6 (kx 2023-04-11 01:18:34 +0300  227)   for( p = buf + 1; *p; ++p )
11c606a6 (kx 2023-04-11 01:18:34 +0300  228)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  229)     if( *p == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  230)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  231)       *p = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  232)       /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  233)       if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  234)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  235)         /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  236)         if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  237)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  238)           return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  239)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  240)       } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  241)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  242)         /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  243)         return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  244)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  245)       *p = '/';
11c606a6 (kx 2023-04-11 01:18:34 +0300  246)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  247)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  248) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  249)   /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  250)   if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  251)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  252)     /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  253)     if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  254)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  255)       return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  256)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  257)   } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  258)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  259)     /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  260)     return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  261)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  262) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  263)   return 0;
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  267) static void _rm_tmpdir( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300  268) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  269)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300  270)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300  271)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  272) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  273)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  274)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300  275) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  276)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  277)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  278)     return; /* stat returns error code; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  279)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  280) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  281)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  282)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  283)     return; /* dirpath is not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  284)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  285) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  286)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  287)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  288)     return; /* Cannot open direcroty; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  289)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  290) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  291)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  292) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  293)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300  294)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  295) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  296)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  297)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300  298) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  299)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300  300)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  301)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  302)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  303)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  304) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  305)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  306)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  307)       if( S_ISDIR(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  308)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  309)         /* recursively remove a nested directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  310)         _rm_tmpdir( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  311)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  312)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  313)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  314)         /* remove a file object */
11c606a6 (kx 2023-04-11 01:18:34 +0300  315)         (void)unlink( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  316)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  317)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  318)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300  319) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  320)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  321) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  322)   /* remove the devastated directory and close the object of this directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  323)   (void)rmdir( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  324) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  325)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  326) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  327) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  328) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  329) static char *_mk_tmpdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  330) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  331)   char   *buf = NULL, *p, *tmp = "/tmp";
11c606a6 (kx 2023-04-11 01:18:34 +0300  332)   size_t  len = 0, size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  333) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  334)   (void)umask( S_IWGRP | S_IWOTH ); /* octal 022 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  335) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  336)   /* Get preferred directory for tmp files */
11c606a6 (kx 2023-04-11 01:18:34 +0300  337)   if( (p = getenv( "TMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  338)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  339)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  340)   else if( (p = getenv( "TEMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  341)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  342)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  343) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  344)   size = strlen( tmp ) + strlen( DISTRO_NAME ) + strlen( program ) + 12;
11c606a6 (kx 2023-04-11 01:18:34 +0300  345) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  346)   buf = (char *)malloc( size );
11c606a6 (kx 2023-04-11 01:18:34 +0300  347)   if( !buf ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  348) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  349)   len = snprintf( buf, size, (const char *)"%s/%s/%s-%.7u", tmp, DISTRO_NAME, program, getpid() );
11c606a6 (kx 2023-04-11 01:18:34 +0300  350)   if( len == 0 || len == size - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  351)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  352)     free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  353)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  354) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  355)   _rm_tmpdir( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  356) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  357)   if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  358)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  359)     return buf;
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)   free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  363) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  364) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  365) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  366) /********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  367)   *requires[] functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  368)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  369) static struct package *create_package( char *name, char *version,
11c606a6 (kx 2023-04-11 01:18:34 +0300  370)                                        char *arch, char *distro_name,
11c606a6 (kx 2023-04-11 01:18:34 +0300  371)                                        char *distro_version )
11c606a6 (kx 2023-04-11 01:18:34 +0300  372) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  373)   struct package *pkg = (struct package *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  374) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  375)   if( !name           || *name           == '\0' ) return pkg;
11c606a6 (kx 2023-04-11 01:18:34 +0300  376)   if( !version        || *version        == '\0' ) return pkg;
11c606a6 (kx 2023-04-11 01:18:34 +0300  377)   if( !arch           || *arch           == '\0' ) return pkg;
11c606a6 (kx 2023-04-11 01:18:34 +0300  378)   if( !distro_name    || *distro_name    == '\0' ) return pkg;
11c606a6 (kx 2023-04-11 01:18:34 +0300  379)   if( !distro_version || *distro_version == '\0' ) return pkg;
11c606a6 (kx 2023-04-11 01:18:34 +0300  380) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  381)   pkg = (struct package *)malloc( sizeof(struct package) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  382)   if( pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300  383)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  384)     pkg->name           = xstrdup( (const char *)name           );
11c606a6 (kx 2023-04-11 01:18:34 +0300  385)     pkg->version        = xstrdup( (const char *)version        );
11c606a6 (kx 2023-04-11 01:18:34 +0300  386)     pkg->arch           = xstrdup( (const char *)arch           );
11c606a6 (kx 2023-04-11 01:18:34 +0300  387)     pkg->distro_name    = xstrdup( (const char *)distro_name    );
11c606a6 (kx 2023-04-11 01:18:34 +0300  388)     pkg->distro_version = xstrdup( (const char *)distro_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300  389)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  390) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  391)   return pkg;
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) static void free_package( struct package *pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300  395) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  396)   if( pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300  397)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  398)     if( pkg->name           ) free( pkg->name           );
11c606a6 (kx 2023-04-11 01:18:34 +0300  399)     if( pkg->version        ) free( pkg->version        );
11c606a6 (kx 2023-04-11 01:18:34 +0300  400)     if( pkg->arch           ) free( pkg->arch           );
11c606a6 (kx 2023-04-11 01:18:34 +0300  401)     if( pkg->distro_name    ) free( pkg->distro_name    );
11c606a6 (kx 2023-04-11 01:18:34 +0300  402)     if( pkg->distro_version ) free( pkg->distro_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300  403) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  404)     free( pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  405)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  406) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  407) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  408) static struct package **create_requires( size_t size )
11c606a6 (kx 2023-04-11 01:18:34 +0300  409) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  410)   struct package **requires = (struct package **)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  411) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  412)   if( size > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  413)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  414)     requires = (struct package **)malloc( size * sizeof(struct package *) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  415)     bzero( (void *)requires, size * sizeof(struct package *) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  416)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  417) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  418)   return( requires );
11c606a6 (kx 2023-04-11 01:18:34 +0300  419) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  420) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  421) static void free_requires( struct package **requires )
11c606a6 (kx 2023-04-11 01:18:34 +0300  422) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  423)   if( requires )
11c606a6 (kx 2023-04-11 01:18:34 +0300  424)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  425)     struct package **ptr = requires;
11c606a6 (kx 2023-04-11 01:18:34 +0300  426) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  427)     while( *ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300  428)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  429)       if( *ptr ) free_package( *ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300  430)       ptr++;
11c606a6 (kx 2023-04-11 01:18:34 +0300  431)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  432)     free( requires );
11c606a6 (kx 2023-04-11 01:18:34 +0300  433)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  434) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  435) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  436)   End of *requires[] functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300  437)  ********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  438) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  439) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  440) /********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  441)   LOCK FILE functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  442)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  443) static int __lock_file( FILE *fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300  444) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  445)   int fd = fileno( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  446) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  447)   if( flock( fd, LOCK_EX ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  448)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  449)     return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  450)     /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  451)       Мы не проверяем errno == EWOULDBLOCK, так какданная ошибка
11c606a6 (kx 2023-04-11 01:18:34 +0300  452)       говорит о том что файл заблокирован другим процессом с флагом
11c606a6 (kx 2023-04-11 01:18:34 +0300  453)       LOCK_NB, а мы не собираемся циклически проверять блокировку.
11c606a6 (kx 2023-04-11 01:18:34 +0300  454)       У нас все просто: процесс просто ждет освобождения дескриптора
11c606a6 (kx 2023-04-11 01:18:34 +0300  455)       и не пытается во время ожидания выполнять другие задачи.
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)   return fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300  459) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  460) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  461) static void __unlock_file( int fd )
11c606a6 (kx 2023-04-11 01:18:34 +0300  462) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  463)   if( fd != -1 ) flock( fd, LOCK_UN );
11c606a6 (kx 2023-04-11 01:18:34 +0300  464)   /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  465)     Здесь, в случае ошибки, мы не будем выводить
11c606a6 (kx 2023-04-11 01:18:34 +0300  466)     никаких сообщений. Наш процесс выполняет простую
11c606a6 (kx 2023-04-11 01:18:34 +0300  467)     атомарную задачу и, наверное, завершится в скором
11c606a6 (kx 2023-04-11 01:18:34 +0300  468)     времени, освободив все дескрипторы.
11c606a6 (kx 2023-04-11 01:18:34 +0300  469)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300  470) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  471) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  472)   End of LOCK FILE functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300  473)  ********************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  474) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  475) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  476) void fatal_error_actions( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  477) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  478)   logmsg( errlog, MSG_NOTICE, "Free resources on FATAL error..." );
11c606a6 (kx 2023-04-11 01:18:34 +0300  479)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  480)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  481) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  482) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  483) void sigint( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  484) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  485)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  486) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  487)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  488)   free_resources();
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) static void set_signal_handlers()
11c606a6 (kx 2023-04-11 01:18:34 +0300  492) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  493)   struct sigaction  sa;
11c606a6 (kx 2023-04-11 01:18:34 +0300  494)   sigset_t          set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  495) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  496)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  497)   sa.sa_handler = sigint;          /* TERM, INT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  498)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  499)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  500)   sigaddset( &set, SIGTERM );
11c606a6 (kx 2023-04-11 01:18:34 +0300  501)   sigaddset( &set, SIGINT );
11c606a6 (kx 2023-04-11 01:18:34 +0300  502)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  503)   sigaction( SIGTERM, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  504)   sigaction( SIGINT, &sa,  NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  505) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  506)   memset( &sa, 0, sizeof( sa ) );  /* ignore SIGPIPE */
11c606a6 (kx 2023-04-11 01:18:34 +0300  507)   sa.sa_handler = SIG_IGN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  508)   sa.sa_flags = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  509)   sigaction( SIGPIPE, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  510) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  511)   /* System V fork+wait does not work if SIGCHLD is ignored */
11c606a6 (kx 2023-04-11 01:18:34 +0300  512)   signal( SIGCHLD, SIG_DFL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  513) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  514) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  515) enum _pkglog_type
11c606a6 (kx 2023-04-11 01:18:34 +0300  516) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  517)   PKGLOG_TEXT = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300  518)   PKGLOG_GZ,
11c606a6 (kx 2023-04-11 01:18:34 +0300  519)   PKGLOG_BZ2,
11c606a6 (kx 2023-04-11 01:18:34 +0300  520)   PKGLOG_XZ,
11c606a6 (kx 2023-04-11 01:18:34 +0300  521)   PKGLOG_TAR,
11c606a6 (kx 2023-04-11 01:18:34 +0300  522) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  523)   PKGLOG_UNKNOWN
11c606a6 (kx 2023-04-11 01:18:34 +0300  524) };
11c606a6 (kx 2023-04-11 01:18:34 +0300  525) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  526) static enum _pkglog_type pkglog_type = PKGLOG_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  527) static char uncompress[2] = { 0, 0 };
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) static enum _pkglog_type check_pkglog_file( const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  531) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  532)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  533)   size_t pkglog_size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  534)   unsigned char buf[8];
11c606a6 (kx 2023-04-11 01:18:34 +0300  535)   int rc, fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300  536) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  537)   /* SIGNATURES: https://www.garykessler.net/library/file_sigs.html */
11c606a6 (kx 2023-04-11 01:18:34 +0300  538) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  539)   uncompress[0] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  540) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  541)   if( stat( fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  542)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  543)     FATAL_ERROR( "Cannot access %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  544)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  545) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  546)   pkglog_size = st.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300  547) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  548)   if( (fd = open( fname, O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  549)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  550)     FATAL_ERROR( "Cannot open %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  551)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  552) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  553)   rc = (int)read( fd, (void *)&buf[0], 7 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  554)   if( rc != 7 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  555)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  556)     FATAL_ERROR( "Unknown type of input file %s", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  557)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  558)   buf[7] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  559) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  560)   /* TEXT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  561)   if( !strncmp( (const char *)&buf[0], "PACKAGE", 7 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  562)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  563)     close( fd ); return PKGLOG_TEXT;
11c606a6 (kx 2023-04-11 01:18:34 +0300  564)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  565) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  566)   /* GZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  567)   if( buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x08 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  568)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  569)     uncompress[0] = 'x';
11c606a6 (kx 2023-04-11 01:18:34 +0300  570)     close( fd ); return PKGLOG_GZ;
11c606a6 (kx 2023-04-11 01:18:34 +0300  571)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  572) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  573)   /* BZ2 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  574)   if( buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  575)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  576)     uncompress[0] = 'j';
11c606a6 (kx 2023-04-11 01:18:34 +0300  577)     close( fd ); return PKGLOG_BZ2;
11c606a6 (kx 2023-04-11 01:18:34 +0300  578)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  579) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  580)   /* XZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  581)   if( buf[0] == 0xFD && buf[1] == 0x37 && buf[2] == 0x7A &&
11c606a6 (kx 2023-04-11 01:18:34 +0300  582)       buf[3] == 0x58 && buf[4] == 0x5A && buf[5] == 0x00   )
11c606a6 (kx 2023-04-11 01:18:34 +0300  583)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  584)     uncompress[0] = 'J';
11c606a6 (kx 2023-04-11 01:18:34 +0300  585)     close( fd ); return PKGLOG_XZ;
11c606a6 (kx 2023-04-11 01:18:34 +0300  586)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  587) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  588)   if( pkglog_size > 262 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  589)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  590)     if( lseek( fd, 257, SEEK_SET ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  591)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  592)       FATAL_ERROR( "Cannot check signature of %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  593)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  594)     rc = (int)read( fd, &buf[0], 5 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  595)     if( rc != 5 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  596)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  597)       FATAL_ERROR( "Cannot read signature of %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  598)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  599)     /* TAR */
11c606a6 (kx 2023-04-11 01:18:34 +0300  600)     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  601)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  602)       close( fd ); return PKGLOG_TAR;
11c606a6 (kx 2023-04-11 01:18:34 +0300  603)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  604)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  605) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  606)   close( fd ); return PKGLOG_UNKNOWN;
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) void get_args( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300  611) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  612)   const char* short_options = "hvd:o:";
11c606a6 (kx 2023-04-11 01:18:34 +0300  613) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  614)   const struct option long_options[] =
11c606a6 (kx 2023-04-11 01:18:34 +0300  615)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  616)     { "help",        no_argument,       NULL, 'h' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  617)     { "version",     no_argument,       NULL, 'v' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  618)     { "destination", required_argument, NULL, 'd' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  619)     { "operation",   required_argument, NULL, 'o' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  620)     { NULL,          0,                 NULL,  0  }
11c606a6 (kx 2023-04-11 01:18:34 +0300  621)   };
11c606a6 (kx 2023-04-11 01:18:34 +0300  622) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  623)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  624)   int option_index = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  625) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  626)   while( (ret = getopt_long( argc, argv, short_options, long_options, &option_index )) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  627)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  628)     switch( ret )
11c606a6 (kx 2023-04-11 01:18:34 +0300  629)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  630)       case 'h':
11c606a6 (kx 2023-04-11 01:18:34 +0300  631)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  632)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  633)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  634)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  635)       case 'v':
11c606a6 (kx 2023-04-11 01:18:34 +0300  636)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  637)         version();
11c606a6 (kx 2023-04-11 01:18:34 +0300  638)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  639)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  640) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  641)       case 'd':
11c606a6 (kx 2023-04-11 01:18:34 +0300  642)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  643)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  644)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  645)           destination = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  646)           remove_trailing_slash( destination );
11c606a6 (kx 2023-04-11 01:18:34 +0300  647)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  648)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  649)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  650)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  651)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  652)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  653)       case 'o':
11c606a6 (kx 2023-04-11 01:18:34 +0300  654)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  655)         operation = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  656)         to_lowercase( operation );
11c606a6 (kx 2023-04-11 01:18:34 +0300  657)         if( strcmp( operation, "inc" ) != 0 && strcmp( operation, "dec" ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  658)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  659)           ERROR( "Invalid '%s' operation requested", operation );
11c606a6 (kx 2023-04-11 01:18:34 +0300  660)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  661)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  662)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  663)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  664) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  665)       case '?': default:
11c606a6 (kx 2023-04-11 01:18:34 +0300  666)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  667)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  668)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  669)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  670)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  671)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  672) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  673) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  674)   if( operation == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  675)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  676)     usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  677)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  678) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  679)   /* last command line argument is the LOGFILE */
11c606a6 (kx 2023-04-11 01:18:34 +0300  680)   if( optind < argc )
11c606a6 (kx 2023-04-11 01:18:34 +0300  681)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  682)     char *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  683) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  684)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  685)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  686) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  687)     if( destination == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  688)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  689)       pkglog_fname = xstrdup( (const char *)argv[optind++] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  690)       if( pkglog_fname == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  691)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  692)         FATAL_ERROR( "Unable to set input PKGLOG file name" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  693)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  694) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  695)       bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  696)       (void)sprintf( buf, "%s", pkglog_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  697)       destination  = xstrdup( (const char *)dirname( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  698)       if( destination == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  699)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  700)         FATAL_ERROR( "Unable to set destination directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  701)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  702) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  703)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  704)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  705)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  706)       bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  707)       (void)sprintf( buf, "%s/%s", destination, argv[optind++] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  708)       pkglog_fname = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  709)       if( pkglog_fname == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  710)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  711)         FATAL_ERROR( "Unable to set inpit PKGLOG file name" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  712)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  713)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  714) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  715)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  716) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  717)     pkglog_type = check_pkglog_file( (const char *)pkglog_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  718)     if( pkglog_type != PKGLOG_TEXT )
11c606a6 (kx 2023-04-11 01:18:34 +0300  719)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  720)       ERROR( "%s: Unknown input file format", basename( pkglog_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  721)       usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  722)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  723) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  724)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  725)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  726)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  727)     usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  728)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  729) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  730) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  731) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  732) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  733)   Especialy for pkginfo lines.
11c606a6 (kx 2023-04-11 01:18:34 +0300  734)   Remove leading spaces and take non-space characters only:
11c606a6 (kx 2023-04-11 01:18:34 +0300  735)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  736) static char *skip_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  737) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  738)   char *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  739) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  740)   if( !s || *s == '\0' ) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  741) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  742)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  743) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  744)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  745)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  746) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  747)   if( *p == '\0' ) return (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  748) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  749)   return( xstrdup( (const char *)p ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  750) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  751) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  752) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  753) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  754)   remove spaces at end of line:
11c606a6 (kx 2023-04-11 01:18:34 +0300  755)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  756) static void skip_eol_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  757) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  758)   char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  759) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  760)   if( !s || *s == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  761) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  762)   p = s + strlen( s ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  763)   while( isspace( *p ) ) { *p-- = '\0'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  764) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  765) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  766) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  767) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  768) int get_pkginfo()
11c606a6 (kx 2023-04-11 01:18:34 +0300  769) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  770)   int   ret = -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  771)   FILE *log = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  772) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  773)   if( pkglog_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  774)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  775)     log = fopen( (const char *)pkglog_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  776)     if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300  777)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  778)       FATAL_ERROR( "Cannot open %s file", pkglog_fname );
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  782)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  783)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  784)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  785)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  786) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  787)     char    *pkgname_pattern = "PACKAGE NAME:",
11c606a6 (kx 2023-04-11 01:18:34 +0300  788)              *pkgver_pattern = "PACKAGE VERSION:",
11c606a6 (kx 2023-04-11 01:18:34 +0300  789)               *group_pattern = "GROUP:",
11c606a6 (kx 2023-04-11 01:18:34 +0300  790)                *arch_pattern = "ARCH:",
11c606a6 (kx 2023-04-11 01:18:34 +0300  791)          *distroname_pattern = "DISTRO:",
11c606a6 (kx 2023-04-11 01:18:34 +0300  792)           *distrover_pattern = "DISTRO VERSION:";
11c606a6 (kx 2023-04-11 01:18:34 +0300  793) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  794)     int last = 10; /* read first 10 lines only */
11c606a6 (kx 2023-04-11 01:18:34 +0300  795) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  796)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  797)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300  798)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  799)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  800)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  801) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  802)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  803) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  804)     if( last )
11c606a6 (kx 2023-04-11 01:18:34 +0300  805)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  806)       int n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  807) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  808)       while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  809)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  810)         char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  811) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  812)         ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  813)         skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300  814) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  815)         if( (match = strstr( ln, pkgname_pattern )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300  816)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  817)           pkgname = skip_spaces( ln + strlen( pkgname_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  818)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  819)         if( (match = strstr( ln, pkgver_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300  820)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  821)           pkgver = skip_spaces( ln + strlen( pkgver_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  822)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  823)         if( (match = strstr( ln, arch_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300  824)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  825)           arch = skip_spaces( ln + strlen( arch_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  826)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  827)         if( (match = strstr( ln, distroname_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300  828)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  829)           distroname = skip_spaces( ln + strlen( distroname_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  830)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  831)         if( (match = strstr( ln, distrover_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300  832)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  833)           distrover = skip_spaces( ln + strlen( distrover_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  834)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  835)         if( (match = strstr( ln, group_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300  836)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  837)           group = skip_spaces( ln + strlen( group_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  838)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  839) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  840)         if( n < last ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300  841)         else break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  842) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  843)       } /* End of while() */
11c606a6 (kx 2023-04-11 01:18:34 +0300  844) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  845)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  846) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  847)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300  848) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  849)     if(    pkgname == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  850)     if(     pkgver == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  851)     if(       arch == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  852)     if( distroname == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  853)     if(  distrover == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  854)     /* group can be equal to NULL */
11c606a6 (kx 2023-04-11 01:18:34 +0300  855) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  856)     fclose( log );
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)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300  860) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  861) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  862) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  863) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  864) int get_references_section( int *start, int *stop, unsigned int *cnt, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300  865) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  866)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  867) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  868)   if( !start || !stop || !cnt ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  869) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  870)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  871)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  872)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  873)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  874) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  875)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  876)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300  877)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  878)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  879)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  880) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  881)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  882) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  883)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  884)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  885)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  886) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  887)       if( (match = strstr( ln, "REFERENCE COUNTER:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300  888)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  889)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  890)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300  891) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  892)         /* Get reference counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300  893)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  894)           unsigned int count;
11c606a6 (kx 2023-04-11 01:18:34 +0300  895)           int          rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300  896) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  897)           ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  898)           skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300  899) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  900)           rc = sscanf( ln, "REFERENCE COUNTER: %u", &count );
11c606a6 (kx 2023-04-11 01:18:34 +0300  901)           if( rc == 1 && cnt != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  902)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300  903)             *cnt = count;
11c606a6 (kx 2023-04-11 01:18:34 +0300  904)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300  905)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  906)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  907)       if( (match = strstr( ln, "REQUIRES:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300  908)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  909)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  910)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300  911)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  912) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  913)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  914)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  915) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  916)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300  917) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  918)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300  919) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  920)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300  921)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  922) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  923)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300  924) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  925) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  926) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  927) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  928) int get_requires_section( int *start, int *stop, const char *log_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  929) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  930)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  931) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  932)   FILE *log = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  933) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  934)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  935) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  936)   if( log_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  937)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  938)     log = fopen( (const char *)log_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  939)     if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300  940)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  941)       return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  942)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  943)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  944) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  945)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  946)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  947)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  948)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  949) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  950)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  951)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300  952)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  953)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  954)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  955) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  956)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  957) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  958)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  959)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  960)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  961) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  962)       if( (match = strstr( ln, "REQUIRES:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300  963)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  964)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  965)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300  966)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  967)       if( (match = strstr( ln, "PACKAGE DESCRIPTION:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300  968)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  969)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  970)         ++found;
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)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  974)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  975) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  976)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300  977) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  978)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300  979) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  980)     fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300  981)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  982) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  983)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300  984) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  985) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  986) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  987) int get_description_section( int *start, int *stop, const char *log_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  988) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  989)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  990) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  991)   FILE *log = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  992) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  993)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  994) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  995)   if( log_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  996)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  997)     log = fopen( (const char *)log_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  998)     if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300  999)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1000)       return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1001)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1002)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1003) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1004)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1005)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1006)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1007)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1008) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1009)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1010)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1011)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1012)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1013)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1014) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1015)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1016) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1017)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1018)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1019)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1020) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1021)       if( (match = strstr( ln, "PACKAGE DESCRIPTION:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1022)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1023)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1024)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1025)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1026)       if( (match = strstr( ln, "RESTORE LINKS:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1027)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1028)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1029)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1030)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1031) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1032)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1033)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1034) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1035)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1036) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1037)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1038) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1039)     fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1040)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1041) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1042)   return( ret );
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1046) int get_restore_links_section( int *start, int *stop, const char *log_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1047) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1048)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1049) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1050)   FILE *log = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1051) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1052)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1053) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1054)   if( log_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1055)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1056)     log = fopen( (const char *)log_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1057)     if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1058)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1059)       return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1060)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1061)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1062) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1063)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1064)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1065)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1066)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1067) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1068)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1069)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1070)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1071)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1072)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1073) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1074)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1075) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1076)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1077)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1078)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1079) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1080)       if( (match = strstr( ln, "RESTORE LINKS:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1081)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1082)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1083)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1084)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1085)       if( (match = strstr( ln, "INSTALL SCRIPT:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1086)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1087)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1088)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1089)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1090) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1091)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1092)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1093) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1094)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1095) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1096)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1097) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1098)     fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1099)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1100) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1101)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1102) }
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) int get_install_script_section( int *start, int *stop, const char *log_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1106) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1107)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1108) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1109)   FILE *log = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1110) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1111)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1112) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1113)   if( log_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1114)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1115)     log = fopen( (const char *)log_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1116)     if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1117)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1118)       return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1119)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1120)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1121) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1122)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1123)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1124)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1125)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1126) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1127)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1128)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1129)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1130)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1131)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1132) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1133)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1134) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1135)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1136)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1137)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1138) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1139)       if( (match = strstr( ln, "INSTALL SCRIPT:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1140)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1141)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1142)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1143)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1144)       if( (match = strstr( ln, "FILE LIST:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1145)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1146)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1147)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1148)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1149) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1150)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1151)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1152) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1153)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1154) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1155)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1156) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1157)     fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1158)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1159) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1160)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1161) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1162) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1163) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1164) int get_file_list_section( int *start, int *stop, const char *log_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1165) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1166)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1167) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1168)   FILE *log = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1169) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1170)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1171) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1172)   if( log_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1173)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1174)     log = fopen( (const char *)log_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1175)     if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1176)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1177)       return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1178)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1179)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1180) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1181)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1182)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1183)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1184)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1185) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1186)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1187)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1188)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1189)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1190)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1191) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1192)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1193)     *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1194) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1195)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1196)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1197)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1198) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1199)       if( (match = strstr( ln, "FILE LIST:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1200)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1201)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1202)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1203)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1204) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1205)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1206)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1207) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1208)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1209) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1210)     ret = ( found == 1 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1211) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1212)     fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1213)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1214) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1215)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1216) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1217) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1218) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1219) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1220) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1221) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1222)   get_requires():
11c606a6 (kx 2023-04-11 01:18:34 +0300 1223)   --------------
11c606a6 (kx 2023-04-11 01:18:34 +0300 1224)     if( success ) - returns number of requires
11c606a6 (kx 2023-04-11 01:18:34 +0300 1225)     if(   error ) - returns -1
11c606a6 (kx 2023-04-11 01:18:34 +0300 1226)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1227) int get_requires( const char *requires, const char *log_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1228) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1229)   int   ret = -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1230)   FILE *req = NULL, *log = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1231) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1232)   int   start = 0, stop  = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1233) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1234)   if( get_requires_section( &start, &stop, log_fname ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1235)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1236)     return ret;
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)   if( log_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1240)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1241)     log = fopen( (const char *)log_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1242)     if( ! log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1243)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1244)       return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1245)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1246)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1247) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1248)   if( requires != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1249)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1250)     req = fopen( (const char *)requires, "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1251)     if( ! req )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1252)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1253)       return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1254)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1255)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1256) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1257)   /* get PKGLOG sections */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1258)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1259)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1260)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1261) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1262)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1263)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1264)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1265)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1266)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1267) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1268)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1269) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1270)     if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1271)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1272)       int n = 1, lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1273) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1274)       while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1275)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1276)         ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1277)         skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1278) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1279)         if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1280)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1281)           fprintf( req, "%s\n", ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1282)           ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1283)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1284)         ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1285)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1286) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1287)       ret = lines; /* number of lines in the LIST */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1288)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1289) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1290)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1291) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1292)     fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1293)     fflush( req ); fclose( req );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1294)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1295) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1296)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1297) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1298) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1299) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1300) struct package **read_requires( const char *fname, int n )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1301) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1302)   struct package **requires = (struct package **)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1303)   struct package **ptr      = (struct package **)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1304) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1305)   FILE  *file;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1306) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1307)   if( ! fname ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1308) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1309)   requires = create_requires( n + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1310)   if( requires )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1311)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1312)     int   i;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1313)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1314)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1315) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1316)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1317)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1318)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1319)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1320)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1321) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1322)     struct package *package;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1323) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1324)     file = fopen( fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1325)     if( !file )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1326)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1327)       free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1328)       free_requires( requires );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1329)       return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1330)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1331) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1332)     ptr = requires;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1333)     for( i = 0; i < n; ++i )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1334)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1335)       if( (ln = fgets( line, PATH_MAX, file )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1336)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1337)         char *d, *name, *version;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1338) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1339)         ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1340)         skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1341) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1342)         /* сut 'name=version' by delimiter '=': */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1343)         d = index( ln, '=' ); *d = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1344)         version = ++d; name = ln;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1345) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1346)         package = create_package( name, version, arch, DISTRO_NAME, DISTRO_VERSION );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1347)         if( package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1348)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1349)           *ptr = package;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1350)           ptr++;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1351)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1352)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1353)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1354)     *ptr = (struct package *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1355) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1356)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1357)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1358) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1359)   return requires;
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) int find_requires( char *pname, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1363) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1364)   char *name = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1365)   char *buf  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1366) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1367)   struct package **ptr = requires;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1368) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1369)   buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1370) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1371)   if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1372) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1373)   while( *ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1374)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1375)     if( grp && *grp != '\0' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1376)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1377)       char   *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1378)       size_t  len = strlen( (*ptr)->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1379) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1380)       if( (p = strstr( (*ptr)->name, grp )) && (p == (*ptr)->name) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1381)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1382)         /* if group is equal to required package's group then remove group from the name */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1383)         name = alloca( len + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1384)         strcpy( name, (const char *)(*ptr)->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1385) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1386)         name = index( name, '/' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1387)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1388)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1389)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1390)         /* if group is not equal to required package's group then add group to the name */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1391)         name = alloca( len + strlen( grp ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1392)         (void)sprintf( name, "%s/%s", grp, (const char *)(*ptr)->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1393)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1394)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1395)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1396)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1397)       name = (*ptr)->name;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1398)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1399) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1400)     (void)sprintf( buf, "%s-%s-%s-%s-%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1401)                          name, (*ptr)->version, (*ptr)->arch,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1402)                          (*ptr)->distro_name, (*ptr)->distro_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1403) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1404)     if( ! strcmp( buf, pname ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1405)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1406)       free( buf ); return 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1407)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1408)     ptr++;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1409)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1410) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1411)   free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1412) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1413)   return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1414) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1415) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1416) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1417) int save_tmp_head( FILE *log, int stop, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1418) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1419)   FILE *fp;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1420)   int   ret = -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1421) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1422)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1423)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1424)   int   n = 1, lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1425) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1426)   if( !stop || !log || !fname || *fname == '\0' ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1427) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1428)   fp = fopen( fname, "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1429)   if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1430)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1431)     return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1432)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1433) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1434)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1435)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1436)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1437)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1438)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1439) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1440)   ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1441) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1442)   while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1443)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1444)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1445)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1446) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1447)     if( n < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1448)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1449)       fprintf( fp, "%s\n", ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1450)       ++n; ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1451)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1452)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1453)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1454)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1455) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1456)   ret = lines; /* number of lines in the HEAD */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1457) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1458)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1459) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1460)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1461)   fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1462) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1463)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1464) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1465) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1466) int save_tmp_tail( FILE *log, int start, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1467) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1468)   FILE *fp;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1469)   int   ret = -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1470) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1471)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1472)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1473)   int   n = 1, lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1474) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1475)   if( !start || !log || !fname || *fname == '\0' ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1476) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1477)   fp = fopen( fname, "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1478)   if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1479)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1480)     return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1481)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1482) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1483)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1484)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1485)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1486)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1487)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1488) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1489)   ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1490) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1491)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1492) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1493)   while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1494)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1495)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1496)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1497) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1498)     fprintf( fp, "%s\n", ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1499)     ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1500)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1501) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1502)   ret = lines; /* number of lines in the TAIL */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1503) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1504)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1505) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1506)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1507)   fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1508) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1509)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1510) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1511) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1512) int write_tmp_part( FILE *log, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1513) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1514)   FILE *fp;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1515)   int   ret = -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1516) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1517)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1518)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1519)   int   lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1520) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1521)   if( !log || !fname || *fname == '\0' ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1522) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1523)   fp = fopen( fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1524)   if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1525)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1526)     return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1527)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1528) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1529)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1530)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1531)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1532)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1533)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1534) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1535)   ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1536) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1537)   while( (ln = fgets( line, PATH_MAX, fp )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1538)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1539)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1540)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1541) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1542)     fprintf( log, "%s\n", ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1543)     ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1544)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1545) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1546)   ret = lines; /* number of written lines */
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)   fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1551) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1552)   return ret;
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1556) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1557) static char **create_references( size_t size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1558) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1559)   char **references = (char **)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1560) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1561)   if( size > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1562)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1563)     references = (char **)malloc( size * sizeof(char *) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1564)     bzero( (void *)references, size * sizeof(char *) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1565)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1566) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1567)   return( references );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1568) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1569) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1570) static void free_references( char **references )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1571) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1572)   if( references )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1573)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1574)     char **ptr = references;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1575) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1576)     while( *ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1577)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1578)       if( *ptr ) free( *ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1579)       ptr++;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1580)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1581)     free( references );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1582)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1583) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1584) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1585) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1586) static char **get_references( FILE *log, int start, unsigned int *cnt, char *grp, char *name, char *version )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1587) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1588)   char **refs = (char **)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1589)   char **ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1590) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1591)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1592)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1593)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1594) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1595)   size_t len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1596) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1597)   unsigned int counter, pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1598) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1599)   char *pkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1600) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1601)   if( !log || !cnt || *cnt == 0 || !name || !version ) return refs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1602) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1603)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1604)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1605)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1606)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1607)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1608) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1609)   pkg = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1610)   if( !pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1611)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1612)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1613)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1614) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1615)   counter = *cnt;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1616) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1617)   if( grp && *grp != '\0' ) { (void)sprintf( pkg, "%s/%s=", grp, name ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1618)   else                      { (void)sprintf( pkg, "%s=", name );         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1619) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1620)   len = strlen( pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1621) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1622)   refs = ptr = create_references( counter + 1 ); /* null terminated char *references[] */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1623) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1624)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1625) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1626)   n = 0; pkgs = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1627)   while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1628)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1629)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1630)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1631) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1632)     if( strstr( ln, "REQUIRES:" ) ) break; /* if cnt greater than real number of references */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1633) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1634)     if( n < counter )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1635)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1636)       if( strncmp( ln, pkg, len ) ) /* always remove 'name=version' from list */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1637)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1638)         if( refs )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1639)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1640)           *ptr = xstrdup( (const char *)ln ); ++ptr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1641)           *ptr = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1642)           ++pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1643)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1644)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1645)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1646)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1647)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1648)       break;
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)   free( line ); free( pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1652) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1653)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1654) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1655)   if( pkgs == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1656)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1657)     free_references( refs );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1658)     refs = (char **)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1659)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1660) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1661)   *cnt = pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1662) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1663)   return refs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1664) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1665) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1666) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1667) static void _change_references( char *grp, char *name, char *version, const char *log_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1668) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1669)   int    fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1670)   FILE  *log;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1671) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1672)   char  *head_fname = NULL, *tail_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1673)   int    head_lines, tail_lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1674) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1675)   int          rc, start, stop;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1676)   unsigned int counter;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1677) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1678)   int    inc = ( strcmp( operation, "inc" ) == 0 ) ? 1 : 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1679) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1680)   char **references = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1681) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1682)   if( !name || !version || log_fname == NULL ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1683)   if( check_pkglog_file( log_fname ) != PKGLOG_TEXT ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1684) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1685)   log = fopen( (const char *)log_fname, "r+" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1686)   if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1687)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1688)     ERROR( "Cannot access %s file: %s", log_fname, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1689)     return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1690)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1691) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1692)   fd = __lock_file( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1693) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1694)   rc = get_references_section( &start, &stop, &counter, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1695)   if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1696)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1697)     ERROR( "%s: PKGLOG doesn't contains REFERENCE COUNTER section", log_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1698)     __unlock_file( fd ); fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1699)     return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1700)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1701) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1702)   head_fname = (char *)alloca( strlen( tmpdir ) + 7 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1703)   (void)sprintf( head_fname, "%s/.HEAD", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1704) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1705)   tail_fname = (char *)alloca( strlen( tmpdir ) + 7 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1706)   (void)sprintf( tail_fname, "%s/.TAIL", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1707) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1708)   head_lines = save_tmp_head( log, start, (const char *)head_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1709)   tail_lines = save_tmp_tail( log, stop - 1, (const char *)tail_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1710) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1711)   if( head_lines < 10 && tail_lines < 12 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1712)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1713)     ERROR( "%s: Invalid PKGLOG file", log_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1714)     __unlock_file( fd ); fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1715)     return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1716)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1717) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1718)   references = get_references( log, start, &counter, grp, name, version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1719) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1720)   if( ftruncate( fd, 0 ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1721)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1722)     ERROR( "Cannot change REFERENCE COUNTER in the %s file: %s", log_fname, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1723)     free_references( references );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1724)     __unlock_file( fd ); fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1725)     return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1726)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1727) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1728)   head_lines = write_tmp_part( log, (const char *)head_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1729) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1730)   if( inc ) ++counter;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1731)   fprintf( log, "REFERENCE COUNTER: %u\n", counter );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1732)   if( inc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1733)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1734)     if( grp && *grp != '\0' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1735)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1736)       fprintf( log, "%s/%s=%s\n", grp, name, version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1737)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1738)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1739)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1740)       fprintf( log, "%s=%s\n", name, version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1741)     }
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)   if( references )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1745)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1746)     char **ptr = references;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1747) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1748)     while( *ptr )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1749)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1750)       if( *ptr ) fprintf( log, "%s\n", *ptr );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1751)       ptr++;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1752)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1753) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1754)     free_references( references );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1755)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1756) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1757)   tail_lines = write_tmp_part( log, (const char *)tail_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1758) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1759)   __unlock_file( fd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1760)   fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1761) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1762) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1763) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1764) static void _search_required_packages( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1765) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1766)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1767)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1768)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1769) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1770)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1771)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1772) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1773)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1774)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1775)     FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1776)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1777) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1778)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1779)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1780)     FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1781)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1782) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1783)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1784)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1785)     FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1786)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1787) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1788)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1789) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1790)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1791)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1792)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1793)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1794) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1795)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1796)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1797) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1798)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1799)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1800)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1801) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1802)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1803)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1804)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1805)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1806)         if( find_requires( entry->d_name, grp ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1807)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1808)           _change_references( group, pkgname, pkgver, (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1809)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1810)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1811)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1812)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1813)         _search_required_packages( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1814)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1815)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1816)       /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1817) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1818)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1819) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1820)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1821) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1822) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1823) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1824) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1825) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1826) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1827)   Get directory where this program is placed:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1828)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1829) char *get_selfdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1830) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1831)   char    *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1832)   ssize_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1833) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1834)   buf = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1835)   if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1836)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1837)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1838)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1839) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1840)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1841)   len = readlink( "/proc/self/exe", buf, (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1842)   if( len > 0 && len < PATH_MAX )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1843)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1844)     char *p = xstrdup( (const char *)dirname( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1845)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1846)     return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1847)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1848)   FATAL_ERROR( "Cannot determine self directory. Please mount /proc filesystem" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1849) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1850) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1851) void set_stack_size( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1852) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1853)   const rlim_t   stack_size = 16 * 1024 * 1024; /* min stack size = 16 MB */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1854)   struct rlimit  rl;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1855)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1856) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1857)   ret = getrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1858)   if( ret == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1859)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1860)     if( rl.rlim_cur < stack_size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1861)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1862)       rl.rlim_cur = stack_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1863)       ret = setrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1864)       if( ret != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1865)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1866)         fprintf(stderr, "setrlimit returned result = %d\n", ret);
11c606a6 (kx 2023-04-11 01:18:34 +0300 1867)         FATAL_ERROR( "Cannot set stack size" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1868)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1869)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1870)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1871) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1872) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1873) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1874) int main( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1875) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1876)   gid_t  gid;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1877) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1878)   int    ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1879) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1880)   set_signal_handlers();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1881) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1882)   gid = getgid();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1883)   setgroups( 1, &gid );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1884) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1885)   fatal_error_hook = fatal_error_actions;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1886) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1887)   selfdir = get_selfdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1888) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1889)   errlog = stderr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1890) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1891)   program = basename( argv[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1892)   get_args( argc, argv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1893) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1894)   /* set_stack_size(); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1895) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1896)   exit_status = get_pkginfo();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1897)   if( exit_status != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1898)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1899)     FATAL_ERROR( "%s: Invalid input PKGLOG file", basename( pkglog_fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1900)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1901) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1902)   tmpdir = _mk_tmpdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1903)   if( !tmpdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1904)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1905)     FATAL_ERROR( "Cannot create temporary directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1906)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1907)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1908)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1909)     char *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1910) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1911)     buf = (char *)malloc( (size_t)strlen( tmpdir ) + 11 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1912)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1913) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1914)     (void)sprintf( (char *)&buf[0], "%s/.REQUIRES", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1915)     requires_fname = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1916)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1917)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1918) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1919)   /*******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1920)     Getting REQUIRES:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1921)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1922)   if( (ret = get_requires( (const char *)requires_fname, (const char *)pkglog_fname )) > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1923)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1924)     /* We have non-empty list of REQUIRES in the 'requires_fname' file */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1925)     requires = read_requires( (const char *)requires_fname, ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1926)     _search_required_packages( (const char *)destination, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1927)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1928) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1929)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1930)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1931) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1932)   exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1933) }