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-requires"
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, *pkg_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   exit_status = EXIT_SUCCESS; /* errors counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300   73) char *selfdir     = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300   74) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   75) int __done = 0, __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300   76) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   77) enum _input_type {
11c606a6 (kx 2023-04-11 01:18:34 +0300   78)   IFMT_PKG = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300   79)   IFMT_LOG,
11c606a6 (kx 2023-04-11 01:18:34 +0300   80) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   81)   IFMT_UNKNOWN
11c606a6 (kx 2023-04-11 01:18:34 +0300   82) } input_format = IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300   83) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   84) enum _priority priority = REQUIRED;
11c606a6 (kx 2023-04-11 01:18:34 +0300   85) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   86) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   87) void free_resources()
11c606a6 (kx 2023-04-11 01:18:34 +0300   88) {
11c606a6 (kx 2023-04-11 01:18:34 +0300   89)   if( root )         { free( root );         root         = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300   90)   if( pkgs_path )    { free( pkgs_path );    pkgs_path    = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300   91)   if( pkg_fname )    { free( pkg_fname );    pkg_fname    = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300   92) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   93)   if( selfdir )      { free( selfdir );      selfdir      = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300   94) 
11c606a6 (kx 2023-04-11 01:18:34 +0300   95)   free_tarballs();
11c606a6 (kx 2023-04-11 01:18:34 +0300   96)   free_packages();
11c606a6 (kx 2023-04-11 01:18:34 +0300   97)   free_srcpkgs();
11c606a6 (kx 2023-04-11 01:18:34 +0300   98) }
11c606a6 (kx 2023-04-11 01:18:34 +0300   99) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  100) void usage()
11c606a6 (kx 2023-04-11 01:18:34 +0300  101) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  102)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  103) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  104)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  105)   fprintf( stdout, "Usage: %s [options] <package|pkglog>\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  106)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  107)   fprintf( stdout, "This utility checks  if packages required by requested package are\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  108)   fprintf( stdout, "instaled.  If there are non-installed packages or packages have to\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  109)   fprintf( stdout, "updated  then the list of  non-installed packages is output to the\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  110)   fprintf( stdout, "standard error stream.\n" );
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, "Options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  113)   fprintf( stdout, "  -h,--help                     Display this information.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  114)   fprintf( stdout, "  -v,--version                  Display the version of %s utility.\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  115)   fprintf( stdout, "  -r,--root=<DIR>               Target rootfs path.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  116) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  117)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  118)   fprintf( stdout, "Parameter:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  119)   fprintf( stdout, "  <package|pkglog>              The PACKAGE tarball or PKGLOG.\n"  );
11c606a6 (kx 2023-04-11 01:18:34 +0300  120)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  121)   fprintf( stdout, "The list of required packages prints out in following format:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  122)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  123)   fprintf( stdout, "app/attr:2.4.47:PROCEDURE\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  124)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  125)   fprintf( stdout, "where PROCEDURE is:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  126)   fprintf( stdout, "  install  -  package should be installed; or\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  127)   fprintf( stdout, "  update   -  the old version of required package already instaled\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  128)   fprintf( stdout, "              but should be  updated  to the new version presented\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  129)   fprintf( stdout, "              between colon characters.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  130)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  131) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  132)   exit( EXIT_FAILURE );
11c606a6 (kx 2023-04-11 01:18:34 +0300  133) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  134) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  135) void to_lowercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  136) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  137)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  138)   while( p && *p ) { int c = *p; *p = tolower( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  139) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  140) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  141) void to_uppercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  142) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  143)   char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  144)   while( p && *p ) { int c = *p; *p = toupper( c ); ++p; }
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) void version()
11c606a6 (kx 2023-04-11 01:18:34 +0300  148) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  149)   char *upper = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  150) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  151)   upper = (char *)alloca( strlen( program ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  152) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  153)   strcpy( (char *)upper, (const char *)program );
11c606a6 (kx 2023-04-11 01:18:34 +0300  154)   to_uppercase( upper );
11c606a6 (kx 2023-04-11 01:18:34 +0300  155) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  156)   fprintf( stdout, "%s (%s) %s\n", program, upper, PROGRAM_VERSION );
11c606a6 (kx 2023-04-11 01:18:34 +0300  157) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  158)   fprintf( stdout, "Copyright (C) 2019 Andrey V.Kosteltsev.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  159)   fprintf( stdout, "This is free software.   There is NO warranty; not even\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  160)   fprintf( stdout, "for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  161)   fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  162) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  163)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  164)   exit( EXIT_SUCCESS );
11c606a6 (kx 2023-04-11 01:18:34 +0300  165) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  166) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  167) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  168) static void remove_trailing_slash( char *dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300  169) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  170)   char *s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  171) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  172)   if( !dir || dir[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  173) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  174)   s = dir + strlen( dir ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  175)   while( *s == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  176)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  177)     *s = '\0'; --s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  178)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  179) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  180) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  181) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  182) static int _mkdir_p( const char *dir, const mode_t mode )
11c606a6 (kx 2023-04-11 01:18:34 +0300  183) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  184)   char  *buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  185)   char  *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  186)   struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  187) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  188)   if( !dir ) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  189) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  190)   buf = (char *)alloca( strlen( dir ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  191)   strcpy( buf, dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  192) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  193)   remove_trailing_slash( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  194) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  195)   /* check if path exists and is a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  196)   if( stat( buf, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  197)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  198)     if( S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  199)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  200)       return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  201)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  202)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  203) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  204)   /* mkdir -p */
11c606a6 (kx 2023-04-11 01:18:34 +0300  205)   for( p = buf + 1; *p; ++p )
11c606a6 (kx 2023-04-11 01:18:34 +0300  206)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  207)     if( *p == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  208)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  209)       *p = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  210)       /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  211)       if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  212)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  213)         /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  214)         if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  215)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  216)           return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  217)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  218)       } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  219)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  220)         /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  221)         return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  222)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  223)       *p = '/';
11c606a6 (kx 2023-04-11 01:18:34 +0300  224)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  225)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  226) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  227)   /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300  228)   if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  229)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  230)     /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  231)     if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  232)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  233)       return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  234)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  235)   } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  236)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  237)     /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  238)     return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  239)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  240) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  241)   return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  242) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  243) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  244) static void _rm_tmpdir( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300  245) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  246)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300  247)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300  248)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  249) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  250)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  251)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300  252) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  253)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  254)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  255)     return; /* stat returns error code; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  256)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  257) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  258)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  259)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  260)     return; /* dirpath is not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  261)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  262) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  263)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  264)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  265)     return; /* Cannot open direcroty; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300  266)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  267) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  268)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  269) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  270)   while( (entry = readdir( dir )) != NULL)
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)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  274)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300  275) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  276)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300  277)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  278)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  279)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  280)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  281) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  282)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  283)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  284)       if( S_ISDIR(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  285)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  286)         /* recursively remove a nested directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  287)         _rm_tmpdir( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  288)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  289)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  290)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  291)         /* remove a file object */
11c606a6 (kx 2023-04-11 01:18:34 +0300  292)         (void)unlink( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  293)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  294)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  295)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  299)   /* remove the devastated directory and close the object of this directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300  300)   (void)rmdir( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  301) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  302)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  303) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  304) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  305) static char *_mk_tmpdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  306) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  307)   char   *buf = NULL, *p, *tmp = "/tmp";
11c606a6 (kx 2023-04-11 01:18:34 +0300  308)   size_t  len = 0, size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  309) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  310)   (void)umask( S_IWGRP | S_IWOTH ); /* octal 022 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  311) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  312)   /* Get preferred directory for tmp files */
11c606a6 (kx 2023-04-11 01:18:34 +0300  313)   if( (p = getenv( "TMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  314)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  315)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  316)   else if( (p = getenv( "TEMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  317)     tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  318)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  319) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  320)   size = strlen( tmp ) + strlen( DISTRO_NAME ) + strlen( program ) + 12;
11c606a6 (kx 2023-04-11 01:18:34 +0300  321) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  322)   buf = (char *)malloc( size );
11c606a6 (kx 2023-04-11 01:18:34 +0300  323)   if( !buf ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  324) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  325)   len = snprintf( buf, size, (const char *)"%s/%s/%s-%.7u", tmp, DISTRO_NAME, program, getpid() );
11c606a6 (kx 2023-04-11 01:18:34 +0300  326)   if( len == 0 || len == size - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  327)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  328)     free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  329)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  330) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  331)   _rm_tmpdir( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  332) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  333)   if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  334)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  335)     return buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300  336)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  337) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  338)   free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  339) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  340) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  341) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  342) void fatal_error_actions( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  343) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  344)   logmsg( errlog, MSG_NOTICE, "Free resources on FATAL error..." );
11c606a6 (kx 2023-04-11 01:18:34 +0300  345)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  346)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  347) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  348) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  349) void sigint( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  350) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  351)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  352) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  353)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  354)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300  355) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  356) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  357) void sigchld( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300  358) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  359)   pid_t  pid = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  360)   int    status;
11c606a6 (kx 2023-04-11 01:18:34 +0300  361) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  362)   (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300  363) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  364)   while( (pid = waitpid( -1, &status, WNOHANG )) > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  365)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  366)     ; /* One of children with 'pid' is terminated */
11c606a6 (kx 2023-04-11 01:18:34 +0300  367) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  368)     if( WIFEXITED( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  369)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  370)       if( (int) WEXITSTATUS (status) > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  371)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  372)         ++exit_status; /* printf( "Child %d returned non zero status: %d\n", pid, (int)WEXITSTATUS (status) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  373)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  374)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300  375)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  376)         ; /* printf( "Child %d terminated with status: %d\n", pid, (int)WEXITSTATUS (status) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  377)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  378)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  379)     else if( WIFSIGNALED( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  380)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  381)       ++exit_status; /* printf( "Child %d terminated on signal: %d\n", pid,  WTERMSIG( status ) ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  382)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  383)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  384)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  385)       ++exit_status; /* printf( "Child %d terminated on unknown reason\n", pid ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300  386)     }
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)   if( pid == -1 && errno == ECHILD )
11c606a6 (kx 2023-04-11 01:18:34 +0300  391)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  392)     /* No child processes: */
11c606a6 (kx 2023-04-11 01:18:34 +0300  393)     __done = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  394)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  395)   return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  396) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  397) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  398) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  399) static void set_signal_handlers()
11c606a6 (kx 2023-04-11 01:18:34 +0300  400) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  401)   struct sigaction  sa;
11c606a6 (kx 2023-04-11 01:18:34 +0300  402)   sigset_t          set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  403) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  404)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  405)   sa.sa_handler = sigint;          /* TERM, INT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  406)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  407)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  408)   sigaddset( &set, SIGTERM );
11c606a6 (kx 2023-04-11 01:18:34 +0300  409)   sigaddset( &set, SIGINT );
11c606a6 (kx 2023-04-11 01:18:34 +0300  410)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  411)   sigaction( SIGTERM, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  412)   sigaction( SIGINT, &sa,  NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  413) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  414)   /* System V fork+wait does not work if SIGCHLD is ignored */
11c606a6 (kx 2023-04-11 01:18:34 +0300  415)   memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  416)   sa.sa_handler = sigchld;         /* CHLD */
11c606a6 (kx 2023-04-11 01:18:34 +0300  417)   sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300  418)   sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300  419)   sigaddset( &set, SIGCHLD );
11c606a6 (kx 2023-04-11 01:18:34 +0300  420)   sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300  421)   sigaction( SIGCHLD, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  422) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  423)   memset( &sa, 0, sizeof( sa ) );  /* ignore SIGPIPE */
11c606a6 (kx 2023-04-11 01:18:34 +0300  424)   sa.sa_handler = SIG_IGN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  425)   sa.sa_flags = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  426)   sigaction( SIGPIPE, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  427) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  428) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  429) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  430) static enum _input_type check_input_file( char *uncompress, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  431) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  432)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  433)   size_t pkglog_size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  434)   unsigned char buf[8];
11c606a6 (kx 2023-04-11 01:18:34 +0300  435)   int rc, fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300  436) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  437)   /* SIGNATURES: https://www.garykessler.net/library/file_sigs.html */
11c606a6 (kx 2023-04-11 01:18:34 +0300  438) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  439)   if( uncompress )
11c606a6 (kx 2023-04-11 01:18:34 +0300  440)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  441)     *uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  442)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  443) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  444)   if( stat( fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  445)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  446)     FATAL_ERROR( "Cannot access %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  447)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  448) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  449)   pkglog_size = st.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300  450) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  451)   if( (fd = open( fname, O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  452)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  453)     FATAL_ERROR( "Cannot open %s file: %s", basename( (char *)fname ), strerror( errno ) );
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)   rc = (int)read( fd, (void *)&buf[0], 7 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  457)   if( rc != 7 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  458)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  459)     close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  460)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  461)   buf[7] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  462) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  463)   /* TEXT */
11c606a6 (kx 2023-04-11 01:18:34 +0300  464)   if( !strncmp( (const char *)&buf[0], "PACKAGE", 7 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  465)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  466)     close( fd ); return IFMT_LOG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  467)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  468) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  469)   /* GZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  470)   if( buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x08 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  471)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  472)     if( uncompress ) { *uncompress = 'x'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  473)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  474)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  475) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  476)   /* BZ2 */
11c606a6 (kx 2023-04-11 01:18:34 +0300  477)   if( buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  478)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  479)     if( uncompress ) { *uncompress = 'j'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  480)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  481)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  482) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  483)   /* XZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300  484)   if( buf[0] == 0xFD && buf[1] == 0x37 && buf[2] == 0x7A &&
11c606a6 (kx 2023-04-11 01:18:34 +0300  485)       buf[3] == 0x58 && buf[4] == 0x5A && buf[5] == 0x00   )
11c606a6 (kx 2023-04-11 01:18:34 +0300  486)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  487)     if( uncompress ) { *uncompress = 'J'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  488)     close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  489)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  490) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  491)   if( pkglog_size > 262 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  492)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  493)     if( lseek( fd, 257, SEEK_SET ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  494)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  495)       FATAL_ERROR( "Cannot check signature of %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  496)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  497)     rc = (int)read( fd, &buf[0], 5 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  498)     if( rc != 5 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  499)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  500)       FATAL_ERROR( "Cannot read signature of %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  501)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  502)     /* TAR */
11c606a6 (kx 2023-04-11 01:18:34 +0300  503)     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  504)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  505)       close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300  506)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  507)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  508) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  509)   close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  510) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  511) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  512) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  513) void get_args( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300  514) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  515)   const char* short_options = "hvr:";
11c606a6 (kx 2023-04-11 01:18:34 +0300  516) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  517)   const struct option long_options[] =
11c606a6 (kx 2023-04-11 01:18:34 +0300  518)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  519)     { "help",        no_argument,       NULL, 'h' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  520)     { "version",     no_argument,       NULL, 'v' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  521)     { "root",        required_argument, NULL, 'r' },
11c606a6 (kx 2023-04-11 01:18:34 +0300  522)     { NULL,          0,                 NULL,  0  }
11c606a6 (kx 2023-04-11 01:18:34 +0300  523)   };
11c606a6 (kx 2023-04-11 01:18:34 +0300  524) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  525)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  526)   int option_index = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  527) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  528)   while( (ret = getopt_long( argc, argv, short_options, long_options, &option_index )) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  529)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  530)     switch( ret )
11c606a6 (kx 2023-04-11 01:18:34 +0300  531)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  532)       case 'h':
11c606a6 (kx 2023-04-11 01:18:34 +0300  533)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  534)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  535)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  536)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  537)       case 'v':
11c606a6 (kx 2023-04-11 01:18:34 +0300  538)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  539)         version();
11c606a6 (kx 2023-04-11 01:18:34 +0300  540)         break;
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)       case 'r':
11c606a6 (kx 2023-04-11 01:18:34 +0300  544)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  545)         if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  546)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300  547)           root = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  548)           remove_trailing_slash( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  549)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300  550)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300  551)           /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300  552)           usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  553)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  554)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  555) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  556)       case '?': default:
11c606a6 (kx 2023-04-11 01:18:34 +0300  557)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  558)         usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  559)         break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  560)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  561)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  562)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  563) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  564) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  565)   if( optind < argc )
11c606a6 (kx 2023-04-11 01:18:34 +0300  566)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  567)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  568)     char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  569) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  570)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  571) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  572)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  573)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  574)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  575) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  576)     (void)strcpy( buf, (const char *)argv[optind] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  577)     if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  578)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  579)       FATAL_ERROR( "Cannot access '%s' file: %s", buf, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  580)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  581) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  582)     if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  583)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  584)       pkg_fname = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  585)       free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  586)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  587)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  588)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  589)       FATAL_ERROR( "Input package '%s' is not a regular file", buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  590)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  591)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  592)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  593)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  594)     usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300  595)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  596) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  597) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  598)   if( !pkgs_path )
11c606a6 (kx 2023-04-11 01:18:34 +0300  599)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  600)     struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300  601)     char  *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  602) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  603)     bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  604) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  605)     buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  606)     if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  607)     bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  608) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  609)     if( !root )
11c606a6 (kx 2023-04-11 01:18:34 +0300  610)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  611)       buf[0] = '/'; buf[1] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  612)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  613)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  614)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  615)       int len = strlen( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  616) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  617)       (void)strcpy( buf, (const char *)root );
11c606a6 (kx 2023-04-11 01:18:34 +0300  618)       if( buf[ len - 1 ] != '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300  619)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  620)         buf[len] = '/'; buf[len+1] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  621)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  622)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  623) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  624)     (void)strcat( buf, PACKAGES_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300  625)     if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  626)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  627)       FATAL_ERROR( "Cannot access '%s' file or directory: %s", buf, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  628)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  629) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  630)     if( S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  631)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  632)       pkgs_path = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300  633)       free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  634)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  635)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300  636)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  637)       FATAL_ERROR( "Defined --root '%s' is not a directory", buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300  638)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  639) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  640)   } /* End if( !pkgs_path ) */
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) /***************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  645)   Copy functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300  646)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  647) static void _copy_pkglog( const char *group, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  648) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  649)   enum _input_type  type = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300  650)   char              uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  651) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  652)   type = check_input_file( &uncompress, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  653) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  654)   if( type == IFMT_LOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300  655)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  656)     int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  657)     char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  658) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  659)     tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  660)     if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  661)     bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  662) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  663)     if( group ) { (void)sprintf( &tmp[0], "%s/%s", tmpdir, group ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  664)     else        { (void)sprintf( &tmp[0], "%s", tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  665) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  666)     if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  667)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  668)       ERROR( "Cannot copy '%s' PKGLOG file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  669)       free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  670)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  671)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  672) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  673)     cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  674)     if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300  675)     bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  676) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  677)     len = snprintf( &cmd[0], PATH_MAX, "cp %s %s/ > /dev/null 2>&1", fname, tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  678)     if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  679)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  680)       FATAL_ERROR( "Cannot copy %s PKGLOG file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  681)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  682)     (void)sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300  683)     ++__child;
11c606a6 (kx 2023-04-11 01:18:34 +0300  684) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  685)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300  686)     free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300  687)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  688) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  689) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  690) static void _search_pkglogs( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300  691) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  692)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300  693)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300  694)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300  695) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  696)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300  697)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300  698) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  699)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  700)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  701)     FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
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)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  705)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  706)     FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  707)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  708) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  709)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  710)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  711)     FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  712)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  713) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  714)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  715) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  716)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300  717)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  718)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300  719)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300  720) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  721)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300  722)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  723) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  724)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300  725)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  726)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  727) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  728)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  729)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  730)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  731)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  732)         _copy_pkglog( grp, (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300  733)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  734)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  735)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  736)         _search_pkglogs( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300  737)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  738)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  739)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300  740)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  741) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  742)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300  743) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  744) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  745) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  746)   copy_pkglogs() - returns number of copied PKGLOGS or 0 if
11c606a6 (kx 2023-04-11 01:18:34 +0300  747)                    no PKGLOGS found in the destination
11c606a6 (kx 2023-04-11 01:18:34 +0300  748)                    directory (SETUP_DB_PATH).
11c606a6 (kx 2023-04-11 01:18:34 +0300  749)                    The exit_status has been set.
11c606a6 (kx 2023-04-11 01:18:34 +0300  750)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  751) int copy_pkglogs( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300  752) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  753)   int ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  754) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  755)   __done = 0; __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  756) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  757)   _search_pkglogs( (const char *)pkgs_path, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300  758) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  759)   if( __child > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300  760)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  761)     while( !__done ) usleep( 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300  762)     ret = __child;
11c606a6 (kx 2023-04-11 01:18:34 +0300  763)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  764) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  765)   __done = 0; __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  766) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  767)   return ret;
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)   Enf of Copy functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300  771)  ***********************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300  772) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  773) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  774) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  775)   Remove leading spaces and take non-space characters only:
11c606a6 (kx 2023-04-11 01:18:34 +0300  776)   (Especialy for pkginfo lines)
11c606a6 (kx 2023-04-11 01:18:34 +0300  777)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  778) static char *skip_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  779) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  780)   char *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  781) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  782)   if( !s || *s == '\0' ) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  783) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  784)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  785) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  786)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  787)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  788) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  789)   if( *p == '\0' ) return (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  790) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  791)   return( xstrdup( (const char *)p ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300  792) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  793) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  794) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  795) /*******************************
11c606a6 (kx 2023-04-11 01:18:34 +0300  796)   remove spaces at end of line:
11c606a6 (kx 2023-04-11 01:18:34 +0300  797)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300  798) static void skip_eol_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  799) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  800)   char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  801) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  802)   if( !s || *s == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  803) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  804)   p = s + strlen( s ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  805)   while( isspace( *p ) ) { *p-- = '\0'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  806) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  807) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  808) static size_t read_usize( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  809) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  810)   size_t  size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  811)   size_t  mult = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  812)   double  sz = 0.0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  813) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  814)   char    suffix;
11c606a6 (kx 2023-04-11 01:18:34 +0300  815)   char   *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  816) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  817)   if( !s || *s == '\0' ) return size;
11c606a6 (kx 2023-04-11 01:18:34 +0300  818) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  819)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  820) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  821)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  822)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  823) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  824)   if( *p == '\0' ) return size;
11c606a6 (kx 2023-04-11 01:18:34 +0300  825) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  826)   --q;
11c606a6 (kx 2023-04-11 01:18:34 +0300  827)   suffix = *q;
11c606a6 (kx 2023-04-11 01:18:34 +0300  828)   switch( suffix )
11c606a6 (kx 2023-04-11 01:18:34 +0300  829)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  830)     /* by default size calculates in KiB - 1024 Bytes (du -s -h .) */
11c606a6 (kx 2023-04-11 01:18:34 +0300  831)     case 'G':
11c606a6 (kx 2023-04-11 01:18:34 +0300  832)     case 'g':
11c606a6 (kx 2023-04-11 01:18:34 +0300  833)       mult = 1024 * 1024;
11c606a6 (kx 2023-04-11 01:18:34 +0300  834)       *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  835)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  836)     case 'M':
11c606a6 (kx 2023-04-11 01:18:34 +0300  837)     case 'm':
11c606a6 (kx 2023-04-11 01:18:34 +0300  838)       mult = 1024;
11c606a6 (kx 2023-04-11 01:18:34 +0300  839)       *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  840)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  841)     case 'K':
11c606a6 (kx 2023-04-11 01:18:34 +0300  842)     case 'k':
11c606a6 (kx 2023-04-11 01:18:34 +0300  843)       *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  844)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  845)     default:
11c606a6 (kx 2023-04-11 01:18:34 +0300  846)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300  847)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  848) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  849)   if( sscanf( p, "%lg", &sz ) != 1 ) return size;
11c606a6 (kx 2023-04-11 01:18:34 +0300  850) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  851)   return (size_t)round( sz * (double)mult );
11c606a6 (kx 2023-04-11 01:18:34 +0300  852) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  853) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  854) static int read_total_files( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300  855) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  856)   int   n = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  857)   char *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  858) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  859)   if( !s || *s == '\0' ) return n;
11c606a6 (kx 2023-04-11 01:18:34 +0300  860) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  861)   p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  862) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  863)   while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  864)   while(  *q != ' ' && *q != '\t'  && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  865) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  866)   if( *p == '\0' ) return n;
11c606a6 (kx 2023-04-11 01:18:34 +0300  867) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  868)   if( sscanf( p, "%u", &n ) != 1 ) return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  869) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  870)   return n;
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) static struct pkg *input_package( const char *pkginfo_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300  874) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  875)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  876)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  877) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  878)   FILE *pkginfo = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  879) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  880)   struct pkg *pkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  881)   char *pkgname = NULL, *pkgver = NULL, *group = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  882) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  883)   if( pkginfo_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  884)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  885)     pkginfo = fopen( (const char *)pkginfo_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  886)     if( !pkginfo )
11c606a6 (kx 2023-04-11 01:18:34 +0300  887)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  888)       FATAL_ERROR( "Cannot open %s file", pkginfo_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  889)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  890)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  891) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  892)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  893)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300  894)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  895)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  896)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  897) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  898)   while( (ln = fgets( line, PATH_MAX, pkginfo )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300  899)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  900)     char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  901) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  902)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  903)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300  904) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  905)     if( (match = strstr( ln, "pkgname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  906)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  907)       if( p != NULL ) pkgname = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  908)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  909)     if( (match = strstr( ln, "pkgver" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  910)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  911)       if( p != NULL ) pkgver = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  912)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  913)     if( (match = strstr( ln, "group" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  914)       char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300  915)       if( p != NULL ) group = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  916)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  917)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  918) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  919)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300  920) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  921)   if( pkgname && pkgver )
11c606a6 (kx 2023-04-11 01:18:34 +0300  922)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  923)     pkg = pkg_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300  924)     if( pkg )
11c606a6 (kx 2023-04-11 01:18:34 +0300  925)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  926)       if( group )
11c606a6 (kx 2023-04-11 01:18:34 +0300  927)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300  928)         pkg->group = group;
11c606a6 (kx 2023-04-11 01:18:34 +0300  929)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300  930)       pkg->name    = pkgname;
11c606a6 (kx 2023-04-11 01:18:34 +0300  931)       pkg->version = pkgver;
11c606a6 (kx 2023-04-11 01:18:34 +0300  932)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  933) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  934)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  935)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  936)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  937)     if( group )      free( group );
11c606a6 (kx 2023-04-11 01:18:34 +0300  938)     if( pkgname )    free( pkgname );
11c606a6 (kx 2023-04-11 01:18:34 +0300  939)     if( pkgver )     free( pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300  940) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  941)     FATAL_ERROR( "Invalid input .PKGINFO file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  942)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  943) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  944)   fclose( pkginfo );
11c606a6 (kx 2023-04-11 01:18:34 +0300  945) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  946)   return( pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300  947) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  948) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  949) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  950) static void get_short_description( char *buf, const char *line )
11c606a6 (kx 2023-04-11 01:18:34 +0300  951) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  952)   char *s, *p, *q;
11c606a6 (kx 2023-04-11 01:18:34 +0300  953) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  954)   if( buf ) { buf[0] = '\0'; s = buf; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  955)   if( !line || line[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300  956) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  957)   p = index( line, '(' );
11c606a6 (kx 2023-04-11 01:18:34 +0300  958)   q = index( line, ')' );
11c606a6 (kx 2023-04-11 01:18:34 +0300  959)   if( p && q && q > p )
11c606a6 (kx 2023-04-11 01:18:34 +0300  960)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  961)     ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  962)     while( *p && p < q )
11c606a6 (kx 2023-04-11 01:18:34 +0300  963)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  964)       *s = *p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  965)       ++p; ++s;
11c606a6 (kx 2023-04-11 01:18:34 +0300  966)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  967)     *s = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300  968)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  969)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300  970)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  971)     /*
11c606a6 (kx 2023-04-11 01:18:34 +0300  972)       If short description declaration is incorrect at first line
11c606a6 (kx 2023-04-11 01:18:34 +0300  973)       of description; then we take whole first line of description:
11c606a6 (kx 2023-04-11 01:18:34 +0300  974)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300  975)     p = index( line, ':' ); ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300  976)     while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300  977)     strcpy( buf, p );
11c606a6 (kx 2023-04-11 01:18:34 +0300  978)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300  979) }
11c606a6 (kx 2023-04-11 01:18:34 +0300  980) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  981) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  982) static int get_references_section( int *start, int *stop, unsigned int *cnt, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300  983) {
11c606a6 (kx 2023-04-11 01:18:34 +0300  984)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300  985) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  986)   if( !start || !stop || !cnt ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300  987) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  988)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300  989)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300  990)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  991)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300  992) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  993)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300  994)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300  995)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300  996)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300  997)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300  998) 
11c606a6 (kx 2023-04-11 01:18:34 +0300  999)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1000)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1001) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1002)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1003)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1004)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1005) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1006)       if( (match = strstr( ln, "REFERENCE COUNTER:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1007)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1008)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1009)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1010) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1011)         /* Get reference counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1012)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1013)           unsigned int count;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1014)           int          rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1015) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1016)           ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1017)           skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1018) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1019)           rc = sscanf( ln, "REFERENCE COUNTER: %u", &count );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1020)           if( rc == 1 && cnt != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1021)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1022)             *cnt = count;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1023)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1024)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1025)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1026)       if( (match = strstr( ln, "REQUIRES:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1027)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1028)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1029)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1030)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1031) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1032)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1033)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1034) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1035)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1036) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1037)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1038) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1039)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1040)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1041) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1042)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1043) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1044) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1045) static int get_requires_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1046) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1047)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1048) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1049)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1050) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1051)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1052)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1053)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1054)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1055) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1056)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1057)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1058)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1059)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1060)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1061) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1062)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1063)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1064) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1065)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1066)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1067)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1068) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1069)       if( (match = strstr( ln, "REQUIRES:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1070)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1071)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1072)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1073)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1074)       if( (match = strstr( ln, "PACKAGE DESCRIPTION:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1075)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1076)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1077)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1078)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1079) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1080)       ++ret;
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)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1084) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1085)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1086) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1087)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1088)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1089) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1090)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1091) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1092) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1093) static int get_description_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1094) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1095)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1096) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1097)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1098) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1099)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1100)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1101)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1102)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1103) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1104)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1105)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1106)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1107)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1108)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1109) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1110)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1111)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1112) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1113)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1114)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1115)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1116) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1117)       if( (match = strstr( ln, "PACKAGE DESCRIPTION:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1118)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1119)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1120)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1121)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1122)       if( (match = strstr( ln, "RESTORE LINKS:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1123)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1124)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1125)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1126)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1127) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1128)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1129)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1130) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1131)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1132) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1133)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1134) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1135)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1136)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1137) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1138)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1139) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1140) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1141) static int get_restore_links_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1142) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1143)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1144) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1145)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1146) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1147)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1148)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1149)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1150)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1151) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1152)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1153)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1154)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1155)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1156)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1157) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1158)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1159)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1160) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1161)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1162)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1163)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1164) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1165)       if( (match = strstr( ln, "RESTORE LINKS:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1166)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1167)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1168)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1169)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1170)       if( (match = strstr( ln, "INSTALL SCRIPT:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1171)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1172)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1173)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1174)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1175) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1176)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1177)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1178) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1179)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1180) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1181)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1182) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1183)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1184)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1185) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1186)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1187) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1188) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1189) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1190) static int get_install_script_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1191) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1192)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1193) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1194)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1195) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1196)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1197)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1198)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1199)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1200) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1201)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1202)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1203)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1204)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1205)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1206) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1207)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1208)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1209) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1210)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1211)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1212)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1213) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1214)       if( (match = strstr( ln, "INSTALL SCRIPT:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1215)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1216)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1217)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1218)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1219)       if( (match = strstr( ln, "FILE LIST:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1220)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1221)         *stop = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1222)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1223)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1224) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1225)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1226)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1227) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1228)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1229) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1230)     ret = ( found == 2 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1231) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1232)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1233)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1234) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1235)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1236) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1237) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1238) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1239) static int get_file_list_section( int *start, int *stop, FILE *log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1240) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1241)   int ret = -1, found = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1242) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1243)   if( !start || !stop ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1244) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1245)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1246)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1247)     char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1248)     char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1249) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1250)     line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1251)     if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1252)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1253)       FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1254)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1255) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1256)     ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1257)     *start = 0; *stop = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1258) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1259)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1260)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1261)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1262) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1263)       if( (match = strstr( ln, "FILE LIST:" )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1264)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1265)         *start = ret + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1266)         ++found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1267)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1268) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1269)       ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1270)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1271) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1272)     free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1273) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1274)     ret = ( found == 1 ) ? 0 : 1; /* 0 - success; 1 - not found. */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1275) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1276)     fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1277)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1278) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1279)   return( ret );
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1283) int read_pkginfo( FILE *log, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1284) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1285)   int ret = -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1286) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1287)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1288)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1289) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1290)   char           *pkgname_pattern = "PACKAGE NAME:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1291)                   *pkgver_pattern = "PACKAGE VERSION:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1292)                     *arch_pattern = "ARCH:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1293)               *distroname_pattern = "DISTRO:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1294)                *distrover_pattern = "DISTRO VERSION:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1295)                    *group_pattern = "GROUP:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1296)                      *url_pattern = "URL:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1297)                  *license_pattern = "LICENSE:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1298)        *uncompressed_size_pattern = "UNCOMPRESSED SIZE:",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1299)              *total_files_pattern = "TOTAL FILES:";
11c606a6 (kx 2023-04-11 01:18:34 +0300 1300) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1301) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1302)   if( !log || !package ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1303) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1304)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1305)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1306)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1307)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1308)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1309) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1310)   ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1311) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1312)   while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1313)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1314)     char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1315) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1316)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1317)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1318) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1319)     if( (match = strstr( ln, pkgname_pattern )) && match == ln ) /* at start of line only */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1320)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1321)       package->pkginfo->name = skip_spaces( ln + strlen( pkgname_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1322)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1323)     if( (match = strstr( ln, pkgver_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1324)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1325)       package->pkginfo->version = skip_spaces( ln + strlen( pkgver_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1326)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1327)     if( (match = strstr( ln, arch_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1328)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1329)       package->pkginfo->arch = skip_spaces( ln + strlen( arch_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1330)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1331)     if( (match = strstr( ln, distroname_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1332)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1333)       package->pkginfo->distro_name = skip_spaces( ln + strlen( distroname_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1334)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1335)     if( (match = strstr( ln, distrover_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1336)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1337)       package->pkginfo->distro_version = skip_spaces( ln + strlen( distrover_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1338)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1339)     if( (match = strstr( ln, group_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1340)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1341)       package->pkginfo->group = skip_spaces( ln + strlen( group_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1342)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1343)     if( (match = strstr( ln, url_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1344)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1345)       package->pkginfo->url = skip_spaces( ln + strlen( url_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1346)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1347)     if( (match = strstr( ln, license_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1348)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1349)       package->pkginfo->license = skip_spaces( ln + strlen( license_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1350)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1351)     if( (match = strstr( ln, uncompressed_size_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1352)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1353)       package->pkginfo->uncompressed_size = read_usize( ln + strlen( uncompressed_size_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1354)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1355)     if( (match = strstr( ln, total_files_pattern )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1356)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1357)       package->pkginfo->total_files = read_total_files( ln + strlen( total_files_pattern ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1358)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1359) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1360)     if( (match = strstr( ln, "PACKAGE DESCRIPTION:" )) && match == ln )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1361)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1362)       char *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1363) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1364)       buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1365)       if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1366)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1367)         FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1368)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1369) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1370)       /* Get short_description from PACKAGE DESCRIPTION */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1371)       ln = fgets( line, PATH_MAX, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1372)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1373) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1374)       bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1375)       get_short_description( buf, (const char *)line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1376)       if( buf[0] != '\0' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1377)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1378)         package->pkginfo->short_description = xstrdup( (const char *)buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1379)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1380)       free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1381)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1382) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1383)   } /* End of while() */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1384) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1385)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1386) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1387)   if( package->pkginfo->name           == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1388)   if( package->pkginfo->version        == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1389)   if( package->pkginfo->arch           == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1390)   if( package->pkginfo->distro_name    == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1391)   if( package->pkginfo->distro_version == NULL ) ++ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1392)   /* group can be equal to NULL */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1393) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1394)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1395) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1396)   return( ret );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1397) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1398) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1399) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1400) static unsigned int read_references( FILE *log, int start, unsigned int *cnt, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1401) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1402)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1403)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1404)   char *p = NULL, *group = NULL, *name = NULL, *version = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1405)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1406) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1407)   unsigned int counter, pkgs = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1408) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1409)   struct pkg *pkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1410) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1411)   if( !log || !cnt || *cnt == 0 || !package ) return pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1412) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1413)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1414)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1415)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1416)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1417)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1418) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1419)   counter = *cnt;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1420) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1421)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1422) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1423)   n = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1424)   while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1425)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1426)     ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1427)     skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1428) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1429)     if( strstr( ln, "REQUIRES:" ) ) break; /* if cnt greater than real number of references */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1430) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1431)     if( n < counter )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1432)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1433)       if( (p = index( (const char *)ln, '=' )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1434)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1435)         *p = '\0'; version = ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1436)         if( (p = index( (const char *)ln, '/' )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1437)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1438)           *p = '\0'; name = ++p; group = (char *)&ln[0];
11c606a6 (kx 2023-04-11 01:18:34 +0300 1439)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1440)         else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1441)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1442)           name  = (char *)&ln[0]; group = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1443)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1444) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1445)         pkg = pkg_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1446) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1447)         if( group ) pkg->group = xstrdup( (const char *)group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1448)         pkg->name    = xstrdup( (const char *)name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1449)         pkg->version = xstrdup( (const char *)version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1450) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1451)         add_reference( package, pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1452)         ++pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1453)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1454)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1455)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1456)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1457)       break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1458)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1459) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1460)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1461) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1462)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1463) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1464)   *cnt = pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1465) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1466)   return pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1467) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1468) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1469) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1470) static unsigned int read_requires( FILE *log, int start, int stop, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1471) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1472)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1473)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1474)   char *p = NULL, *group = NULL, *name = NULL, *version = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1475)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1476) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1477)   unsigned int pkgs = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1478) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1479)   struct pkg *pkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1480) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1481)   if( !log || !package ) return pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1482) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1483)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1484)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1485)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1486)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1487)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1488) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1489)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1490) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1491)   if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1492)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1493)     ++n; /* skip section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1494) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1495)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1496)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1497)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1498)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1499) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1500)       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 1501) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1502)       if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1503)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1504)         if( (p = index( (const char *)ln, '=' )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1505)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1506)           *p = '\0'; version = ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1507)           if( (p = index( (const char *)ln, '/' )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1508)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1509)             *p = '\0'; name = ++p; group = (char *)&ln[0];
11c606a6 (kx 2023-04-11 01:18:34 +0300 1510)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1511)           else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1512)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1513)             name  = (char *)&ln[0]; group = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1514)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1515) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1516)           pkg = pkg_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1517) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1518)           if( group ) pkg->group = xstrdup( (const char *)group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1519)           pkg->name    = xstrdup( (const char *)name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1520)           pkg->version = xstrdup( (const char *)version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1521) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1522)           add_required( package, pkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1523)           ++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)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1528)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1529) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1530)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1531) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1532)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1533) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1534)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1535) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1536)   return pkgs;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1537) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1538) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1539) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1540) static unsigned int read_description( FILE *log, int start, int stop, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1541) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1542)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1543)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1544)   char *pattern = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1545)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1546) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1547)   char  *tmp_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1548)   FILE  *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1549) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1550)   unsigned int lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1551) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1552)   if( !log || !package ) return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1553) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1554)   tmp_fname = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1555)   if( !tmp_fname ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1556) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1557)   bzero( (void *)tmp_fname, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1558)   (void)sprintf( (char *)&tmp_fname[0], "%s/.DESCRIPTION", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1559) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1560)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1561)   if( !line )    { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1562) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1563)   pattern = (char *)malloc( (size_t)strlen( package->pkginfo->name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1564)   if( !pattern ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1565) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1566)   (void)sprintf( pattern, "%s:", package->pkginfo->name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1567) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1568) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1569)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1570) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1571)   if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1572)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1573)     ++n; /* skip section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1574) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1575)     tmp = fopen( (const char *)&tmp_fname[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1576)     if( !tmp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1577)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1578)       FATAL_ERROR( "Cannot create temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1579)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1580) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1581)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1582)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1583)       char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1584) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1585)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1586)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1587) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1588)       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 1589) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1590)       if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1591)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1592)         /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 1593)           skip non-significant spaces at beginning of line
11c606a6 (kx 2023-04-11 01:18:34 +0300 1594)           and print lines started with 'pkgname:'
11c606a6 (kx 2023-04-11 01:18:34 +0300 1595)          */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1596)         if( (match = strstr( ln, pattern )) && lines < DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1597)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1598)           int mlen   = strlen( match ), plen = strlen( pattern );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1599)           int length = ( mlen > plen )  ? (mlen - plen - 1) : 0 ;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1600) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1601)           if( length > DESCRIPTION_LENGTH_OF_LINE )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1602)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1603)             /* WARNING( "Package DESCRIPTION contains lines with length greater than %d characters", DESCRIPTION_LENGTH_OF_LINE ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1604)             match[plen + 1 + DESCRIPTION_LENGTH_OF_LINE] = '\0'; /* truncating description line  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1605)             skip_eol_spaces( match );                            /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1606)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1607)           fprintf( tmp, "%s\n", match );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1608)           ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1609)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1610) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1611)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1612)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1613)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1614) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1615)     if( lines < (unsigned int)DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1616)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1617)       /* WARNING( "Package DESCRIPTION contains less than %d lines", DESCRIPTION_NUMBER_OF_LINES ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1618)       while( lines < (unsigned int)DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1619)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1620)         fprintf( tmp, "%s\n", pattern );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1621)         ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1622)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1623)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1624) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1625)     fflush( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1626)     fclose( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1627) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1628)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1629) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1630)   free( pattern );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1631)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1632) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1633)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1634) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1635)   /* read temporary saved description */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1636)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1637)     struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1638)     size_t size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1639)     int    fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1640) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1641)     char  *desc = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1642) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1643)     if( stat( tmp_fname, &sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1644)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1645)       FATAL_ERROR( "Cannot stat temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1646)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1647)     size = (size_t)sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1648) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1649)     if( size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1650)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1651)       ssize_t rc = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1652) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1653)       desc = (char *)malloc( size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1654)       if( !desc ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1655)       bzero( (void *)desc, size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1656) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1657)       if( (fd = open( (const char *)&tmp_fname[0], O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1658)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1659)         FATAL_ERROR( "Canot access temporary %s file: %s", basename( (char *)&tmp_fname[0] ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1660)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1661) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1662)       rc = read( fd, (void *)desc, size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1663)       if( rc != (ssize_t)size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1664)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1665)         ERROR( "The %s file is not fully read", basename( (char *)&tmp_fname[0] ) );
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)       package->description = desc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1669) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1670)       close( fd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1671)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1672) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1673)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1674) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1675)   (void)unlink( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1676)   free( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1677) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1678)   return 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) static unsigned int read_restore_links( FILE *log, int start, int stop, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1683) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1684)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1685)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1686)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1687) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1688)   char  *tmp_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1689)   FILE  *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1690) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1691)   unsigned int lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1692) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1693)   if( !log || !package ) return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1694) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1695)   tmp_fname = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1696)   if( !tmp_fname ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1697) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1698)   bzero( (void *)tmp_fname, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1699)   (void)sprintf( (char *)&tmp_fname[0], "%s/.RESTORELINKS", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1700) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1701)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1702)   if( !line )    { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1703) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1704)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1705) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1706)   if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1707)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1708)     ++n; /* skip section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1709) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1710)     tmp = fopen( (const char *)&tmp_fname[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1711)     if( !tmp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1712)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1713)       FATAL_ERROR( "Cannot create temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1714)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1715) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1716)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1717)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1718)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1719)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1720) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1721)       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 1722) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1723)       if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1724)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1725)         fprintf( tmp, "%s\n", ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1726)         ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1727)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1728)       ++n;
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)     fflush( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1732)     fclose( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1733) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1734)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1735) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1736)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1737) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1738)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1739) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1740)   /* read temporary saved description */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1741)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1742)     struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1743)     size_t size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1744)     int    fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1745) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1746)     char  *links = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1747) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1748)     if( stat( tmp_fname, &sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1749)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1750)       FATAL_ERROR( "Cannot stat temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1751)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1752)     size = (size_t)sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1753) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1754)     if( size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1755)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1756)       ssize_t rc = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1757) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1758)       links = (char *)malloc( size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1759)       if( !links ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1760)       bzero( (void *)links, size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1761) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1762)       if( (fd = open( (const char *)&tmp_fname[0], O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1763)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1764)         FATAL_ERROR( "Canot access temporary %s file: %s", basename( (char *)&tmp_fname[0] ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1765)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1766) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1767)       rc = read( fd, (void *)links, size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1768)       if( rc != (ssize_t)size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1769)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1770)         ERROR( "The %s file is not fully read", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1771)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1772) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1773)       package->restore_links = links;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1774) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1775)       close( fd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1776)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1777) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1778)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1779) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1780)   (void)unlink( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1781)   free( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1782) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1783)   return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1784) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1785) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1786) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1787) static unsigned int read_install_script( FILE *log, int start, int stop, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1788) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1789)   char *ln      = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1790)   char *line    = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1791)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1792) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1793)   char  *tmp_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1794)   FILE  *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1795) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1796)   unsigned int lines = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1797) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1798)   if( !log || !package ) return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1799) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1800)   tmp_fname = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1801)   if( !tmp_fname ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1802) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1803)   bzero( (void *)tmp_fname, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1804)   (void)sprintf( (char *)&tmp_fname[0], "%s/.INSTALL", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1805) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1806)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1807)   if( !line )    { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1808) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1809)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1810) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1811)   if( start && start < stop )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1812)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1813)     ++n; /* skip section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1814) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1815)     tmp = fopen( (const char *)&tmp_fname[0], "w" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1816)     if( !tmp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1817)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1818)       FATAL_ERROR( "Cannot create temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1819)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1820) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1821)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1822)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1823)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1824)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1825) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1826)       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 1827) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1828)       if( (n > start) && (n < stop) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1829)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1830)         fprintf( tmp, "%s\n", ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1831)         ++lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1832)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1833)       ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1834)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1835) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1836)     fflush( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1837)     fclose( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1838) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1839)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1840) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1841)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1842) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1843)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1844) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1845)   /* read temporary saved description */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1846)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1847)     struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1848)     size_t size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1849)     int    fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1850) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1851)     char  *install = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1852) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1853)     if( stat( tmp_fname, &sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1854)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1855)       FATAL_ERROR( "Cannot stat temporary %s file", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1856)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1857)     size = (size_t)sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1858) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1859)     if( size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1860)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1861)       ssize_t rc = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1862) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1863)       install = (char *)malloc( size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1864)       if( !install ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1865)       bzero( (void *)install, size + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1866) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1867)       if( (fd = open( (const char *)&tmp_fname[0], O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1868)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1869)         FATAL_ERROR( "Canot access temporary %s file: %s", basename( (char *)&tmp_fname[0] ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1870)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1871) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1872)       rc = read( fd, (void *)install, size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1873)       if( rc != (ssize_t)size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1874)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1875)         ERROR( "The %s file is not fully read", basename( (char *)&tmp_fname[0] ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1876)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1877) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1878)       package->install_script = install;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1879) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1880)       close( fd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1881)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1882) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1883)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1884) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1885)   (void)unlink( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1886)   free( tmp_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1887) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1888)   return lines;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1889) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1890) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1891) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1892) static unsigned int read_file_list( FILE *log, int start, struct package *package )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1893) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1894)   char *ln   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1895)   char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1896)   int   n = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1897) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1898)   unsigned int files = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1899) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1900)   if( !log || !package ) return files;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1901) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1902)   line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1903)   if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1904)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1905)     FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1906)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1907) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1908)   while( (ln = fgets( line, PATH_MAX, log )) && (n < start) ) ++n;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1909) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1910)   if( start )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1911)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1912)     while( (ln = fgets( line, PATH_MAX, log )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1913)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1914)       ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1915)       skip_eol_spaces( ln );     /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1916) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1917)       add_file( package, (const char *)ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1918)       ++files;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1919)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1920) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1921)   } /* End if( start && start < stop ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1922) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1923)   free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1924) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1925)   fseek( log, 0, SEEK_SET );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1926) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1927)   return files;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1928) }
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1932) static void _read_pkglog( const char *group, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1933) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1934)   FILE *log   = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1935)   char *bname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1936) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1937)   if( fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1938)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1939)     log = fopen( (const char *)fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1940)     if( !log )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1941)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1942)       FATAL_ERROR( "Cannot open %s file", fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1943)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1944)     bname = (char *)fname + strlen( tmpdir ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1945)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1946) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1947)   if( log != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1948)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1949)     struct package *package = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1950)     int             rc, start, stop;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1951)     unsigned int    counter;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1952) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1953)     package = package_alloc();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1954) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1955)     if( read_pkginfo( log, package ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1956)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1957)       ERROR( "%s: Invalid PKGLOG file", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1958)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1959)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1960)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1961)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1962) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1963)     if( hardware ) package->hardware = xstrdup( (const char *)hardware );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1964)     if( tarballs ) /* find tarball and allocate package->tarball */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1965)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1966)       struct pkginfo *info = package->pkginfo;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1967)       const char     *tgz  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1968)       char           *buf  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1969)       struct stat     sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1970) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1971)       buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1972)       if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1973) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1974)       if( info->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1975)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1976)         (void)sprintf( buf, "%s/%s-%s-%s-%s-%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1977)                              info->group, info->name, info->version, info->arch,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1978)                              info->distro_name, info->distro_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1979)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1980)       else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1981)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1982)         (void)sprintf( buf, "%s-%s-%s-%s-%s",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1983)                              info->name, info->version, info->arch,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1984)                              info->distro_name, info->distro_version );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1985)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1986)       tgz = find_tarball( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1987)       if( tgz )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1988)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1989)         package->tarball = xstrdup( (const char *)tgz );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1990) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 1991)         bzero( (void *)&buf[0], PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1992)         (void)sprintf( buf, "%s/%s", pkgs_path, tgz );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1993)         if( stat( buf, &sb ) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1994)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1995)           info->compressed_size = (size_t)sb.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1996)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1997)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1998)       free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1999)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2000)     package->procedure = INSTALL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2001)     package->priority  = priority;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2002) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2003)     if( package->pkginfo->group && group  && strcmp( package->pkginfo->group, group ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2004)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2005)       char *tgz;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2006) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2007)       if( package->tarball ) { tgz = package->tarball; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2008)       else                   { tgz = basename( (char *)fname ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2009) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2010)       WARNING( "%s: Should be moved into '%s' subdir", tgz, package->pkginfo->group );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2011)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2012) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2013)     /******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2014)       read references:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2015)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2016)     rc = get_references_section( &start, &stop, &counter, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2017)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2018)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2019)       ERROR( "%s: PKGLOG doesn't contains REFERENCE COUNTER section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2020)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2021)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2022)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2023)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2024)     if( counter > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2025)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2026)       unsigned int pkgs = counter;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2027) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2028)       if( read_references( log, start, &counter, package ) != pkgs )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2029)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2030)         ERROR( "%s: Invalid REFERENCE COUNTER section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2031)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2032)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2033)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2034)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2035)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2036) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2037)     /******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2038)       read requires:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2039)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2040)     rc = get_requires_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2041)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2042)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2043)       ERROR( "%s: PKGLOG doesn't contains REQUIRES section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2044)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2045)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2046)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2047)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2048)     if( (stop - start) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2049)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2050)       unsigned int pkgs = (unsigned int)(stop - start - 1); /* -1 skips section header */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2051) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2052)       if( read_requires( log, start, stop, package ) != pkgs )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2053)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2054)         ERROR( "%s: Invalid REQUIRES section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2055)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2056)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2057)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2058)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2059)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2060) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2061)     /*******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2062)       read description:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2063)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2064)     rc = get_description_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2065)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2066)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2067)       ERROR( "%s: PKGLOG doesn't contains PACKAGE DESCRIPTION section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2068)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2069)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2070)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2071)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2072)     if( (stop - start) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2073)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2074)       if( read_description( log, start, stop, package ) != (unsigned int)DESCRIPTION_NUMBER_OF_LINES )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2075)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2076)         ERROR( "%s: Invalid DESCRIPTION section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2077)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2078)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2079)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2080)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2081)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2082) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2083)     /*********************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2084)       read restore links:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2085)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2086)     rc = get_restore_links_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2087)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2088)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2089)       ERROR( "%s: PKGLOG doesn't contains RESTORE LINKS section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2090)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2091)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2092)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2093)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2094)     if( (stop - start) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2095)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2096)       (void)read_restore_links( log, start, stop, package );
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)       read install script:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2101)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2102)     rc = get_install_script_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2103)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2104)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2105)       ERROR( "%s: PKGLOG doesn't contains INSTALL SCRIPT section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2106)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2107)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2108)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2109)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2110)     if( (stop - start) > 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2111)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2112)       (void)read_install_script( log, start, stop, package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2113)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2114) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2115)     /*****************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2116)       read file_list:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2117)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2118)     rc = get_file_list_section( &start, &stop, log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2119)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2120)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2121)       ERROR( "%s: PKGLOG doesn't contains FILE LIST section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2122)       package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2123)       fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2124)       return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2125)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2126)     if( start )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2127)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2128)       unsigned int files = read_file_list( log, start, package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2129)       if( files == (unsigned int)0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2130)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2131)         /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 2132)           Packages that do not contain regular files are ignored.
11c606a6 (kx 2023-04-11 01:18:34 +0300 2133)           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 2134)          */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2135)         if( ! DO_NOT_PRINTOUT_INFO )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2136)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2137)           INFO( "%s: PKGLOG contains empty FILE LIST section", bname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2138)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2139)         package_free( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2140)         fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2141)         return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2142)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2143)       package->pkginfo->total_files = (int)files;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2144)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2145) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2146)     /*
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)       утилита check-package).
11c606a6 (kx 2023-04-11 01:18:34 +0300 2150)      */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2151)     add_package( package );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2152) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2153)     ++__child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2154)     fclose( log );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2155)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2156) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2157) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2158) static void _read_pkglogs( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2159) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2160)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2161)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2162)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2163) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2164)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2165)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2166) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2167)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2168)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2169)     FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2170)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2171) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2172)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2173)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2174)     FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2175)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2176) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2177)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2178)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2179)     FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2180)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2181) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2182)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2183) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2184)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 2185)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2186)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2187)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2188) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2189)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2190)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2191) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2192)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2193)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2194)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2195) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2196)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2197)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2198)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2199)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2200)         if( check_input_file( NULL, (const char *)path ) == IFMT_LOG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2201)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2202)           _read_pkglog( grp, (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2203)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2204)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2205)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2206)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2207)         _read_pkglogs( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2208)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2209)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2210)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2211)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2212) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2213)   closedir( dir );
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) int read_pkglogs( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2217) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2218)   int ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2219) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2220)   __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2221) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2222)   _read_pkglogs( (const char *)tmpdir, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2223) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2224)   ret = __child;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2225) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2226)   __child = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2227) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2228)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2229) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2230) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2231) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2232) static void check_pkg_fname( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2233) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2234)   struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2235)   char *fname = pkg_fname;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2236) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2237)   bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2238) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2239)   if( stat( (const char *)fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2240)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2241)     FATAL_ERROR( "Cannot access input '%s' file: %s", fname, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2242)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2243) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2244)   if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2245)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2246)     struct pkg *srcpkg = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2247) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2248)     pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2249)     int   rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2250) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2251)     int   len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2252)     char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2253) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2254)     tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2255)     if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2256)     bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2257) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2258)     (void)sprintf( &tmp[0], "%s", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2259)     if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2260)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2261)       FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
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)     cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2265)     if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2266)     bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2267) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2268)     len = snprintf( &cmd[0], PATH_MAX, "%s/pkginfo -d %s -o pkginfo %s > /dev/null 2>&1", selfdir, tmp, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2269)     if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2270)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2271)       FATAL_ERROR( "Cannot get PKGINFO from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2272)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2273)     p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2274)     rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2275)     if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2276)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2277)       FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2278)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2279) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2280)     (void)strcat( tmp, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2281)     srcpkg = input_package( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2282)     add_srcpkg( srcpkg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2283)     *(strstr( tmp, "/.PKGINFO" )) = '\0'; /* :restore tmpdir in tmp[] buffer */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2284) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2285)     if( check_input_file( NULL, (const char *)fname ) == IFMT_PKG )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2286)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2287)       bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2288)       len = snprintf( &cmd[0], PATH_MAX, "%s/pkglog -m -d %s %s > /dev/null 2>&1", selfdir, tmp, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2289)       if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2290)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2291)         FATAL_ERROR( "Cannot get PKGLOG from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2292)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2293)       p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2294)       rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2295)       if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2296)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2297)         FATAL_ERROR( "Cannot get PKGLOG from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2298)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2299)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2300)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2301)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2302)       char *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2303) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2304)       buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2305)       if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2306)       bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2307) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2308)       if( srcpkg->group ) { (void)sprintf( &buf[0], "%s/%s", tmp, srcpkg->group ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2309)       else                { (void)sprintf( &buf[0], "%s", tmp ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2310) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2311)       if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2312)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2313)         FATAL_ERROR( "Cannot copy '%s' PKGLOG file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2314)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2315) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2316)       bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2317)       len = snprintf( &cmd[0], PATH_MAX, "cp %s %s/ > /dev/null 2>&1", fname, buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2318)       if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2319)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2320)         FATAL_ERROR( "Cannot copy %s PKGLOG file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2321)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2322)       p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2323)       rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2324)       if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2325)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2326)         FATAL_ERROR( "Cannot copy %s PKGLOG file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2327)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2328) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2329)       free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2330)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2331) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2332)     free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2333)     free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2334)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2335)   else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2336)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2337)     FATAL_ERROR( "Input %s file is not a regular file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2338)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2339) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2340) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2341) /****************************************************************
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)   нужную функциональность.
11c606a6 (kx 2023-04-11 01:18:34 +0300 2345) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2346)   Например: libs/libspectre требует libs/cairo, а xlibs/cairo
11c606a6 (kx 2023-04-11 01:18:34 +0300 2347)   требует libs/libspectre, однако libs/libspectre может
11c606a6 (kx 2023-04-11 01:18:34 +0300 2348)   использовать как libs/cairo так и xlibs/cairo .
11c606a6 (kx 2023-04-11 01:18:34 +0300 2349) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2350)   Search installed package with specified name within any group:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2351)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2352) static char *pkglog_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2353) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2354) static void _probe_pkglog( const char *pname, const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2355) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2356)   DIR    *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2357)   char   *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2358)   size_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2359) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2360)   struct stat    path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2361)   struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2362) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2363)   if( pkglog_fname ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2364) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2365)   if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2366)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2367)     FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2368)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2369) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2370)   if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2371)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2372)     FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2373)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2374) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2375)   if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2376)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2377)     FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2378)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2379) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2380)   len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2381) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2382)   while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 2383)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2384)     /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2385)     if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2386) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2387)     /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2388)     path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2389) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2390)     strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2391)     strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2392)     strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2393) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2394)     if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2395)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2396)       if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2397)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2398)         char *match  = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2399)         char *pkglog = basename( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2400) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2401)         if( (match = strstr( pkglog, pname )) && match == pkglog )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2402)         {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2403)           char *buf = NULL, *p = NULL, *q = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2404) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2405)           p = q = buf = xstrdup( (const char *)pkglog );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2406)           ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2407)           while( *p != '\0' && !isblank(*p) && !(*q == '-' && isdigit(*p)) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2408)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2409)             /* package version starts with a number and separated by '-' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2410)             ++p; ++q;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2411)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2412)           *(--p) = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 2413) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2414)           /*******************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2415)             We have to make sure that the name we are looking for
11c606a6 (kx 2023-04-11 01:18:34 +0300 2416)             is not shorter than the name of the found package.
11c606a6 (kx 2023-04-11 01:18:34 +0300 2417)            */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2418)           if( strlen(pname) >= strlen(buf) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2419)           {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2420) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2421)             pkglog_fname = xstrdup( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2422)             free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2423)             closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2424)             return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2425)           }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2426)           free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2427)         }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2428)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2429)       if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2430)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2431)         _probe_pkglog( pname, (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2432)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2433)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2434)     /* else { stat() returns error code; errno is set; and we have to continue the loop } */
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)   closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2438) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2439) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2440) /******************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2441)   probe_package():
11c606a6 (kx 2023-04-11 01:18:34 +0300 2442)   ---------------
11c606a6 (kx 2023-04-11 01:18:34 +0300 2443)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2444) static char *probe_package( const char *name )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2445) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2446)   char *ret = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2447) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2448)   _probe_pkglog( name, (const char *)pkgs_path, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2449)   if( pkglog_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2450)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2451)     ret = pkglog_fname;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2452)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2453) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2454)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2455) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2456) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2457) static int check_installed_pkgname( const char *name )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2458) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2459)   int   ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2460)   char *fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2461) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2462)   if( !name ) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2463) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2464)   fname = probe_package( name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2465)   if( fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2466)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2467)     ret = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2468)     free( pkglog_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2469)     pkglog_fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2470)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2471) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2472)   return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2473) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2474) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 2475)   End of search installed package.
11c606a6 (kx 2023-04-11 01:18:34 +0300 2476)  ****************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 2477) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2478) static int __extern_requires = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2479) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2480) static void _print_extern_requires( void *data, void *user_data )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2481) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2482)   struct pkg *pkg = (struct pkg *)data;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2483) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2484)   if( pkg && !check_installed_pkgname( (const char *)pkg->name ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2485)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2486)     if( pkg->group )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2487)       fprintf( stderr, "%s/%s:%s:%s\n", pkg->group, pkg->name, pkg->version, strproc( pkg->procedure ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2488)     else
11c606a6 (kx 2023-04-11 01:18:34 +0300 2489)       fprintf( stderr, "%s:%s:%s\n", pkg->name, pkg->version, strproc( pkg->procedure ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2490) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2491)     ++__extern_requires;
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) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2495) static void print_extern_requires( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2496) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2497)   dlist_foreach( extern_requires, _print_extern_requires, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2498) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2499) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2500) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2501) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2502)   Get directory where this program is placed:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2503)  */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2504) char *get_selfdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2505) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2506)   char    *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2507)   ssize_t  len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2508) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2509)   buf = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2510)   if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2511)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2512)     FATAL_ERROR( "Cannot allocate memory" );
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)   bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2516)   len = readlink( "/proc/self/exe", buf, (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2517)   if( len > 0 && len < PATH_MAX )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2518)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2519)     char *p = xstrdup( (const char *)dirname( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2520)     free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2521)     return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2522)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2523)   FATAL_ERROR( "Cannot determine self directory. Please mount /proc filesystem" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2524) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2525) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2526) void set_stack_size( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2527) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2528)   const rlim_t   stack_size = 16 * 1024 * 1024; /* min stack size = 16 MB */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2529)   struct rlimit  rl;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2530)   int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2531) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2532)   ret = getrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2533)   if( ret == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2534)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2535)     if( rl.rlim_cur < stack_size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2536)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2537)       rl.rlim_cur = stack_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2538)       ret = setrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2539)       if( ret != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2540)       {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2541)         fprintf(stderr, "setrlimit returned result = %d\n", ret);
11c606a6 (kx 2023-04-11 01:18:34 +0300 2542)         FATAL_ERROR( "Cannot set stack size" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2543)       }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2544)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2545)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2546) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2547) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2548) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2549) int main( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2550) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2551)   gid_t  gid;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2552) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2553)   set_signal_handlers();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2554) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2555)   gid = getgid();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2556)   setgroups( 1, &gid );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2557) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2558)   fatal_error_hook = fatal_error_actions;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2559) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2560)   selfdir = get_selfdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2561) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2562)   errlog = stderr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2563) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2564)   program = basename( argv[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2565)   get_args( argc, argv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2566) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2567)   /* set_stack_size(); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2568) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2569)   tmpdir = _mk_tmpdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2570)   if( !tmpdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2571)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2572)     FATAL_ERROR( "Cannot create temporary directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2573)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2574) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2575)   /* Copy PKGLOGs into TMPDIR: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2576)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2577)     int pkgs = copy_pkglogs();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2578)     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 2579)     if( exit_status > 0 ) { FATAL_ERROR( "Cannot copy some PKGLOG file" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2580)     if( ! DO_NOT_PRINTOUT_INFO )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2581)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2582)       INFO( "Found %d PKGLOG files in the '%s' directory", pkgs, pkgs_path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2583)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2584)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2585) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2586)   /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 2587)     Fill srcpkg struct and put or replace pkglog into tmpdir:
11c606a6 (kx 2023-04-11 01:18:34 +0300 2588)    */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2589)   check_pkg_fname();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2590) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2591)   /* Read PKGLOGs from TMPDIR and create Double Linked List of PACKAGES: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2592)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2593)     int pkgs = read_pkglogs();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2594)     if( pkgs == 0 )       { FATAL_ERROR( "There are no PKGLOG files in the '%s' directory", tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2595)     if( exit_status > 0 ) { FATAL_ERROR( "Cannot read some PKGLOG file" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2596)     if( ! DO_NOT_PRINTOUT_INFO )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2597)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2598)       /* INFO( "Found %d PKGLOG files in the '%s' directory", pkgs, tmpdir ); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 2599)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2600)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2601) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2602)   {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2603)     int extern_pkgs = create_provides_list( srcpkgs );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2604)     if( extern_pkgs )
11c606a6 (kx 2023-04-11 01:18:34 +0300 2605)     {
11c606a6 (kx 2023-04-11 01:18:34 +0300 2606)       print_extern_requires();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2607)       if( __extern_requires ) exit_status += 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 2608)     }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2609)     free_provides_list();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2610)   }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2611) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2612)   if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 2613)   free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 2614) 
11c606a6 (kx 2023-04-11 01:18:34 +0300 2615)   exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 2616) }