Radix cross Linux package tools

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

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