11c606a6 (kx 2023-04-11 01:18:34 +0300 1)
11c606a6 (kx 2023-04-11 01:18:34 +0300 2) /**********************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 3)
11c606a6 (kx 2023-04-11 01:18:34 +0300 4) Copyright 2019 Andrey V.Kosteltsev
11c606a6 (kx 2023-04-11 01:18:34 +0300 5)
11c606a6 (kx 2023-04-11 01:18:34 +0300 6) Licensed under the Radix.pro License, Version 1.0 (the "License");
11c606a6 (kx 2023-04-11 01:18:34 +0300 7) you may not use this file except in compliance with the License.
11c606a6 (kx 2023-04-11 01:18:34 +0300 8) You may obtain a copy of the License at
11c606a6 (kx 2023-04-11 01:18:34 +0300 9)
11c606a6 (kx 2023-04-11 01:18:34 +0300 10) https://radix.pro/licenses/LICENSE-1.0-en_US.txt
11c606a6 (kx 2023-04-11 01:18:34 +0300 11)
11c606a6 (kx 2023-04-11 01:18:34 +0300 12) Unless required by applicable law or agreed to in writing, software
11c606a6 (kx 2023-04-11 01:18:34 +0300 13) distributed under the License is distributed on an "AS IS" BASIS,
11c606a6 (kx 2023-04-11 01:18:34 +0300 14) WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11c606a6 (kx 2023-04-11 01:18:34 +0300 15) implied.
11c606a6 (kx 2023-04-11 01:18:34 +0300 16)
11c606a6 (kx 2023-04-11 01:18:34 +0300 17) **********************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 18)
11c606a6 (kx 2023-04-11 01:18:34 +0300 19) #include <config.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 20)
11c606a6 (kx 2023-04-11 01:18:34 +0300 21) #include <stdlib.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 22) #include <stdio.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 23) #include <sys/types.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 24) #include <stdint.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 25) #include <dirent.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 26) #include <sys/stat.h> /* chmod(2) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 27) #include <sys/file.h> /* flock(2) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 28) #include <fcntl.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 29) #include <linux/limits.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 30) #include <alloca.h> /* alloca(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 31) #include <string.h> /* strdup(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 32) #include <strings.h> /* index(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 33) #include <libgen.h> /* basename(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 34) #include <ctype.h> /* tolower(3) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 35) #include <errno.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 36) #include <time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 37) #include <sys/time.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 38) #include <pwd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 39) #include <grp.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 40) #include <stdarg.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 41) #include <unistd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 42)
11c606a6 (kx 2023-04-11 01:18:34 +0300 43) #include <sys/wait.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 44)
11c606a6 (kx 2023-04-11 01:18:34 +0300 45) #include <sys/resource.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 46)
11c606a6 (kx 2023-04-11 01:18:34 +0300 47) #include <signal.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 48) #if !defined SIGCHLD && defined SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300 49) # define SIGCHLD SIGCLD
11c606a6 (kx 2023-04-11 01:18:34 +0300 50) #endif
11c606a6 (kx 2023-04-11 01:18:34 +0300 51)
11c606a6 (kx 2023-04-11 01:18:34 +0300 52) #define _GNU_SOURCE
11c606a6 (kx 2023-04-11 01:18:34 +0300 53) #include <getopt.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 54)
11c606a6 (kx 2023-04-11 01:18:34 +0300 55) #include <msglog.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 56) #include <wrapper.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 57) #include <system.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 58) #include <cmpvers.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 59)
11c606a6 (kx 2023-04-11 01:18:34 +0300 60) #define PROGRAM_NAME "check-package"
11c606a6 (kx 2023-04-11 01:18:34 +0300 61)
11c606a6 (kx 2023-04-11 01:18:34 +0300 62) #include <defs.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 63)
11c606a6 (kx 2023-04-11 01:18:34 +0300 64)
11c606a6 (kx 2023-04-11 01:18:34 +0300 65) char *program = PROGRAM_NAME;
11c606a6 (kx 2023-04-11 01:18:34 +0300 66) char *root = NULL, *pkgs_path = NULL, *pkg_fname = NULL, *pkg_found = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 67) *tmpdir = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 68)
11c606a6 (kx 2023-04-11 01:18:34 +0300 69) int quiet = 0, print_broken_files = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 70)
11c606a6 (kx 2023-04-11 01:18:34 +0300 71) int exit_status = EXIT_SUCCESS; /* errors counter */
11c606a6 (kx 2023-04-11 01:18:34 +0300 72) char *selfdir = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 73)
11c606a6 (kx 2023-04-11 01:18:34 +0300 74) static char *pkgname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 75) *pkgver = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 76) *arch = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 77) *distroname = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 78) *distrover = NULL,
11c606a6 (kx 2023-04-11 01:18:34 +0300 79) *group = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 80)
11c606a6 (kx 2023-04-11 01:18:34 +0300 81) static char *installed_version = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 82)
11c606a6 (kx 2023-04-11 01:18:34 +0300 83) enum _input_type {
11c606a6 (kx 2023-04-11 01:18:34 +0300 84) IFMT_PKG = 0,
11c606a6 (kx 2023-04-11 01:18:34 +0300 85) IFMT_LOG,
11c606a6 (kx 2023-04-11 01:18:34 +0300 86)
11c606a6 (kx 2023-04-11 01:18:34 +0300 87) IFMT_UNKNOWN
11c606a6 (kx 2023-04-11 01:18:34 +0300 88) } input_format = IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300 89)
11c606a6 (kx 2023-04-11 01:18:34 +0300 90)
11c606a6 (kx 2023-04-11 01:18:34 +0300 91) #define FREE_PKGINFO_VARIABLES() \
11c606a6 (kx 2023-04-11 01:18:34 +0300 92) if( pkgname ) { free( pkgname ); } pkgname = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300 93) if( pkgver ) { free( pkgver ); } pkgver = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300 94) if( arch ) { free( arch ); } arch = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300 95) if( distroname ) { free( distroname ); } distroname = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300 96) if( distrover ) { free( distrover ); } distrover = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300 97) if( group ) { free( group ); } group = NULL; \
11c606a6 (kx 2023-04-11 01:18:34 +0300 98) if( installed_version ) { free( installed_version ); } installed_version = NULL
11c606a6 (kx 2023-04-11 01:18:34 +0300 99)
11c606a6 (kx 2023-04-11 01:18:34 +0300 100) void free_resources()
11c606a6 (kx 2023-04-11 01:18:34 +0300 101) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 102) if( root ) { free( root ); root = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 103) if( pkgs_path ) { free( pkgs_path ); pkgs_path = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 104) if( pkg_fname ) { free( pkg_fname ); pkg_fname = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 105)
11c606a6 (kx 2023-04-11 01:18:34 +0300 106) if( selfdir ) { free( selfdir ); selfdir = NULL; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 107)
11c606a6 (kx 2023-04-11 01:18:34 +0300 108) FREE_PKGINFO_VARIABLES();
11c606a6 (kx 2023-04-11 01:18:34 +0300 109) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 110)
11c606a6 (kx 2023-04-11 01:18:34 +0300 111) void usage()
11c606a6 (kx 2023-04-11 01:18:34 +0300 112) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 113) free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 114)
11c606a6 (kx 2023-04-11 01:18:34 +0300 115) fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 116) fprintf( stdout, "Usage: %s [options] <package|pkglog|pkgname>\n", program );
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, "This utility checks if specified package is installed. If package\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 119) fprintf( stdout, "or some another version of this package is already installed then\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 120) fprintf( stdout, "this utility checks if installed package is correct.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 121) fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 122) fprintf( stdout, "Options:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 123) fprintf( stdout, " -h,--help Display this information.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 124) fprintf( stdout, " -v,--version Display the version of %s utility.\n", program );
11c606a6 (kx 2023-04-11 01:18:34 +0300 125) fprintf( stdout, " -p,--print-broken-files Print the list of broken directories,\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 126) fprintf( stdout, " files, or symbolic links to stdout.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 127) fprintf( stdout, " -q,--quiet Do not display explanations for\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 128) fprintf( stdout, " return codes.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 129) fprintf( stdout, " -r,--root=<DIR> Target rootfs path.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 130) fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 131) fprintf( stdout, "Parameter:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 132) fprintf( stdout, " <package|pkglog|pkgname> The PKGNAME, PACKAGE tarball or PKGLOG.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 133) fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 134) fprintf( stdout, "Return codes:\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 135) fprintf( stdout, " ------+---------------------------+--------------------\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 136) fprintf( stdout, " code | status | what can be done\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 137) fprintf( stdout, " ------+---------------------------+--------------------\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 138) fprintf( stdout, " 30 | not installed | install\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 139) fprintf( stdout, " 31 | installed correctly | nothing to do\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 140) fprintf( stdout, " 32 | installed but not correct | repair, re-install\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 141) fprintf( stdout, " 33 | installed correctly | upgrade\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 142) fprintf( stdout, " 34 | installed but not correct | repair, upgrade\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 143) fprintf( stdout, " 35 | installed correctly | downgrade\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 144) fprintf( stdout, " 36 | installed but not correct | repair, downgrade\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 145) fprintf( stdout, " ------+---------------------------+--------------------\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 146) fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 147) fprintf( stdout, "Other non-zero codes assumes that this utility faced to errors not\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 148) fprintf( stdout, "related to quality of installed package.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 149) fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 150) fprintf( stdout, "If package specified by short name (probably with version) instead\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 151) fprintf( stdout, "of regular files such as package tarball or pkglog file then this\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 152) fprintf( stdout, "utility doesn't check other installed versions of this package.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 153) fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 154)
11c606a6 (kx 2023-04-11 01:18:34 +0300 155) exit( EXIT_FAILURE );
11c606a6 (kx 2023-04-11 01:18:34 +0300 156) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 157)
11c606a6 (kx 2023-04-11 01:18:34 +0300 158) void to_lowercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 159) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 160) char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 161) while( p && *p ) { int c = *p; *p = tolower( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 162) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 163)
11c606a6 (kx 2023-04-11 01:18:34 +0300 164) void to_uppercase( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 165) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 166) char *p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 167) while( p && *p ) { int c = *p; *p = toupper( c ); ++p; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 168) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 169)
11c606a6 (kx 2023-04-11 01:18:34 +0300 170) void version()
11c606a6 (kx 2023-04-11 01:18:34 +0300 171) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 172) char *upper = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 173)
11c606a6 (kx 2023-04-11 01:18:34 +0300 174) upper = (char *)alloca( strlen( program ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 175)
11c606a6 (kx 2023-04-11 01:18:34 +0300 176) strcpy( (char *)upper, (const char *)program );
11c606a6 (kx 2023-04-11 01:18:34 +0300 177) to_uppercase( upper );
11c606a6 (kx 2023-04-11 01:18:34 +0300 178)
11c606a6 (kx 2023-04-11 01:18:34 +0300 179) fprintf( stdout, "%s (%s) %s\n", program, upper, PROGRAM_VERSION );
11c606a6 (kx 2023-04-11 01:18:34 +0300 180)
11c606a6 (kx 2023-04-11 01:18:34 +0300 181) fprintf( stdout, "Copyright (C) 2019 Andrey V.Kosteltsev.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 182) fprintf( stdout, "This is free software. There is NO warranty; not even\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 183) fprintf( stdout, "for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 184) fprintf( stdout, "\n" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 185)
11c606a6 (kx 2023-04-11 01:18:34 +0300 186) free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 187) exit( EXIT_SUCCESS );
11c606a6 (kx 2023-04-11 01:18:34 +0300 188) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 189)
11c606a6 (kx 2023-04-11 01:18:34 +0300 190)
11c606a6 (kx 2023-04-11 01:18:34 +0300 191) static void remove_trailing_slash( char *dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 192) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 193) char *s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 194)
11c606a6 (kx 2023-04-11 01:18:34 +0300 195) if( !dir || dir[0] == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 196)
11c606a6 (kx 2023-04-11 01:18:34 +0300 197) s = dir + strlen( dir ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 198) while( *s == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 199) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 200) *s = '\0'; --s;
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)
11c606a6 (kx 2023-04-11 01:18:34 +0300 205) static int _mkdir_p( const char *dir, const mode_t mode )
11c606a6 (kx 2023-04-11 01:18:34 +0300 206) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 207) char *buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300 208) char *p = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 209) struct stat sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 210)
11c606a6 (kx 2023-04-11 01:18:34 +0300 211) if( !dir ) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 212)
11c606a6 (kx 2023-04-11 01:18:34 +0300 213) buf = (char *)alloca( strlen( dir ) + 1 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 214) strcpy( buf, dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 215)
11c606a6 (kx 2023-04-11 01:18:34 +0300 216) remove_trailing_slash( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 217)
11c606a6 (kx 2023-04-11 01:18:34 +0300 218) /* check if path exists and is a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 219) if( stat( buf, &sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 220) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 221) if( S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 222) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 223) return 0;
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) /* mkdir -p */
11c606a6 (kx 2023-04-11 01:18:34 +0300 228) for( p = buf + 1; *p; ++p )
11c606a6 (kx 2023-04-11 01:18:34 +0300 229) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 230) if( *p == '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 231) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 232) *p = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 233) /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300 234) if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 235) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 236) /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 237) if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 238) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 239) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 240) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 241) } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 242) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 243) /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 244) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 245) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 246) *p = '/';
11c606a6 (kx 2023-04-11 01:18:34 +0300 247) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 248) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 249)
11c606a6 (kx 2023-04-11 01:18:34 +0300 250) /* test path */
11c606a6 (kx 2023-04-11 01:18:34 +0300 251) if( stat( buf, &sb ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 252) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 253) /* path does not exist - create directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 254) if( mkdir( buf, mode ) < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 255) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 256) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 257) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 258) } else if( !S_ISDIR(sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 259) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 260) /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 261) return -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 262) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 263)
11c606a6 (kx 2023-04-11 01:18:34 +0300 264) return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 265) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 266)
11c606a6 (kx 2023-04-11 01:18:34 +0300 267) static void _rm_tmpdir( const char *dirpath )
11c606a6 (kx 2023-04-11 01:18:34 +0300 268) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 269) DIR *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 270) char *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 271) size_t len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 272)
11c606a6 (kx 2023-04-11 01:18:34 +0300 273) struct stat path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 274) struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 275)
11c606a6 (kx 2023-04-11 01:18:34 +0300 276) if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 277) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 278) return; /* stat returns error code; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300 279) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 280)
11c606a6 (kx 2023-04-11 01:18:34 +0300 281) if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 282) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 283) return; /* dirpath is not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 284) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 285)
11c606a6 (kx 2023-04-11 01:18:34 +0300 286) if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 287) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 288) return; /* Cannot open direcroty; errno is set */
11c606a6 (kx 2023-04-11 01:18:34 +0300 289) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 290)
11c606a6 (kx 2023-04-11 01:18:34 +0300 291) len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 292)
11c606a6 (kx 2023-04-11 01:18:34 +0300 293) while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 294) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 295)
11c606a6 (kx 2023-04-11 01:18:34 +0300 296) /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 297) if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 298)
11c606a6 (kx 2023-04-11 01:18:34 +0300 299) /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 300) path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 301) strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 302) strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 303) strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 304)
11c606a6 (kx 2023-04-11 01:18:34 +0300 305) if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 306) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 307) if( S_ISDIR(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 308) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 309) /* recursively remove a nested directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 310) _rm_tmpdir( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 311) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 312) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 313) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 314) /* remove a file object */
11c606a6 (kx 2023-04-11 01:18:34 +0300 315) (void)unlink( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 316) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 317) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 318) /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 319)
11c606a6 (kx 2023-04-11 01:18:34 +0300 320) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 321)
11c606a6 (kx 2023-04-11 01:18:34 +0300 322) /* remove the devastated directory and close the object of this directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 323) (void)rmdir( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 324)
11c606a6 (kx 2023-04-11 01:18:34 +0300 325) closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 326) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 327)
11c606a6 (kx 2023-04-11 01:18:34 +0300 328) static char *_mk_tmpdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 329) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 330) char *buf = NULL, *p, *tmp = "/tmp";
11c606a6 (kx 2023-04-11 01:18:34 +0300 331) size_t len = 0, size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 332)
11c606a6 (kx 2023-04-11 01:18:34 +0300 333) (void)umask( S_IWGRP | S_IWOTH ); /* octal 022 */
11c606a6 (kx 2023-04-11 01:18:34 +0300 334)
11c606a6 (kx 2023-04-11 01:18:34 +0300 335) /* Get preferred directory for tmp files */
11c606a6 (kx 2023-04-11 01:18:34 +0300 336) if( (p = getenv( "TMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 337) tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 338) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 339) else if( (p = getenv( "TEMP" )) != NULL ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 340) tmp = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 341) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 342)
11c606a6 (kx 2023-04-11 01:18:34 +0300 343) size = strlen( tmp ) + strlen( DISTRO_NAME ) + strlen( program ) + 12;
11c606a6 (kx 2023-04-11 01:18:34 +0300 344)
11c606a6 (kx 2023-04-11 01:18:34 +0300 345) buf = (char *)malloc( size );
11c606a6 (kx 2023-04-11 01:18:34 +0300 346) if( !buf ) return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 347)
11c606a6 (kx 2023-04-11 01:18:34 +0300 348) len = snprintf( buf, size, (const char *)"%s/%s/%s-%.7u", tmp, DISTRO_NAME, program, getpid() );
11c606a6 (kx 2023-04-11 01:18:34 +0300 349) if( len == 0 || len == size - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 350) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 351) free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 352) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 353)
11c606a6 (kx 2023-04-11 01:18:34 +0300 354) _rm_tmpdir( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 355)
11c606a6 (kx 2023-04-11 01:18:34 +0300 356) if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 357) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 358) return buf;
11c606a6 (kx 2023-04-11 01:18:34 +0300 359) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 360)
11c606a6 (kx 2023-04-11 01:18:34 +0300 361) free( buf ); return NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 362) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 363)
11c606a6 (kx 2023-04-11 01:18:34 +0300 364)
11c606a6 (kx 2023-04-11 01:18:34 +0300 365) void fatal_error_actions( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 366) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 367) logmsg( errlog, MSG_NOTICE, "Free resources on FATAL error..." );
11c606a6 (kx 2023-04-11 01:18:34 +0300 368) if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 369) free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 370) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 371)
11c606a6 (kx 2023-04-11 01:18:34 +0300 372) void sigint( int signum )
11c606a6 (kx 2023-04-11 01:18:34 +0300 373) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 374) (void)signum;
11c606a6 (kx 2023-04-11 01:18:34 +0300 375)
11c606a6 (kx 2023-04-11 01:18:34 +0300 376) if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 377) free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 378) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 379)
11c606a6 (kx 2023-04-11 01:18:34 +0300 380) static void set_signal_handlers()
11c606a6 (kx 2023-04-11 01:18:34 +0300 381) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 382) struct sigaction sa;
11c606a6 (kx 2023-04-11 01:18:34 +0300 383) sigset_t set;
11c606a6 (kx 2023-04-11 01:18:34 +0300 384)
11c606a6 (kx 2023-04-11 01:18:34 +0300 385) memset( &sa, 0, sizeof( sa ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 386) sa.sa_handler = sigint; /* TERM, INT */
11c606a6 (kx 2023-04-11 01:18:34 +0300 387) sa.sa_flags = SA_RESTART;
11c606a6 (kx 2023-04-11 01:18:34 +0300 388) sigemptyset( &set );
11c606a6 (kx 2023-04-11 01:18:34 +0300 389) sigaddset( &set, SIGTERM );
11c606a6 (kx 2023-04-11 01:18:34 +0300 390) sigaddset( &set, SIGINT );
11c606a6 (kx 2023-04-11 01:18:34 +0300 391) sa.sa_mask = set;
11c606a6 (kx 2023-04-11 01:18:34 +0300 392) sigaction( SIGTERM, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 393) sigaction( SIGINT, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 394)
11c606a6 (kx 2023-04-11 01:18:34 +0300 395) memset( &sa, 0, sizeof( sa ) ); /* ignore SIGPIPE */
11c606a6 (kx 2023-04-11 01:18:34 +0300 396) sa.sa_handler = SIG_IGN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 397) sa.sa_flags = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 398) sigaction( SIGPIPE, &sa, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 399)
11c606a6 (kx 2023-04-11 01:18:34 +0300 400) /* System V fork+wait does not work if SIGCHLD is ignored */
11c606a6 (kx 2023-04-11 01:18:34 +0300 401) signal( SIGCHLD, SIG_DFL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 402) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 403)
11c606a6 (kx 2023-04-11 01:18:34 +0300 404)
11c606a6 (kx 2023-04-11 01:18:34 +0300 405) static enum _input_type check_input_file( char *uncompress, const char *fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 406) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 407) struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 408) size_t pkglog_size = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 409) unsigned char buf[8];
11c606a6 (kx 2023-04-11 01:18:34 +0300 410) int rc, fd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 411)
11c606a6 (kx 2023-04-11 01:18:34 +0300 412) /* SIGNATURES: https://www.garykessler.net/library/file_sigs.html */
11c606a6 (kx 2023-04-11 01:18:34 +0300 413)
11c606a6 (kx 2023-04-11 01:18:34 +0300 414) if( uncompress )
11c606a6 (kx 2023-04-11 01:18:34 +0300 415) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 416) *uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 417) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 418)
11c606a6 (kx 2023-04-11 01:18:34 +0300 419) if( stat( fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 420) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 421) FATAL_ERROR( "Cannot access %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 422) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 423)
11c606a6 (kx 2023-04-11 01:18:34 +0300 424) pkglog_size = st.st_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 425)
11c606a6 (kx 2023-04-11 01:18:34 +0300 426) if( (fd = open( fname, O_RDONLY )) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 427) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 428) FATAL_ERROR( "Cannot open %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 429) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 430)
11c606a6 (kx 2023-04-11 01:18:34 +0300 431) rc = (int)read( fd, (void *)&buf[0], 7 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 432) if( rc != 7 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 433) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 434) close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 435) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 436) buf[7] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 437)
11c606a6 (kx 2023-04-11 01:18:34 +0300 438) /* TEXT */
11c606a6 (kx 2023-04-11 01:18:34 +0300 439) if( !strncmp( (const char *)&buf[0], "PACKAGE", 7 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 440) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 441) close( fd ); return IFMT_LOG;
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) /* GZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300 445) if( buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x08 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 446) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 447) if( uncompress ) { *uncompress = 'x'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 448) close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300 449) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 450)
11c606a6 (kx 2023-04-11 01:18:34 +0300 451) /* BZ2 */
11c606a6 (kx 2023-04-11 01:18:34 +0300 452) if( buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 453) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 454) if( uncompress ) { *uncompress = 'j'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 455) close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300 456) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 457)
11c606a6 (kx 2023-04-11 01:18:34 +0300 458) /* XZ */
11c606a6 (kx 2023-04-11 01:18:34 +0300 459) if( buf[0] == 0xFD && buf[1] == 0x37 && buf[2] == 0x7A &&
11c606a6 (kx 2023-04-11 01:18:34 +0300 460) buf[3] == 0x58 && buf[4] == 0x5A && buf[5] == 0x00 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 461) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 462) if( uncompress ) { *uncompress = 'J'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 463) close( fd ); return IFMT_PKG;
11c606a6 (kx 2023-04-11 01:18:34 +0300 464) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 465)
11c606a6 (kx 2023-04-11 01:18:34 +0300 466) if( pkglog_size > 262 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 467) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 468) if( lseek( fd, 257, SEEK_SET ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 469) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 470) FATAL_ERROR( "Cannot check signature of %s file: %s", basename( (char *)fname ), strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 471) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 472) rc = (int)read( fd, &buf[0], 5 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 473) if( rc != 5 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 474) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 475) FATAL_ERROR( "Cannot read signature of %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 476) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 477) /* TAR */
11c606a6 (kx 2023-04-11 01:18:34 +0300 478) 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 479) {
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)
11c606a6 (kx 2023-04-11 01:18:34 +0300 484) close( fd ); return IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 485) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 486)
11c606a6 (kx 2023-04-11 01:18:34 +0300 487)
11c606a6 (kx 2023-04-11 01:18:34 +0300 488) void get_args( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300 489) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 490) const char* short_options = "hvpqr:";
11c606a6 (kx 2023-04-11 01:18:34 +0300 491)
11c606a6 (kx 2023-04-11 01:18:34 +0300 492) const struct option long_options[] =
11c606a6 (kx 2023-04-11 01:18:34 +0300 493) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 494) { "help", no_argument, NULL, 'h' },
11c606a6 (kx 2023-04-11 01:18:34 +0300 495) { "version", no_argument, NULL, 'v' },
11c606a6 (kx 2023-04-11 01:18:34 +0300 496) { "print-broken-files", no_argument, NULL, 'p' },
11c606a6 (kx 2023-04-11 01:18:34 +0300 497) { "quiet", no_argument, NULL, 'q' },
11c606a6 (kx 2023-04-11 01:18:34 +0300 498) { "root", required_argument, NULL, 'r' },
11c606a6 (kx 2023-04-11 01:18:34 +0300 499) { NULL, 0, NULL, 0 }
11c606a6 (kx 2023-04-11 01:18:34 +0300 500) };
11c606a6 (kx 2023-04-11 01:18:34 +0300 501)
11c606a6 (kx 2023-04-11 01:18:34 +0300 502) int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 503) int option_index = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 504)
11c606a6 (kx 2023-04-11 01:18:34 +0300 505) while( (ret = getopt_long( argc, argv, short_options, long_options, &option_index )) != -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 506) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 507) switch( ret )
11c606a6 (kx 2023-04-11 01:18:34 +0300 508) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 509) case 'h':
11c606a6 (kx 2023-04-11 01:18:34 +0300 510) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 511) usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300 512) break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 513) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 514) case 'v':
11c606a6 (kx 2023-04-11 01:18:34 +0300 515) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 516) version();
11c606a6 (kx 2023-04-11 01:18:34 +0300 517) break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 518) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 519) case 'p':
11c606a6 (kx 2023-04-11 01:18:34 +0300 520) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 521) print_broken_files = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 522) break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 523) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 524) case 'q':
11c606a6 (kx 2023-04-11 01:18:34 +0300 525) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 526) quiet = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 527) break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 528) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 529)
11c606a6 (kx 2023-04-11 01:18:34 +0300 530) case 'r':
11c606a6 (kx 2023-04-11 01:18:34 +0300 531) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 532) if( optarg != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 533) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 534) root = xstrdup( (const char *)optarg );
11c606a6 (kx 2023-04-11 01:18:34 +0300 535) remove_trailing_slash( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300 536) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 537) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 538) /* option is present but without value */
11c606a6 (kx 2023-04-11 01:18:34 +0300 539) usage();
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 '?': default:
11c606a6 (kx 2023-04-11 01:18:34 +0300 544) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 545) usage();
11c606a6 (kx 2023-04-11 01:18:34 +0300 546) break;
11c606a6 (kx 2023-04-11 01:18:34 +0300 547) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 548) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 549) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 550)
11c606a6 (kx 2023-04-11 01:18:34 +0300 551)
11c606a6 (kx 2023-04-11 01:18:34 +0300 552) if( optind < argc )
11c606a6 (kx 2023-04-11 01:18:34 +0300 553) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 554) pkg_fname = xstrdup( (const char *)argv[optind] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 555) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 556) else
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) }
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) if( !pkgs_path )
11c606a6 (kx 2023-04-11 01:18:34 +0300 563) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 564) struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 565) char *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 566)
11c606a6 (kx 2023-04-11 01:18:34 +0300 567) bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 568)
11c606a6 (kx 2023-04-11 01:18:34 +0300 569) buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 570) if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 571) bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 572)
11c606a6 (kx 2023-04-11 01:18:34 +0300 573) if( !root )
11c606a6 (kx 2023-04-11 01:18:34 +0300 574) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 575) buf[0] = '/'; buf[1] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 576) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 577) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 578) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 579) int len = strlen( root );
11c606a6 (kx 2023-04-11 01:18:34 +0300 580)
11c606a6 (kx 2023-04-11 01:18:34 +0300 581) (void)strcpy( buf, (const char *)root );
11c606a6 (kx 2023-04-11 01:18:34 +0300 582) if( buf[ len - 1 ] != '/' )
11c606a6 (kx 2023-04-11 01:18:34 +0300 583) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 584) buf[len] = '/'; buf[len+1] = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 585) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 586) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 587)
11c606a6 (kx 2023-04-11 01:18:34 +0300 588) (void)strcat( buf, PACKAGES_PATH );
11c606a6 (kx 2023-04-11 01:18:34 +0300 589) if( stat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 590) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 591) FATAL_ERROR( "Cannot access '%s' file or directory: %s", buf, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 592) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 593)
11c606a6 (kx 2023-04-11 01:18:34 +0300 594) if( S_ISDIR(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 595) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 596) pkgs_path = xstrdup( (const char *)&buf[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 597) free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 598) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 599) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 600) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 601) FATAL_ERROR( "Defined --root '%s' is not a directory", buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 602) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 603)
11c606a6 (kx 2023-04-11 01:18:34 +0300 604) } /* End if( !pkgs_path ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 605) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 606)
11c606a6 (kx 2023-04-11 01:18:34 +0300 607)
11c606a6 (kx 2023-04-11 01:18:34 +0300 608) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 609) Remove leading spaces and take non-space characters only:
11c606a6 (kx 2023-04-11 01:18:34 +0300 610) (Especialy for pkginfo lines)
11c606a6 (kx 2023-04-11 01:18:34 +0300 611) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 612) static char *skip_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 613) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 614) char *q, *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 615)
11c606a6 (kx 2023-04-11 01:18:34 +0300 616) if( !s || *s == '\0' ) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 617)
11c606a6 (kx 2023-04-11 01:18:34 +0300 618) p = s;
11c606a6 (kx 2023-04-11 01:18:34 +0300 619)
11c606a6 (kx 2023-04-11 01:18:34 +0300 620) while( (*p == ' ' || *p == '\t') && *p != '\0' ) { ++p; } q = p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 621) while( *q != ' ' && *q != '\t' && *q != '\0' ) { ++q; } *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 622)
11c606a6 (kx 2023-04-11 01:18:34 +0300 623) if( *p == '\0' ) return (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 624)
11c606a6 (kx 2023-04-11 01:18:34 +0300 625) return( xstrdup( (const char *)p ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 626) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 627)
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) remove spaces at end of line:
11c606a6 (kx 2023-04-11 01:18:34 +0300 631) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 632) static void skip_eol_spaces( char *s )
11c606a6 (kx 2023-04-11 01:18:34 +0300 633) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 634) char *p = (char *)0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 635)
11c606a6 (kx 2023-04-11 01:18:34 +0300 636) if( !s || *s == '\0' ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 637)
11c606a6 (kx 2023-04-11 01:18:34 +0300 638) p = s + strlen( s ) - 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 639) while( isspace( *p ) ) { *p-- = '\0'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 640) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 641)
11c606a6 (kx 2023-04-11 01:18:34 +0300 642)
11c606a6 (kx 2023-04-11 01:18:34 +0300 643) /***************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 644) Probe functions:
11c606a6 (kx 2023-04-11 01:18:34 +0300 645) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 646) static void _probe_pkglog( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 647) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 648) DIR *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 649) char *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 650) size_t len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 651)
11c606a6 (kx 2023-04-11 01:18:34 +0300 652) struct stat path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 653) struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 654)
11c606a6 (kx 2023-04-11 01:18:34 +0300 655) if( pkg_found ) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 656)
11c606a6 (kx 2023-04-11 01:18:34 +0300 657) if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 658) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 659) FATAL_ERROR( "%s: Cannot stat Setup Database or destination directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 660) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 661)
11c606a6 (kx 2023-04-11 01:18:34 +0300 662) if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 663) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 664) FATAL_ERROR( "%s: Setup Database or destination is not a directory", dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 665) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 666)
11c606a6 (kx 2023-04-11 01:18:34 +0300 667) if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 668) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 669) FATAL_ERROR( "Canot access %s directory: %s", dirpath, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 670) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 671)
11c606a6 (kx 2023-04-11 01:18:34 +0300 672) len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 673)
11c606a6 (kx 2023-04-11 01:18:34 +0300 674) while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 675) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 676) /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 677) if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 678)
11c606a6 (kx 2023-04-11 01:18:34 +0300 679) /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 680) path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 681)
11c606a6 (kx 2023-04-11 01:18:34 +0300 682) strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 683) strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 684) strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 685)
11c606a6 (kx 2023-04-11 01:18:34 +0300 686) if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 687) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 688) if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 689) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 690) char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 691) char *pkglog = basename( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 692)
11c606a6 (kx 2023-04-11 01:18:34 +0300 693) if( (match = strstr( pkglog, (const char *)basename( pkg_fname ) )) && match == pkglog )
11c606a6 (kx 2023-04-11 01:18:34 +0300 694) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 695) char *buf = NULL, *p = NULL, *q = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 696)
11c606a6 (kx 2023-04-11 01:18:34 +0300 697) p = q = buf = xstrdup( (const char *)pkglog );
11c606a6 (kx 2023-04-11 01:18:34 +0300 698) ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 699) while( *p != '\0' && !isblank(*p) && !(*q == '-' && isdigit(*p)) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 700) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 701) /* package version starts with a number and separated by '-' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 702) ++p; ++q;
11c606a6 (kx 2023-04-11 01:18:34 +0300 703) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 704) *(--p) = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 705)
11c606a6 (kx 2023-04-11 01:18:34 +0300 706) /*******************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 707) We have to make sure that the name we are looking for
11c606a6 (kx 2023-04-11 01:18:34 +0300 708) is not shorter than the name of the found package.
11c606a6 (kx 2023-04-11 01:18:34 +0300 709) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 710) if( strlen(pkg_fname) >= strlen(buf) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 711) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 712)
11c606a6 (kx 2023-04-11 01:18:34 +0300 713) pkg_found = xstrdup( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 714) free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 715) closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 716) return;
11c606a6 (kx 2023-04-11 01:18:34 +0300 717) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 718) free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 719) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 720) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 721) if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 722) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 723) _probe_pkglog( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 724) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 725) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 726) /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 727) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 728)
11c606a6 (kx 2023-04-11 01:18:34 +0300 729) closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 730) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 731)
11c606a6 (kx 2023-04-11 01:18:34 +0300 732) /***********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 733) probe_package():
11c606a6 (kx 2023-04-11 01:18:34 +0300 734) ---------------
11c606a6 (kx 2023-04-11 01:18:34 +0300 735) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 736) char *probe_package( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 737) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 738) char *ret = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 739)
11c606a6 (kx 2023-04-11 01:18:34 +0300 740) _probe_pkglog( (const char *)pkgs_path, NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 741) if( pkg_found )
11c606a6 (kx 2023-04-11 01:18:34 +0300 742) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 743) free( pkg_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 744) ret = pkg_fname = pkg_found;
11c606a6 (kx 2023-04-11 01:18:34 +0300 745) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 746)
11c606a6 (kx 2023-04-11 01:18:34 +0300 747) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 748) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 749) /*
11c606a6 (kx 2023-04-11 01:18:34 +0300 750) Enf of Probe functions.
11c606a6 (kx 2023-04-11 01:18:34 +0300 751) ***********************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 752)
11c606a6 (kx 2023-04-11 01:18:34 +0300 753)
11c606a6 (kx 2023-04-11 01:18:34 +0300 754)
11c606a6 (kx 2023-04-11 01:18:34 +0300 755) static void read_input_pkginfo( const char *pkginfo_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 756) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 757) char *ln = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 758) char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 759)
11c606a6 (kx 2023-04-11 01:18:34 +0300 760) FILE *pkginfo = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 761)
11c606a6 (kx 2023-04-11 01:18:34 +0300 762) if( pkginfo_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 763) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 764) pkginfo = fopen( (const char *)pkginfo_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 765) if( !pkginfo )
11c606a6 (kx 2023-04-11 01:18:34 +0300 766) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 767) FATAL_ERROR( "Cannot open %s file", pkginfo_fname );
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)
11c606a6 (kx 2023-04-11 01:18:34 +0300 771) line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 772) if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 773) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 774) FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 775) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 776)
11c606a6 (kx 2023-04-11 01:18:34 +0300 777) while( (ln = fgets( line, PATH_MAX, pkginfo )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 778) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 779) char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 780)
11c606a6 (kx 2023-04-11 01:18:34 +0300 781) ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 782) skip_eol_spaces( ln ); /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 783)
11c606a6 (kx 2023-04-11 01:18:34 +0300 784) if( (match = strstr( ln, "pkgname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 785) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 786) if( p != NULL ) pkgname = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 787) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 788) if( (match = strstr( ln, "pkgver" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 789) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 790) if( p != NULL ) pkgver = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 791) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 792) if( (match = strstr( ln, "arch" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 793) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 794) if( p != NULL ) arch = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 795) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 796) if( (match = strstr( ln, "distroname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 797) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 798) if( p != NULL ) distroname = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 799) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 800) if( (match = strstr( ln, "distrover" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 801) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 802) if( p != NULL ) distrover = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 803) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 804)
11c606a6 (kx 2023-04-11 01:18:34 +0300 805) if( (match = strstr( ln, "group" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 806) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 807) if( p != NULL ) group = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 808) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 809) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 810)
11c606a6 (kx 2023-04-11 01:18:34 +0300 811) free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 812)
11c606a6 (kx 2023-04-11 01:18:34 +0300 813) if( !pkgname || !pkgver || !arch || !distroname || !distrover )
11c606a6 (kx 2023-04-11 01:18:34 +0300 814) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 815) FATAL_ERROR( "Invalid input .PKGINFO file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 816) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 817)
11c606a6 (kx 2023-04-11 01:18:34 +0300 818) fclose( pkginfo );
11c606a6 (kx 2023-04-11 01:18:34 +0300 819) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 820)
11c606a6 (kx 2023-04-11 01:18:34 +0300 821) static void read_found_pkginfo( const char *pkginfo_fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 822) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 823) char *ln = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 824) char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 825)
11c606a6 (kx 2023-04-11 01:18:34 +0300 826) FILE *pkginfo = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 827)
11c606a6 (kx 2023-04-11 01:18:34 +0300 828) char *pn = NULL, *pv = NULL, *ar = NULL, *dn = NULL, *dv = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 829)
11c606a6 (kx 2023-04-11 01:18:34 +0300 830) if( pkginfo_fname != NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 831) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 832) pkginfo = fopen( (const char *)pkginfo_fname, "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 833) if( !pkginfo )
11c606a6 (kx 2023-04-11 01:18:34 +0300 834) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 835) FATAL_ERROR( "Cannot open %s file", pkginfo_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 836) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 837) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 838)
11c606a6 (kx 2023-04-11 01:18:34 +0300 839) line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 840) if( !line )
11c606a6 (kx 2023-04-11 01:18:34 +0300 841) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 842) FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 843) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 844)
11c606a6 (kx 2023-04-11 01:18:34 +0300 845) while( (ln = fgets( line, PATH_MAX, pkginfo )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 846) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 847) char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 848)
11c606a6 (kx 2023-04-11 01:18:34 +0300 849) ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 850) skip_eol_spaces( ln ); /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 851)
11c606a6 (kx 2023-04-11 01:18:34 +0300 852) if( (match = strstr( ln, "pkgname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 853) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 854) if( p != NULL ) pn = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 855) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 856) if( (match = strstr( ln, "pkgver" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 857) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 858) if( p != NULL ) pv = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 859) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 860) if( (match = strstr( ln, "arch" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 861) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 862) if( p != NULL ) ar = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 863) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 864) if( (match = strstr( ln, "distroname" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 865) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 866) if( p != NULL ) dn = skip_spaces( p );
11c606a6 (kx 2023-04-11 01:18:34 +0300 867) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 868) if( (match = strstr( ln, "distrover" )) && match == ln ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 869) char *p = index( match, '=' ) + 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 870) if( p != NULL ) dv = skip_spaces( p );
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)
11c606a6 (kx 2023-04-11 01:18:34 +0300 874) free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 875)
11c606a6 (kx 2023-04-11 01:18:34 +0300 876) if( !pn || !pv || !ar || !dn || !dv )
11c606a6 (kx 2023-04-11 01:18:34 +0300 877) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 878) FATAL_ERROR( "Invalid input .PKGINFO file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 879) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 880) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 881) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 882) if( pn ) free( pn );
11c606a6 (kx 2023-04-11 01:18:34 +0300 883) if( pv ) installed_version = pv;
11c606a6 (kx 2023-04-11 01:18:34 +0300 884) if( ar ) free( ar );
11c606a6 (kx 2023-04-11 01:18:34 +0300 885) if( dn ) free( dn );
11c606a6 (kx 2023-04-11 01:18:34 +0300 886) if( dv ) free( dv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 887) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 888)
11c606a6 (kx 2023-04-11 01:18:34 +0300 889) fclose( pkginfo );
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) static void _get_found_pkginfo( const char *pkglog )
11c606a6 (kx 2023-04-11 01:18:34 +0300 893) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 894) pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 895) int rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 896)
11c606a6 (kx 2023-04-11 01:18:34 +0300 897) int len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 898) char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 899)
11c606a6 (kx 2023-04-11 01:18:34 +0300 900) tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 901) if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 902) bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 903)
11c606a6 (kx 2023-04-11 01:18:34 +0300 904) (void)sprintf( &tmp[0], "%s", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 905) if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 906) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 907) FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)pkglog ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 908) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 909)
11c606a6 (kx 2023-04-11 01:18:34 +0300 910) cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 911) if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 912) bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 913)
11c606a6 (kx 2023-04-11 01:18:34 +0300 914) len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 915) "%s/pkginfo -d %s -o pkginfo,restore-links,filelist %s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 916) selfdir, tmp, pkglog );
11c606a6 (kx 2023-04-11 01:18:34 +0300 917) if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 918) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 919) FATAL_ERROR( "Cannot get PKGINFO from %s file", basename( (char *)pkglog ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 920) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 921) p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 922) rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 923) if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 924) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 925) FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)pkglog ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 926) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 927)
11c606a6 (kx 2023-04-11 01:18:34 +0300 928) (void)strcat( tmp, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 929) read_found_pkginfo( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 930) *(strstr( tmp, "/.PKGINFO" )) = '\0'; /* :restore tmpdir in tmp[] buffer */
11c606a6 (kx 2023-04-11 01:18:34 +0300 931)
11c606a6 (kx 2023-04-11 01:18:34 +0300 932) free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 933) free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 934) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 935)
11c606a6 (kx 2023-04-11 01:18:34 +0300 936) static void _search_pkglog( const char *dirpath, const char *grp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 937) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 938) DIR *dir;
11c606a6 (kx 2023-04-11 01:18:34 +0300 939) char *path;
11c606a6 (kx 2023-04-11 01:18:34 +0300 940) size_t len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 941)
11c606a6 (kx 2023-04-11 01:18:34 +0300 942) struct stat path_sb, entry_sb;
11c606a6 (kx 2023-04-11 01:18:34 +0300 943) struct dirent *entry;
11c606a6 (kx 2023-04-11 01:18:34 +0300 944)
11c606a6 (kx 2023-04-11 01:18:34 +0300 945) char *pname = (char *)dirpath + strlen( root ); /* do not remove leading '/' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 946)
11c606a6 (kx 2023-04-11 01:18:34 +0300 947) if( stat( dirpath, &path_sb ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 948) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 949) FATAL_ERROR( "%s: Cannot stat Setup Database or group directory", pname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 950) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 951)
11c606a6 (kx 2023-04-11 01:18:34 +0300 952) if( S_ISDIR(path_sb.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 953) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 954) FATAL_ERROR( "%s: Setup Database or group is not a directory", pname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 955) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 956)
11c606a6 (kx 2023-04-11 01:18:34 +0300 957) if( (dir = opendir(dirpath) ) == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 958) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 959) FATAL_ERROR( "Canot access %s directory: %s", pname, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 960) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 961)
11c606a6 (kx 2023-04-11 01:18:34 +0300 962) len = strlen( dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 963)
11c606a6 (kx 2023-04-11 01:18:34 +0300 964) while( (entry = readdir( dir )) != NULL)
11c606a6 (kx 2023-04-11 01:18:34 +0300 965) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 966) /* skip entries '.' and '..' */
11c606a6 (kx 2023-04-11 01:18:34 +0300 967) if( ! strcmp( entry->d_name, "." ) || ! strcmp( entry->d_name, ".." ) ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 968)
11c606a6 (kx 2023-04-11 01:18:34 +0300 969) /* determinate a full name of an entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 970) path = alloca( len + strlen( entry->d_name ) + 2 );
11c606a6 (kx 2023-04-11 01:18:34 +0300 971)
11c606a6 (kx 2023-04-11 01:18:34 +0300 972) strcpy( path, dirpath );
11c606a6 (kx 2023-04-11 01:18:34 +0300 973) strcat( path, "/" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 974) strcat( path, entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 975)
11c606a6 (kx 2023-04-11 01:18:34 +0300 976) if( stat( path, &entry_sb ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 977) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 978) if( S_ISREG(entry_sb.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 979) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 980) char *match = NULL, *name = basename( path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 981)
11c606a6 (kx 2023-04-11 01:18:34 +0300 982) if( (match = strstr( name, pkgname )) && match == name )
11c606a6 (kx 2023-04-11 01:18:34 +0300 983) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 984) /****************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 985) Здесь мы еще должны проверить, что найденный пакет не имеет
11c606a6 (kx 2023-04-11 01:18:34 +0300 986) более длинное имя, которое начинается с имени искомого пакета.
11c606a6 (kx 2023-04-11 01:18:34 +0300 987) Полагаясь на факт, что версия может начинаться только с цифры,
11c606a6 (kx 2023-04-11 01:18:34 +0300 988) мы пропускаем символ '-', разделяющий имя и версию пакета,
11c606a6 (kx 2023-04-11 01:18:34 +0300 989) а затем проверяем начальный символ версии:
11c606a6 (kx 2023-04-11 01:18:34 +0300 990) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 991) if( *(name + strlen( pkgname )) == '-' && isdigit( *(name + strlen( pkgname ) + 1) ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 992) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 993) _get_found_pkginfo( (const char *)path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 994) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 995) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 996) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 997) if( S_ISDIR(entry_sb.st_mode) && grp == NULL )
11c606a6 (kx 2023-04-11 01:18:34 +0300 998) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 999) /**************************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1000) NOTE:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1001) In the Setup Database can be only one package with the same pkgname
11c606a6 (kx 2023-04-11 01:18:34 +0300 1002) but in different groups. For example, the package named 'cairo'
11c606a6 (kx 2023-04-11 01:18:34 +0300 1003) has two instance: libs/cairo-1.14.6 and xlibs/cairo-1.14.6. During
11c606a6 (kx 2023-04-11 01:18:34 +0300 1004) system installation the package libs/cairo-1.14.6 installed first
11c606a6 (kx 2023-04-11 01:18:34 +0300 1005) and then updated by xlibs/cairo-1.14.6 and PKGLOG of libs/cairo-1.14.6
11c606a6 (kx 2023-04-11 01:18:34 +0300 1006) moved from /var/log/radix/packages to /var/log/radix/removed-packages.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1007)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1008) So here we have to look for the PKGLOG in all group directories:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1009) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1010) _search_pkglog( (const char *)path, (const char *)entry->d_name );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1011) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1012) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1013) /* else { stat() returns error code; errno is set; and we have to continue the loop } */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1014) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1015)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1016) closedir( dir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1017) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1018)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1019) static void find_installed_package( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1020) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1021) char *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1022)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1023) tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1024) if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1025) bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1026)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1027) (void)sprintf( &tmp[0], "%s", pkgs_path );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1028)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1029) _search_pkglog( (const char *)&tmp[0], NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1030)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1031) free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1032) }
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) check_input_package():
11c606a6 (kx 2023-04-11 01:18:34 +0300 1036) ---------------------
11c606a6 (kx 2023-04-11 01:18:34 +0300 1037)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1038) Возвращает:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1039) -1 если пакет установлен, но его версия меньше
11c606a6 (kx 2023-04-11 01:18:34 +0300 1040) запрашиваемого,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1041) 0 если пакет не установлен или версия установленного и
11c606a6 (kx 2023-04-11 01:18:34 +0300 1042) запрашиваемого равны,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1043) 1 если пакет установлен, но его версия больше
11c606a6 (kx 2023-04-11 01:18:34 +0300 1044) запрашиваемого.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1045)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1046) В случае возврата -1 или 1, устанавливается переменная
11c606a6 (kx 2023-04-11 01:18:34 +0300 1047) installed_version, равная версии уже установленного пакета.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1048)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1049) В случае возврата нуля есть два варанта:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1050) а) пакет установлен и его надо проверить на целостность
11c606a6 (kx 2023-04-11 01:18:34 +0300 1051) (переменная installed_version != NULL );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1052) б) пакет не установлен.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1053)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1054) Если installed_version != NULL, проверка целостности
11c606a6 (kx 2023-04-11 01:18:34 +0300 1055) пакета будет осуществлена, вне зависимости от его версии.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1056) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1057) static int check_input_package( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1058) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1059) struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1060) char *fname = pkg_fname;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1061)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1062) enum _input_type type = IFMT_UNKNOWN;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1063) char uncompress = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1064)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1065) int ret = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1066)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1067) bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1068)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1069) if( stat( (const char *)fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1070) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1071) /*************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1072) Specified pkg_fname is not a file or directory.
11c606a6 (kx 2023-04-11 01:18:34 +0300 1073) Try to find installed package with name equal
11c606a6 (kx 2023-04-11 01:18:34 +0300 1074) to pkg_fname:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1075) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1076) fname = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1077) fname = probe_package();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1078) if( !fname )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1079) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1080) if( !quiet ) fprintf( stdout, "Specified package '%s' is not installed.\n\n", pkg_fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1081)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1082) exit_status = 30; /* Package is not installed: install */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1083)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1084) if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1085) free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1086)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1087) exit( exit_status );
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)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1091) /* check pkg_fname again: */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1092) if( stat( (const char *)fname, &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1093) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1094) FATAL_ERROR( "Cannot access input '%s' file: %s", fname, strerror( errno ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1095) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1096)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1097) type = check_input_file( &uncompress, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1098) if( type == IFMT_UNKNOWN )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1099) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1100) FATAL_ERROR( "Unknown format of input '%s' file", fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1101) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1102)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1103) if( S_ISREG(st.st_mode) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1104) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1105) pid_t p = (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1106) int rc;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1107)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1108) int len = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1109) char *tmp= NULL, *cmd = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1110)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1111) tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1112) if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1113) bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1114)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1115) (void)sprintf( &tmp[0], "%s", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1116) if( _mkdir_p( tmp, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1117) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1118) FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1119) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1120)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1121) cmd = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1122) if( !cmd ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1123) bzero( (void *)cmd, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1124)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1125) len = snprintf( &cmd[0], PATH_MAX,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1126) "%s/pkginfo -d %s -o pkginfo,restore-links,filelist %s > /dev/null 2>&1",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1127) selfdir, tmp, fname );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1128) if( len == 0 || len == PATH_MAX - 1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1129) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1130) FATAL_ERROR( "Cannot get PKGINFO from %s file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1131) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1132) p = sys_exec_command( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1133) rc = sys_wait_command( p, (char *)NULL, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1134) if( rc != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1135) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1136) FATAL_ERROR( "Cannot get PKGINFO from '%s' file", basename( (char *)fname ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1137) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1138)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1139) (void)strcat( tmp, "/.PKGINFO" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1140) read_input_pkginfo( (const char *)&tmp[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1141) *(strstr( tmp, "/.PKGINFO" )) = '\0'; /* :restore tmpdir in tmp[] buffer */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1142)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1143) find_installed_package();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1144)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1145) free( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1146) free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1147)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1148) if( installed_version )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1149) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1150) ret = cmp_version( (const char *)installed_version, (const char *)pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1151) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1152) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1153) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1154) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1155) FATAL_ERROR( "Input %s file is not a regular file", basename( (char *)fname ) );
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) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1159) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1160)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1161) static int check_package_integrity( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1162) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1163) struct stat st;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1164) FILE *fp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1165)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1166) char *ln = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1167) char *line = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1168)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1169) char *buf = NULL, *tmp = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1170)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1171) int restore_links = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1172) int ret = 1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1173)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1174) buf = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1175) if( !buf ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1176) bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1177)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1178) tmp = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1179) if( !tmp ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1180) bzero( (void *)tmp, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1181)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1182) /* Check if .RESTORELINKS is present */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1183) (void)sprintf( &tmp[0], "%s/.RESTORELINKS", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1184) bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1185) if( (stat( (const char *)&tmp[0], &st ) == 0) && (st.st_size > 8) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1186) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1187) restore_links = 1;
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) (void)sprintf( &tmp[0], "%s/.FILELIST", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1191) fp = fopen( (const char *)&tmp[0], "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1192) if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1193) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1194) FATAL_ERROR( "Cannot open .FILELIST file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1195) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1196)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1197) line = (char *)malloc( (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1198) if( !line ) { FATAL_ERROR( "Cannot allocate memory" ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1199) bzero( (void *)line, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1200)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1201) while( (ln = fgets( line, PATH_MAX, fp )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1202) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1203) int dir = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1204)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1205) ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1206) skip_eol_spaces( ln ); /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1207)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1208) if( *(ln + strlen(ln) - 1) == '/' ) { dir = 1; *(ln + strlen(ln) - 1) = '\0'; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1209) else { dir = 0; }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1210)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1211) if( !dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1212) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1213) char *p = rindex( ln, '.' );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1214) if( p && !strncmp( (const char *)p, ".new", 4 ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1215) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1216) /**************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1217) Do not check .new files:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1218) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1219) *p = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1220) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1221) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1222)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1223) (void)sprintf( &buf[0], "%s/%s", root, ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1224) bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1225)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1226) if( lstat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1227) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1228) /* cannot access file list entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1229) if( dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1230) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1231) if( print_broken_files )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1232) fprintf( stdout, "%s-%s: /%s: no such directory\n", pkgname, installed_version, ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1233) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1234) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1235) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1236) if( print_broken_files )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1237) fprintf( stdout, "%s-%s: /%s: no such file\n", pkgname, installed_version, ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1238) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1239)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1240) ret = 0; continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1241) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1242)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1243) if( dir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1244) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1245) if( S_ISDIR(st.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1246) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1247) /* not a directory */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1248) if( print_broken_files )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1249) fprintf( stdout, "%s-%s: /%s: not a directory\n", pkgname, installed_version, ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1250) ret = 0; continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1251) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1252) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1253) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1254) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1255) if( S_ISREG(st.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1256) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1257) /* not a regular file */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1258) if( print_broken_files )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1259) fprintf( stdout, "%s-%s: /%s: not a regular file\n", pkgname, installed_version, ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1260) ret = 0; continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1261) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1262) if( !restore_links )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1263) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1264) if( S_ISLNK(st.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1265) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1266) /* not a symbolic link */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1267) if( print_broken_files )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1268) fprintf( stdout, "%s-%s: /%s: not a symbolic link\n", pkgname, installed_version, ln );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1269) ret = 0; continue;
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) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1273) } /* End of while( file list entry ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1274) fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1275)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1276)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1277) (void)sprintf( &tmp[0], "%s/.RESTORELINKS", tmpdir );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1278) bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1279)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1280) if( stat( (const char *)&tmp[0], &st ) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1281) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1282) fp = fopen( (const char *)&tmp[0], "r" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1283) if( !fp )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1284) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1285) FATAL_ERROR( "Cannot open .RESTORELINKS file" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1286) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1287)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1288) while( (ln = fgets( line, PATH_MAX, fp )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1289) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1290) char *match = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1291)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1292) ln[strlen(ln) - 1] = '\0'; /* replace new-line symbol */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1293) skip_eol_spaces( ln ); /* remove spaces at end-of-line */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1294)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1295) if( (match = strstr( ln, "; rm -rf " )) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1296) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1297) char *q = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1298) char *p = strstr( ln, "cd" ) + 2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1299) char *f = strstr( ln, "; rm -rf" ) + 8;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1300)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1301) if( !p || !f ) continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1302)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1303) while( (*p == ' ' || *p == '\t') && *p != '\0' ) ++p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1304) while( (*f == ' ' || *f == '\t') && *f != '\0' ) ++f;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1305)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1306) q = p; while( *q != ' ' && *q != '\t' && *q != ';' && *q != '\0' ) ++q; *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1307) q = f; while( *q != ' ' && *q != '\t' && *q != ';' && *q != '\0' ) ++q; *q = '\0';
11c606a6 (kx 2023-04-11 01:18:34 +0300 1308)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1309) if( p && f )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1310) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1311) (void)sprintf( &buf[0], "%s/%s/%s", root, p, f );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1312) bzero( (void *)&st, sizeof( struct stat ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1313)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1314) if( lstat( (const char *)&buf[0], &st ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1315) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1316) /* cannot access restore links entry */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1317) if( print_broken_files )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1318) fprintf( stdout, "%s-%s: /%s/%s: no such file or directory\n", pkgname, installed_version, p, f );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1319) ret = 0; continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1320) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1321)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1322) if( S_ISLNK(st.st_mode) == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1323) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1324) /* not a symbolic link */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1325) if( print_broken_files )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1326) fprintf( stdout, "%s-%s: /%s/%s: not a symbolic link\n", pkgname, installed_version, p, f );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1327) ret = 0; continue;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1328) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1329) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1330) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1331) } /* End of while( restore links entry ) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1332) fclose( fp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1333) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1334)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1335) free( line );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1336) free( tmp );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1337) free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1338)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1339) return ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1340) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1341)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1342)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1343) /*********************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1344) Get directory where this program is placed:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1345) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1346) char *get_selfdir( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1347) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1348) char *buf = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1349) ssize_t len;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1350)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1351) buf = (char *)malloc( PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1352) if( !buf )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1353) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1354) FATAL_ERROR( "Cannot allocate memory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1355) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1356)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1357) bzero( (void *)buf, PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1358) len = readlink( "/proc/self/exe", buf, (size_t)PATH_MAX );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1359) if( len > 0 && len < PATH_MAX )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1360) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1361) char *p = xstrdup( (const char *)dirname( buf ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1362) free( buf );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1363) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1364) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1365) FATAL_ERROR( "Cannot determine self directory. Please mount /proc filesystem" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1366) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1367)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1368) void set_stack_size( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1369) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1370) const rlim_t stack_size = 16 * 1024 * 1024; /* min stack size = 16 MB */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1371) struct rlimit rl;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1372) int ret;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1373)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1374) ret = getrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1375) if( ret == 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1376) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1377) if( rl.rlim_cur < stack_size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1378) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1379) rl.rlim_cur = stack_size;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1380) ret = setrlimit( RLIMIT_STACK, &rl );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1381) if( ret != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1382) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1383) fprintf(stderr, "setrlimit returned result = %d\n", ret);
11c606a6 (kx 2023-04-11 01:18:34 +0300 1384) FATAL_ERROR( "Cannot set stack size" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1385) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1386) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1387) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1388) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1389)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1390)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1391) int main( int argc, char *argv[] )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1392) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1393) gid_t gid;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1394)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1395) set_signal_handlers();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1396)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1397) gid = getgid();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1398) setgroups( 1, &gid );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1399)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1400) fatal_error_hook = fatal_error_actions;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1401)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1402) selfdir = get_selfdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1403)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1404) errlog = stderr;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1405)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1406) program = basename( argv[0] );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1407) get_args( argc, argv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1408)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1409) /* set_stack_size(); */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1410)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1411) tmpdir = _mk_tmpdir();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1412) if( !tmpdir )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1413) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1414) FATAL_ERROR( "Cannot create temporary directory" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1415) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1416)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1417)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1418) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1419) int status = 0, correctly = 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 1420)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1421) /**********************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 1422) Fill pkginfo data and put or replace pkglog into tmpdir:
11c606a6 (kx 2023-04-11 01:18:34 +0300 1423) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1424) status = check_input_package();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1425)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1426) if( installed_version )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1427) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1428) /* In this case we have to check package integrity */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1429) correctly = check_package_integrity(); /* returns 1 if correct */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1430) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1431)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1432) if( exit_status == EXIT_SUCCESS )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1433) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1434) if( status < 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1435) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1436) if( !correctly )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1437) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1438) if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1439) fprintf( stdout,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1440) "Previous version '%s' of specified package '%s-%s' is installed but not correct.\n\n",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1441) installed_version, pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1442) exit_status = 34; /* Package is installed but not correct: repair, upgrade */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1443) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1444) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1445) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1446) if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1447) fprintf( stdout,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1448) "Previous version '%s' of specified package '%s-%s' is installed.\n\n",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1449) installed_version, pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1450) exit_status = 33; /* Package is installed correctly: upgrade */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1451) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1452) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1453) else if( status > 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1454) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1455) if( !correctly )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1456) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1457) if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1458) fprintf( stdout,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1459) "A newer version '%s' of specified package '%s-%s' is installed but not correct.\n\n",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1460) installed_version, pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1461) exit_status = 36; /* Package is installed but not correct: repair, downgrade */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1462) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1463) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1464) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1465) if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1466) fprintf( stdout,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1467) "A newer version '%s' of specified package '%s-%s' is installed.\n\n",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1468) installed_version, pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1469) exit_status = 35; /* Package is installed correctly: downgrade */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1470) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1471) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1472) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1473) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1474) if( installed_version )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1475) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1476) if( !correctly )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1477) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1478) if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1479) fprintf( stdout,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1480) "Specified package '%s-%s' is already installed but not correct.\n\n",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1481) pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1482) exit_status = 32; /* Package is installed but not correct: repair, re-install */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1483) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1484) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1485) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1486) if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1487) fprintf( stdout,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1488) "Specified package '%s-%s' is already installed.\n\n",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1489) pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1490) exit_status = 31; /* Package is installed correctly: nothing to do */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1491) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1492) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1493) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 1494) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 1495) if( !quiet )
11c606a6 (kx 2023-04-11 01:18:34 +0300 1496) fprintf( stdout,
11c606a6 (kx 2023-04-11 01:18:34 +0300 1497) "Specified package '%s-%s' is not installed.\n\n",
11c606a6 (kx 2023-04-11 01:18:34 +0300 1498) pkgname, pkgver );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1499) exit_status = 30; /* Package is not installed: install */
11c606a6 (kx 2023-04-11 01:18:34 +0300 1500) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1501) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1502) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1503)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1504) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1505)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1506)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1507) if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); }
11c606a6 (kx 2023-04-11 01:18:34 +0300 1508) free_resources();
11c606a6 (kx 2023-04-11 01:18:34 +0300 1509)
11c606a6 (kx 2023-04-11 01:18:34 +0300 1510) exit( exit_status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 1511) }