36 "@(#) Copyright (c) 1989, 1990, 1993\n\ 37 The Regents of the University of California. All rights reserved.\n";
46 #if defined(__QNXNTO__) 47 #define st_mtimespec st_mtime 55 #undef _RPMFI_INTERNAL 56 #if defined(_RPMFI_INTERNAL) 57 #define _RPMAV_INTERNAL 66 #define RPM_LIST_HEAD(name, type) \ 67 struct name { struct type *lh_first; } 68 #define RPM_LIST_ENTRY(type) \ 69 struct { struct type *le_next;struct type **le_prev; } 70 #define RPM_LIST_EMPTY(head) \ 71 ((head)->lh_first == NULL) 72 #define RPM_LIST_FIRST(head) \ 74 #define RPM_LIST_NEXT(elm, field) \ 75 ((elm)->field.le_next) 76 #define RPM_LIST_INIT(head) \ 77 do { RPM_LIST_FIRST((head)) = NULL; } while (0) 78 #define RPM_LIST_INSERT_HEAD(head, elm, field) \ 79 do { if ((RPM_LIST_NEXT((elm), field) = RPM_LIST_FIRST((head))) != NULL) \ 80 RPM_LIST_FIRST((head))->field.le_prev = &RPM_LIST_NEXT((elm), field);\ 81 RPM_LIST_FIRST((head)) = (elm); \ 82 (elm)->field.le_prev = &RPM_LIST_FIRST((head)); } while (0) 83 #define RPM_LIST_FOREACH(var, head, field) \ 84 for ((var) = RPM_LIST_FIRST((head)); (var); (var) = RPM_LIST_NEXT((var), field)) 86 #define _MTREE_INTERNAL 89 #define _KFB(n) (1U << (n)) 90 #define _MFB(n) (_KFB(n) | 0x40000000) 117 #if defined(_MTREE_INTERNAL) 158 #define F_BLOCK 0x001 195 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 210 #if defined(_RPMFI_INTERNAL) 260 #define MF_ISSET(_FLAG) ((mtreeFlags & ((MTREE_FLAGS_##_FLAG) & ~0x40000000)) != MTREE_FLAGS_NONE) 263 (MTREE_KEYS_GID | MTREE_KEYS_MODE | MTREE_KEYS_NLINK | MTREE_KEYS_SIZE | \ 264 MTREE_KEYS_SLINK | MTREE_KEYS_TIME | MTREE_KEYS_UID) 266 #define MISMATCHEXIT 2 268 #define MBITS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO) 303 __attribute__ ((format (printf, 1, 2)))
316 (void) vfprintf(stderr, fmt, ap);
318 (void) fprintf(stderr,
"\n");
320 (void)fprintf(stderr,
_(
"%s: failed at line %d of the specification\n"),
330 #define NEEDVALUE 0xffffffff 389 if (needvaluep != NULL)
394 k = (
KEY *)bsearch(&tmp, keylist,
sizeof(keylist) /
sizeof(keylist[0]),
399 if (needvaluep != NULL)
400 *needvaluep = k->flags;
408 const char * tagname = NULL;
431 default: tagname = NULL;
break;
436 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 438 flags_to_string(u_long fflags)
441 char *
string = fflagstostr(fflags);
442 if (
string != NULL && *
string ==
'\0') {
455 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
456 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
457 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
458 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
459 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
460 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
461 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
462 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
463 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
464 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
465 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
466 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
467 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
468 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
469 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
470 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
471 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
472 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
473 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
474 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
475 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
476 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
477 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
478 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
479 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
480 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
481 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
482 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
483 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
484 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
485 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
486 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
487 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
488 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
489 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
490 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
491 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
492 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
493 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
494 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
495 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
496 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
497 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
498 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
499 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
500 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
501 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
502 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
503 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
504 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
505 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
515 crc(
FD_t fd, uint32_t * cval, uint32_t * clen)
522 #define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)] 526 { uint8_t buf[16 * 1024];
528 while ((nr =
Fread(buf,
sizeof(buf[0]),
sizeof(buf), fd)) != 0) {
530 for (len += nr, p = buf; nr--; ++p) {
542 for (; len != 0; len >>= 8) {
547 *cval = (crc ^ 0xffffffff);
557 #define VIS_OCTAL 0x01 558 #define VIS_CSTYLE 0x02 567 #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) 568 #define VIS_SAFE 0x20 573 #define VIS_NOSLASH 0x40 578 #define UNVIS_VALID 1 579 #define UNVIS_VALIDPUSH 2 580 #define UNVIS_NOCHAR 3 581 #define UNVIS_SYNBAD -1 582 #define UNVIS_ERROR -2 589 static char *
vis(
char *dst,
int c,
int flag,
int nextc)
591 static int strvis(
char *dst,
const char *src,
int flag)
594 static int strnvis(
char *dst,
const char *src,
size_t siz,
int flag)
596 static int strvisx(
char *dst,
const char *src,
size_t len,
int flag)
599 static int strunvis(
char *dst,
const char *src)
601 static int unvis(
char *cp,
char c,
int *astate,
int flag)
604 #define isoctal(c) (((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7') 605 #define isvisible(c) \ 606 (((unsigned)(c) <= (unsigned)UCHAR_MAX && isascii((unsigned char)(c)) && \ 607 isgraph((unsigned char)(c))) \ 608 || ((flag & VIS_SP) == 0 && (c) == (int)' ') \ 609 || ((flag & VIS_TAB) == 0 && (c) == (int)'\t') \ 610 || ((flag & VIS_NL) == 0 && (c) == (int)'\n') \ 611 || ((flag & VIS_SAFE) \ 612 && ((c) == (int)'\b' || (c) == (int)'\007' || (c) == (int)'\r'))) 618 vis(
char * dst,
int c,
int flag,
int nextc)
672 if (((c & 0177) == (int)
' ') || (flag &
VIS_OCTAL)) {
674 *dst++ = ((
unsigned char)c >> 6 & 07) +
'0';
675 *dst++ = ((
unsigned char)c >> 3 & 07) +
'0';
676 *dst++ = ((
unsigned char)c & 07) +
'0';
690 *dst++ = (char)(c + (
int)
'@');
715 strvis(
char * dst,
const char * src,
int flag)
720 for (start = dst; (c = *src) !=
'\0';)
721 dst =
vis(dst, (
int)c, flag, (int)*++src);
723 return (dst - start);
728 strnvis(
char * dst,
const char * src,
size_t siz,
int flag)
733 for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
749 dst =
vis(dst, (
int)c, flag, (
int)*++src);
759 while ((c = *src) !=
'\0')
760 dst +=
vis(tbuf, (
int)c, flag, (
int)*++src) - tbuf;
762 return (dst - start);
768 strvisx(
char * dst,
const char * src,
size_t len,
int flag)
773 for (start = dst; len > 1; len--) {
775 dst =
vis(dst, (
int)c, flag, (
int)*++src);
778 dst =
vis(dst, (
int)*src, flag, (
int)
'\0');
780 return (dst - start);
795 #if !defined(isoctal) 796 #define isoctal(c) (((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7') 803 unvis(
char *cp,
char c,
int *astate,
int flag)
831 case '0':
case '1':
case '2':
case '3':
832 case '4':
case '5':
case '6':
case '7':
918 *cp = (*cp << 3) + (c -
'0');
931 *cp = (*cp << 3) + (c -
'0');
962 while ((c = *src++) !=
'\0') {
964 switch (
unvis(dst, c, &state, 0)) {
981 return (dst - start);
987 #if defined(__linux__) || defined(__sun__) || defined(__LCLINT__) || defined(__QNXNTO__) 988 #if !defined(HAVE_GETMODE) || !defined(HAVE_SETMODE) 991 #define SET_LEN_INCR 4 993 typedef struct bitcmd {
999 #define CMD2_CLR 0x01 1000 #define CMD2_SET 0x02 1001 #define CMD2_GBITS 0x04 1002 #define CMD2_OBITS 0x08 1003 #define CMD2_UBITS 0x10 1005 #if !defined(HAVE_GETMODE) 1013 getmode(
const void * bbox, mode_t omode)
1017 mode_t clrval, newmode, value;
1019 set = (
const BITCMD *)bbox;
1021 for (value = 0;;
set++)
1030 value = (newmode & S_IRWXU) >> 6;
1034 value = (newmode & S_IRWXG) >> 3;
1038 value = newmode & S_IRWXO;
1039 common:
if ((
set->cmd2 & CMD2_CLR) !=
'\0') {
1040 clrval = (
set->cmd2 & CMD2_SET) !=
'\0' ? S_IRWXO : value;
1041 if ((
set->cmd2 & CMD2_UBITS) !=
'\0')
1042 newmode &= ~((clrval<<6) &
set->bits);
1043 if ((
set->cmd2 & CMD2_GBITS) !=
'\0')
1044 newmode &= ~((clrval<<3) &
set->bits);
1045 if ((
set->cmd2 & CMD2_OBITS) !=
'\0')
1046 newmode &= ~(clrval &
set->bits);
1048 if ((
set->cmd2 & CMD2_SET) !=
'\0') {
1049 if ((
set->cmd2 & CMD2_UBITS) !=
'\0')
1050 newmode |= (value<<6) &
set->bits;
1051 if ((
set->cmd2 & CMD2_GBITS) !=
'\0')
1052 newmode |= (value<<3) &
set->bits;
1053 if ((
set->cmd2 & CMD2_OBITS) !=
'\0')
1054 newmode |= value &
set->bits;
1059 newmode |=
set->bits;
1063 newmode &= ~
set->bits;
1067 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
1068 newmode |=
set->bits;
1073 #ifdef SETMODE_DEBUG
1074 (
void) printf(
"getmode:%04o -> %04o\n", omode, newmode);
1081 #if !defined(HAVE_SETMODE) 1082 #ifdef SETMODE_DEBUG 1084 dumpmode(BITCMD *
set)
1086 for (;
set->cmd; ++
set)
1087 (
void) printf(
"cmd: '%c' bits %04o%s%s%s%s%s%s\n",
1088 set->cmd,
set->bits,
set->cmd2 ?
" cmd2:" :
"",
1089 set->cmd2 & CMD2_CLR ?
" CLR" :
"",
1090 set->cmd2 & CMD2_SET ?
" SET" :
"",
1091 set->cmd2 & CMD2_UBITS ?
" UBITS" :
"",
1092 set->cmd2 & CMD2_GBITS ?
" GBITS" :
"",
1093 set->cmd2 & CMD2_OBITS ?
" OBITS" :
"");
1097 #define ADDCMD(a, b, c, d) \ 1098 if (set >= endset) { \ 1100 setlen += SET_LEN_INCR; \ 1101 newset = realloc(saveset, sizeof(*newset) * setlen); \ 1102 if (newset == NULL) { \ 1103 if (saveset != NULL) \ 1108 set = newset + (set - saveset); \ 1110 endset = newset + (setlen - 2); \ 1112 set = addcmd(set, (a), (b), (c), (d)) 1114 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) 1117 addcmd( BITCMD *
set,
int op,
int who,
int oparg,
unsigned mask)
1123 set->bits = who ? who : (int) STANDARD_BITS;
1131 set->cmd = (char)op;
1132 set->bits = (who ? (unsigned)who : mask) & oparg;
1138 set->cmd = (char)op;
1140 set->cmd2 = (char)( ((who & S_IRUSR) ? CMD2_UBITS : 0) |
1141 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
1142 ((who & S_IROTH) ? CMD2_OBITS : 0));
1143 set->bits = (mode_t)~0;
1145 set->cmd2 =(char)(CMD2_UBITS | CMD2_GBITS | CMD2_OBITS);
1149 if (oparg == (
int)
'+')
1150 set->cmd2 |= CMD2_SET;
1151 else if (oparg == (
int)
'-')
1152 set->cmd2 |= CMD2_CLR;
1153 else if (oparg == (
int)
'=')
1154 set->cmd2 |= CMD2_SET|CMD2_CLR;
1167 compress_mode( BITCMD *
set)
1171 int setbits, clrbits, Xbits, op;
1173 for (nset =
set;;) {
1175 while ((op = (
int)nset->cmd) != (
int)
'+' && op != (
int)
'-' && op != (
int)
'X') {
1181 for (setbits = clrbits = Xbits = 0;; nset++) {
1182 if ((op = (
int)nset->cmd) == (
int)
'-') {
1183 clrbits |= nset->bits;
1184 setbits &= ~nset->bits;
1185 Xbits &= ~nset->bits;
1186 }
else if (op == (
int)
'+') {
1187 setbits |= nset->bits;
1188 clrbits &= ~nset->bits;
1189 Xbits &= ~nset->bits;
1190 }
else if (op == (
int)
'X')
1191 Xbits |= nset->bits & ~setbits;
1198 set->bits = clrbits;
1204 set->bits = setbits;
1219 setmode(
const char * p)
1225 BITCMD *
set, *saveset, *endset;
1226 sigset_t sigset, sigoset;
1228 int equalopdone = 0;
1229 int permXbits, setlen;
1241 (void) sigfillset(&sigset);
1242 (void) sigprocmask(SIG_BLOCK, &sigset, &sigoset);
1243 (void) umask(mask = umask(0));
1245 (void) sigprocmask(SIG_SETMASK, &sigoset, NULL);
1247 setlen = SET_LEN + 2;
1249 if ((
set = malloc((
unsigned)(
sizeof(*set) * setlen))) == NULL)
1252 endset =
set + (setlen - 2);
1259 perml = strtol(p, NULL, 8);
1261 if (perml < 0 || (perml & ~(STANDARD_BITS|S_ISTXT)))
1267 perm = (int)(mode_t)perml;
1268 while (*++p !=
'\0')
1269 if (*p < '0' || *p >
'7') {
1273 ADDCMD((
int)
'=', (
int)(STANDARD_BITS|S_ISTXT), perm, (
unsigned)mask);
1283 for (who = 0;; ++p) {
1286 who |= STANDARD_BITS;
1289 who |= S_ISUID|S_IRWXU;
1292 who |= S_ISGID|S_IRWXG;
1302 getop:
if ((op = *p++) !=
'+' && op !=
'-' && op !=
'=') {
1310 for (perm = 0, permXbits = 0;; ++p) {
1313 perm |= S_IRUSR|S_IRGRP|S_IROTH;
1320 if (who == 0 || (who & ~S_IRWXO))
1321 perm |= S_ISUID|S_ISGID;
1328 if (who == 0 || (who & ~S_IRWXO)) {
1334 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
1337 permXbits = (int)(S_IXUSR|S_IXGRP|S_IXOTH);
1340 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
1351 ADDCMD((
int)op, who, perm, (
unsigned)mask);
1356 if (op ==
'+' && permXbits) {
1357 ADDCMD((
int)
'X', who, permXbits, (
unsigned)mask);
1360 ADDCMD((
int)*p, who, (
int)op, (
unsigned)mask);
1368 if (perm || (op ==
'=' && !equalopdone)) {
1371 ADDCMD((
int)op, who, perm, (
unsigned)mask);
1375 ADDCMD((
int)
'X', who, permXbits, (
unsigned)mask);
1389 #ifdef SETMODE_DEBUG 1390 (void) printf(
"Before compress_mode()\n");
1393 compress_mode(saveset);
1394 #ifdef SETMODE_DEBUG 1395 (void) printf(
"After compress_mode()\n");
1414 for (; (kw = strtok(t,
"= \t\n")) != NULL; t = NULL) {
1420 if (needvalue && (val = strtok(NULL,
" \t\n")) == NULL)
1425 ip->cksum = strtoul(val, &ep, 10);
1430 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 1431 if (!strcmp(val,
"none")) {
1432 ip->sb.st_flags = 0;
1435 {
unsigned long fset, fclr;
1436 if (strtofflags(&val, &fset, &fclr))
1438 ip->sb.st_flags = fset;
1443 ip->sb.st_gid = strtoul(val, &ep, 10);
1456 if ((m = setmode(val)) == NULL)
1458 ip->sb.st_mode = getmode(m, 0);
1462 ip->sb.st_nlink = strtoul(val, &ep, 10);
1467 (void)
argiAdd(&ip->algos, -1, (
int)needvalue);
1468 (void)
argvAdd(&ip->digests, val);
1472 ip->sb.st_size = strtoul(val, &ep, 10);
1478 ip->slink =
xmalloc(strlen(val) + 1);
1479 if (
strunvis(ip->slink, val) == -1) {
1480 fprintf(stderr,
_(
"%s: filename (%s) encoded incorrectly\n"),
1483 strcpy(ip->slink, val);
1487 #if defined(TIMEVAL_TO_TIMESPEC) 1488 ip->sb.st_mtimespec.tv_sec = strtoul(val, &ep, 10);
1492 ip->sb.st_mtimespec.tv_nsec = strtoul(val, &ep, 10);
1496 ip->sb.st_mtime = strtoul(val, &ep, 10);
1500 (void) strtoul(val, &ep, 10);
1508 if (!strcmp(val,
"block"))
1512 if (!strcmp(val,
"char"))
1516 if (!strcmp(val,
"dir"))
1520 if (!strcmp(val,
"file"))
1522 if (!strcmp(val,
"fifo"))
1526 if (!strcmp(val,
"link"))
1530 if (!strcmp(val,
"socket"))
1538 ip->sb.st_uid = strtoul(val, &ep, 10);
1565 while ((p = strtok(t,
"\n\t ")) != NULL)
1569 #define KF_ISSET(_keys, _KEY) ((_keys) & (MTREE_KEYS_##_KEY)) 1575 NODE *centry = NULL;
1580 NODE *forest = NULL;
1588 memset(&ginfo, 0,
sizeof(ginfo));
1589 for (fts->
lineno = 1; fgets(buf, (
int)
sizeof(buf), fp) != NULL;
1590 ++fts->
lineno, c_cur = c_next, c_next = 0)
1597 if ((p = strchr(buf,
'\n')) == NULL)
1601 if (p[-1] ==
'\\') {
1610 for (p = buf; *p && isspace(*p); ++p);
1613 if (*p ==
'\0' || *p ==
'#')
1617 (void)fprintf(stderr,
"line %3d: {%s}\n", fts->
lineno, p);
1625 if ((p = strtok(p,
"\n\t ")) == NULL)
1631 if (strcmp(p + 1,
"set"))
1636 if (strcmp(p + 1,
"unset"))
1638 unset(NULL, &ginfo);
1642 #if !defined(_RPMFI_INTERNAL) 1643 if (strchr(p,
'/') != NULL)
1647 if (!strcmp(p,
"..")) {
1663 centry =
xcalloc(1,
sizeof(*centry) + strlen(p));
1666 if (strpbrk(p,
MAGIC) != NULL)
1669 fprintf(stderr,
_(
"%s: filename (%s) encoded incorrectly\n"),
1671 strcpy(centry->
name, p);
1676 last = root = centry;
1680 }
else if (centry->
name[0] ==
'.' && centry->
name[1] ==
'\0') {
1681 centry->
prev = root;
1682 last = root = root->
next = centry;
1686 last = last->
child = centry;
1689 centry->
prev = last;
1690 last = last->
next = centry;
1705 case F_CHAR:
return "char";
1706 case F_DIR:
return "dir";
1707 case F_FIFO:
return "fifo";
1708 case F_FILE:
return "file";
1709 case F_LINK:
return "link";
1710 case F_SOCK:
return "socket";
1711 default:
return "unknown";
1721 switch(mode & S_IFMT) {
1722 case S_IFBLK:
return "block";
1723 case S_IFCHR:
return "char";
1724 case S_IFDIR:
return "dir";
1725 case S_IFIFO:
return "fifo";
1726 case S_IFREG:
return "file";
1727 case S_IFLNK:
return "link";
1731 default:
return "unknown";
1762 #define FF(a, b, c, d) \ 1763 (((a)->flags & (c)) && ((b)->flags & (c)) && ((a)->d) != ((b)->d)) 1764 #define FS(a, b, c, d) \ 1765 (((a)->flags & (c)) && ((b)->flags & (c)) && strcmp((a)->d,(b)->d)) 1766 #define FM(a, b, c, d) \ 1767 (((a)->flags & (c)) && ((b)->flags & (c)) && memcmp(&(a)->d,&(b)->d, sizeof (a)->d)) 1776 printf(
" cksum=%lu", (
unsigned long) n->
cksum);
1778 printf(
" gid=%lu", (
unsigned long) n->
sb.st_gid);
1782 printf(
" gname=%s", gname);
1784 printf(
" gid=%lu", (
unsigned long) n->
sb.st_gid);
1787 printf(
" mode=%o", (
unsigned) n->
sb.st_mode);
1789 printf(
" nlink=%lu", (
unsigned long) n->
sb.st_nlink);
1792 printf(
" size=%llu", (
unsigned long long)n->
sb.st_size);
1795 printf(
" uid=%lu", (
unsigned long) n->
sb.st_uid);
1799 printf(
" uname=%s", uname);
1801 printf(
" uid=%lu", (
unsigned long) n->
sb.st_uid);
1808 if (n->
algos != NULL)
1809 for (i = 0; i < (int) n->
algos->
nvals; i++) {
1812 if (tagname != NULL)
1813 printf(
" %s=%s", tagname, n->
digests[i]);
1817 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 1819 printf(
" flags=%s", flags_to_string(n->
sb.st_flags));
1840 if (!(differ & keys))
1861 if (n1 == NULL && n2 != NULL) {
1862 differs = n2->
flags;
1863 xx =
mismatch(n1, n2, differs, path);
1866 if (n1 != NULL && n2 == NULL) {
1867 differs = n1->
flags;
1868 xx =
mismatch(n1, n2, differs, path);
1873 xx =
mismatch(n1, n2, differs, path);
1910 for (i = 0; i < (int) n1->
algos->
nvals; i++) {
1920 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 1926 xx =
mismatch(n1, n2, differs, path);
1937 NODE *c1 = (t1 != NULL ? t1->
child : NULL);
1938 NODE *c2 = (t2 != NULL ? t2->
child : NULL);
1941 while (c1 != NULL || c2 != NULL) {
1946 n1 = (c1 != NULL ? c1->
next : NULL);
1947 n2 = (c2 != NULL ? c2->
next : NULL);
1948 if (c1 != NULL && c2 != NULL) {
1968 if (asprintf(&np,
"%s%s/", path, c2->
name)) {
1974 }
else if (c2 == NULL && c1->
type ==
F_DIR) {
1975 if (asprintf(&np,
"%s%s/", path, c1->
name)) {
1981 }
else if (c1 == NULL || c2 == NULL) {
1984 if (asprintf(&np,
"%s%s/", path, c1->
name)) {
2025 if ((len =
Readlink(name, lbuf,
sizeof(lbuf)-1)) == -1)
2031 #define SKIPDOTSLASH(_f) ((_f)[0] == '.' && (_f)[1] == '/' ? (_f) + 2 : (_f)) 2033 #define COMPAREINDENTNAMELEN 8 2036 (void) printf(_("%s changed\n"), SKIPDOTSLASH(p->fts_path)); \ 2067 default:
return "Unknown";
2085 const char *tab =
"";
2089 if (!S_ISBLK(st->st_mode))
2093 if (!S_ISCHR(st->st_mode))
2097 if (!S_ISDIR(st->st_mode))
2101 if (!S_ISFIFO(st->st_mode))
2105 if (!S_ISREG(st->st_mode))
2116 (void) printf(
_(
"\ttype expected %s found %s)\n"),
2126 (void) printf(
_(
"%s%s expected %lu found %lu"), tab,
"user",
2127 (
unsigned long)s->
sb.st_uid, (
unsigned long)st->st_uid);
2129 if (
Chown(fts_accpath, s->
sb.st_uid, -1))
2130 (
void) printf(
_(
" not modified: %s)\n"), strerror(
errno));
2132 (
void) printf(
_(
" modified)\n"));
2134 (
void) printf(
"\n");
2139 (void) printf(
_(
"%s%s expected %lu found %lu"), tab,
"gid",
2140 (
unsigned long)s->
sb.st_gid, (
unsigned long)st->st_gid);
2142 if (
Chown(fts_accpath, -1, s->
sb.st_gid))
2143 (
void) printf(
_(
" not modified: %s)\n"), strerror(
errno));
2145 (
void) printf(
_(
" modified)\n"));
2147 (
void) printf(
"\n");
2152 mode_t tmode = s->
sb.st_mode;
2153 mode_t mode = (st->st_mode &
MBITS);
2160 if (!((tmode & ~(S_IRWXU|S_IRWXG|S_IRWXO))
2161 || (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO))))
2162 if ((mode | tmode) == tmode)
2166 (void) printf(
_(
"%s%s expected %#o found %#o"), tab,
"permissions",
2167 (unsigned)s->
sb.st_mode, (
unsigned)(st->st_mode &
MBITS));
2169 if (
Chmod(fts_accpath, s->
sb.st_mode))
2170 (
void) printf(
_(
" not modified: %s)\n"), strerror(
errno));
2172 (
void) printf(
_(
" modified)\n"));
2174 (
void) printf(
"\n");
2180 s->
sb.st_nlink != st->st_nlink)
2183 (void) printf(
_(
"%s%s expected %lu found %lu)\n"), tab,
"link_count",
2184 (
unsigned long)s->
sb.st_nlink, (
unsigned long)st->st_nlink);
2187 if (
KF_ISSET(keys, SIZE) && s->
sb.st_size != st->st_size) {
2190 (void) printf(
_(
"%s%s expected %llu found %llu\n"), tab,
"size",
2191 (
unsigned long long)s->
sb.st_size,
2192 (
unsigned long long)st->st_size);
2205 struct timeval tv[2];
2208 #if defined(TIMESPEC_TO_TIMEVAL) 2212 tv[0].tv_sec = (long)s->
sb.st_mtime;
2214 tv[1].tv_sec = (
long)st->st_mtime;
2218 if (tv[0].tv_sec != tv[1].tv_sec
2220 || tv[0].tv_usec != tv[1].tv_usec
2223 time_t t1 = (time_t)tv[0].tv_sec;
2224 time_t t2 = (time_t)tv[1].tv_sec;
2226 (void) printf(
_(
"%s%s expected %.24s "), tab,
"modification time", ctime(&t1));
2227 (void) printf(
_(
"found %.24s"), ctime(&t2));
2230 if (
Utimes(fts_accpath, tv))
2231 (
void) printf(
_(
" not modified: %s)\n"), strerror(
errno));
2233 (
void) printf(
_(
" modified\n"));
2235 (
void) printf(
"\n");
2242 FD_t fd =
Fopen(fts_accpath,
"r.ufdio");
2246 if (fd == NULL ||
Ferror(fd)) {
2248 (void) printf(
"%scksum: %s: %s\n", tab, fts_accpath,
Fstrerror(fd));
2253 if (s->
algos != NULL)
2259 i =
crc(fd, &val, &vlen);
2261 char buffer[16 * 1024];
2262 while (
Fread(buffer,
sizeof(buffer[0]),
sizeof(buffer), fd) > 0)
2264 i = (
Ferror(fd) ? 1 : 0);
2268 (void) printf(
"%scksum: %s: %s\n", tab, fts_accpath,
Fstrerror(fd));
2274 if (s->
cksum != val) {
2276 (void) printf(
_(
"%s%s expected %lu found %lu\n"), tab,
"cksum",
2277 (
unsigned long) s->
cksum, (
unsigned long) val);
2283 if (s->
algos != NULL)
2284 for (i = 0; i < (int) s->
algos->
nvals; i++) {
2285 static int asAscii = 1;
2287 const char * digest = NULL;
2288 size_t digestlen = 0;
2291 assert(digest != NULL);
2292 if (strcmp(digest, s->
digests[i])) {
2294 printf(
_(
"%s%s expected %s found %s\n"), tab,
algo2name(algo),
2298 digest =
_free(digest);
2314 (void) printf(
_(
"%s%s expected %s found %s\n"), tab,
"link_ref",
2317 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 2318 if (
KF_ISSET(keys, FLAGS) && s->
sb.st_flags != st->st_flags) {
2322 fflags = fflagstostr(s->
sb.st_flags);
2323 (void) printf(
_(
"%s%s expected \"%s\""), tab,
"flags", fflags);
2324 fflags =
_free(fflags);
2326 fflags = fflagstostr(st->st_flags);
2327 (void) printf(
_(
" found \"%s\""), fflags);
2328 fflags =
_free(fflags);
2331 if (chflags(fts_accpath, s->
sb.st_flags))
2332 (void) printf(
" not modified: %s)\n", strerror(
errno));
2334 (
void) printf(
" modified)\n");
2337 (void) printf(
"\n");
2346 #define _FTSCALLOC(_p, _n) \ 2348 (_p) = _free(_p); (_p) = xcalloc((_n), sizeof(*(_p))); \ 2363 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 2364 unsigned long maxflags = 0;
2379 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 2384 for (; p != NULL; p = p->
fts_link) {
2387 if (
MF_ISSET(DIRSONLY) || !S_ISDIR(st->st_mode))
2391 { mode_t st_mode = st->st_mode &
MBITS;
2392 if (st_mode < fts->maxm && ++fts->
m[st_mode] > maxmode) {
2393 sb.st_mode = st_mode;
2394 maxmode = fts->
m[st_mode];
2398 if (st->st_gid < fts->
maxg && ++fts->
g[st->st_gid] > maxgid) {
2399 sb.st_gid = st->st_gid;
2400 maxgid = fts->
g[st->st_gid];
2403 if (st->st_uid < fts->
maxu && ++fts->
u[st->st_uid] > maxuid) {
2404 sb.st_uid = st->st_uid;
2405 maxuid = fts->
u[st->st_uid];
2407 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 2414 #define FLAGS2IDX(f) ((f & 0xf) | ((f >> 12) & 0xf0)) 2416 {
unsigned long st_flags = FLAGS2IDX(st->st_flags);
2417 if (st_flags < fts->maxf && ++fts->f[st_flags] > maxflags) {
2419 sb.st_flags = st->st_flags;
2420 maxflags = fts->f[st_flags];
2431 if (((
KF_ISSET(keys, UNAME) ||
KF_ISSET(keys, UID)) && (fts->
sb.st_uid != sb.st_uid))
2433 || (
KF_ISSET(keys, MODE) && (fts->
sb.st_mode != sb.st_mode))
2434 #
if defined(HAVE_STRUCT_STAT_ST_FLAGS)
2435 || (
KF_ISSET(keys, FLAGS) && (fts->
sb.st_flags != sb.st_flags))
2441 (void) printf(
"/set type=dir");
2443 (
void) printf(
"/set type=file");
2447 (void) printf(
" uname=%s", uname);
2449 fprintf(stderr,
_(
"%s: Could not get uname for uid=%lu\n"),
2453 (
unsigned long)sb.st_uid);
2456 (void) printf(
" uid=%lu", (
unsigned long)sb.st_uid);
2460 (void) printf(
" gname=%s", gname);
2462 fprintf(stderr,
_(
"%s: Could not get gname for gid=%lu\n"),
2466 (
unsigned long) sb.st_gid);
2469 (void) printf(
" gid=%lu", (
unsigned long)sb.st_gid);
2471 (
void) printf(
" mode=%#o", (
unsigned)sb.st_mode);
2473 (void) printf(
" nlink=1");
2474 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 2476 const char * fflags = flags_to_string(sb.st_flags);
2477 (void) printf(
" flags=%s", fflags);
2478 fflags =
_free(fflags);
2481 (void) printf(
"\n");
2487 #define CWALKINDENTNAMELEN 15 2488 #define MAXLINELEN 80 2500 (void)
vsnprintf(buf,
sizeof(buf), fmt, ap);
2503 if (*offset + strlen(buf) >
MAXLINELEN - 3) {
2507 *offset += printf(
" %s", buf) + 1;
2517 unsigned short fts_info = fts->
p->
fts_info;
2522 {
const char * fts_name = fts->
p->
fts_name;
2527 if (fts->
p->
fts_level == 0 && fts_namelen == 0) {
2529 fts_namelen =
sizeof(
".") - 1;
2532 escname =
xmalloc(fts_namelen * 4 + 1);
2536 if (
MF_ISSET(INDENT) || S_ISDIR(st->st_mode))
2537 offset = printf(
"%*s%s", indent,
"", escname);
2539 offset = printf(
"%*s %s", indent,
"", escname);
2540 escname =
_free(escname);
2548 if (!S_ISREG(st->st_mode) && !
MF_ISSET(DIRSONLY))
2550 if (st->st_uid != fts->
sb.st_uid) {
2554 output(indent, &offset,
"uname=%s", uname);
2556 fprintf(stderr,
_(
"%s: Could not get uname for uid=%lu\n"),
2560 (
unsigned long)st->st_uid);
2563 output(indent, &offset,
"uid=%u", st->st_uid);
2565 if (st->st_gid != fts->
sb.st_gid) {
2569 output(indent, &offset,
"gname=%s", gname);
2571 fprintf(stderr,
_(
"%s: Could not get gname for gid=%lu\n"),
2575 (
unsigned long) st->st_gid);
2578 output(indent, &offset,
"gid=%lu", (
unsigned long)st->st_gid);
2581 output(indent, &offset,
"mode=%#o", (st->st_mode &
MBITS));
2582 if (
KF_ISSET(keys, NLINK) && st->st_nlink != 1)
2583 output(indent, &offset,
"nlink=%lu", (
unsigned long)st->st_nlink);
2584 if (
KF_ISSET(keys, SIZE) && S_ISREG(st->st_mode))
2585 output(indent, &offset,
"size=%llu", (
unsigned long long)st->st_size);
2588 #if defined(TIMESPEC_TO_TIMEVAL) 2591 tv.tv_sec = (long)st->st_mtime;
2594 output(indent, &offset,
"time=%lu.%lu",
2595 (
unsigned long) tv.tv_sec,
2596 (
unsigned long) tv.tv_usec);
2600 if (S_ISREG(st->st_mode)) {
2604 FD_t fd =
Fopen(fts_accpath,
"r.ufdio");
2608 if (fd == NULL ||
Ferror(fd)) {
2610 (void) fprintf(stderr,
_(
"%s: %s: cksum: %s\n"),
2620 if (fts->
algos != NULL)
2626 i =
crc(fd, &val, &len);
2628 char buffer[16 * 1024];
2629 while (
Fread(buffer,
sizeof(buffer[0]),
sizeof(buffer), fd) > 0)
2631 i = (
Ferror(fd) ? 1 : 0);
2635 (void) fprintf(stderr,
_(
"%s: %s: cksum: %s\n"),
2646 output(indent, &offset,
"cksum=%lu", (
unsigned long)val);
2650 if (fts->
algos != NULL)
2651 for (i = 0; i < (int) fts->
algos->
nvals; i++) {
2652 static int asAscii = 1;
2653 const char * digest = NULL;
2654 size_t digestlen = 0;
2660 assert(digest != NULL);
2666 if (tagname != NULL)
2667 output(indent, &offset,
"%s=%s", tagname, digest);
2669 digest =
_free(digest);
2686 char * escname =
xmalloc(strlen(name) * 4 + 1);
2688 output(indent, &offset,
"link=%s", escname);
2689 escname =
_free(escname);
2693 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 2694 char * fflags = fflagstostr(st->st_flags);
2696 if (fflags != NULL && fflags[0] !=
'\0')
2697 output(indent, &offset,
"flags=%s", fflags);
2699 output(indent, &offset,
"flags=none");
2702 output(indent, &offset,
"flags=none");
2705 (void) putchar(
'\n');
2752 char buffer[16 * 1024];
2755 fprintf(stderr,
_(
"%s: open of %s failed: %s\n"),
__progname,
2757 if (fd != NULL) (void)
Fclose(fd);
2761 while (fgets(buffer, (
int)
sizeof(buffer), fp) != NULL) {
2766 buffer[
sizeof(buffer)-1] =
'\0';
2767 for (line = buffer; *line !=
'\0'; line++)
2768 if (strchr(
" \t\n\r", line[1]) == NULL)
break;
2769 if (*line ==
'\0' || *line ==
'#')
2771 for (len = strlen(line); len > 0; len--)
2772 if (strchr(
" \t\n\r", line[len-1]) == NULL)
break;
2778 e->
pathname = (strchr(line,
'/') != NULL ? 1 : 0);
2797 #define MATCH(g, n) (fnmatch((g), (n), FNM_PATHNAME) == 0) 2814 if (S_ISDIR((*a)->fts_statp->st_mode)) {
2815 if (!S_ISDIR((*b)->fts_statp->st_mode))
2817 }
else if (S_ISDIR((*b)->fts_statp->st_mode))
2819 return strcmp((*a)->fts_name, (*b)->fts_name);
2822 #if defined(_RPMFI_INTERNAL) 2832 size_t flen = strlen(fn);
2833 size_t slen = strlen(suffix);
2834 return (flen > slen && !strcmp(fn + flen - slen, suffix));
2837 static int _rpmfiStat(
const char * path,
struct stat * st)
2842 rpmfi fi = _rpmfts->fi;
2843 size_t len = strlen(fts->
paths[0]);
2849 fprintf(stderr,
"*** _rpmfiStat(%s, %p) fi %p rc %d\n", path+len, st, fi, rc);
2854 static int _rpmfiClosedir( DIR * dir)
2858 rpmfi fi = _rpmfts->fi;
2861 fprintf(stderr,
"*** _rpmfiClosedir(%p) fi %p\n", dir, fi);
2863 return avClosedir(dir);
2866 static struct dirent * _rpmfiReaddir(DIR * dir)
2870 rpmfi fi = _rpmfts->fi;
2874 fprintf(stderr,
"*** _rpmfiReaddir(%p) fi %p %p \"%s\"\n", dir, fi, dp, (dp != NULL ? dp->d_name :
""));
2882 uint8_t * rpmfiParentDirNotWithin(
rpmfi fi)
2885 size_t * dnlens =
xmalloc(fi->dc *
sizeof(*dnlens));
2886 uint8_t * noparent = memset(
xmalloc(fi->dc), 1, fi->dc);
2889 for (i = 0; i < (int)fi->dc; i++)
2890 dnlens[i] = strlen(fi->dnl[i]);
2893 for (i = 0; i < (int)fi->fc; i++) {
2894 size_t dnlen, bnlen;
2896 if (!S_ISDIR(fi->fmodes[i]))
2899 dnlen = dnlens[fi->dil[i]];
2900 bnlen = strlen(fi->bnl[i]);
2902 for (j = 0; j < (int)fi->dc; j++) {
2904 if (!noparent[j] || j == (
int)fi->dil[i])
2906 if (dnlens[j] != (dnlen+bnlen+1))
2908 if (strncmp(fi->dnl[j], fi->dnl[fi->dil[i]], dnlen))
2910 if (strncmp(fi->dnl[j]+dnlen, fi->bnl[i], bnlen))
2912 if (fi->dnl[j][dnlen+bnlen] !=
'/' || fi->dnl[j][dnlen+bnlen+1] !=
'\0')
2916 noparent[j] = (uint8_t)0;
2920 dnlens =
_free(dnlens);
2924 static Header rpmftsReadHeader(rpmfts fts,
const char * path)
2954 static rpmfi rpmftsLoadFileInfo(rpmfts fts,
const char * path)
2959 size_t nb = strlen(fn);
2963 h = rpmftsReadHeader(fts, fn);
2974 static DIR * _rpmfiOpendir(
const char * path)
2983 if (fts->ts == NULL)
2986 if (fts->fi == NULL) {
2987 rpmfi fi = rpmftsLoadFileInfo(fts, path);
2988 uint8_t * noparent = rpmfiParentDirNotWithin(fi);
2990 const char ** fnames = NULL;
2998 if (!S_ISDIR(fi->fmodes[i]) && !noparent[fi->dil[i]])
3001 fmodes[ac++] = fi->fmodes[i];
3004 dir = (DIR *) avOpendir(path, fnames, fmodes);
3007 fmodes =
_free(fmodes);
3008 noparent =
_free(noparent);
3011 const char * dn = path + strlen(fts->
paths[0]);
3017 fprintf(stderr,
"*** _rpmfiOpendir(%s) dir %p\n", path, dir);
3022 #define ALIGNBYTES (__alignof__ (long double) - 1) 3023 #define ALIGN(p) (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES) 3040 len =
sizeof(*p) + namelen;
3048 memmove(p->
fts_name, name, namelen);
3065 static void _rpmfiSetFts(rpmfts fts)
3069 char *
const * argv = (
char *
const *) fts->
paths;
3072 int (*compar) (
const FTSENT **,
const FTSENT **) = sp->compar;
3074 register FTSENT *p, *root;
3081 fprintf(stderr,
"*** _rpmfiSetFts(%p)\n", fts);
3092 if (*argv != NULL) {
3098 for (root = NULL,
nitems = 0; *argv != NULL; ++argv, ++
nitems) {
3099 len = strlen(*argv);
3104 p->fts_accpath = p->fts_name;
3110 p->fts_info =
FTS_D;
3113 p->fts_name[len-1] =
'\0';
3114 {
struct stat * st = p->fts_statp;
3115 int xx =
Stat(p->fts_accpath, st);
3117 st->st_mode &= ~S_IFMT;
3118 st->st_mode |= S_IFDIR;
3119 p->fts_dev = st->st_dev;
3120 p->fts_ino = st->st_ino;
3121 p->fts_nlink = st->st_nlink;
3123 p->fts_name[len-1] =
'/';
3124 p->fts_info =
FTS_D;
3149 if (compar &&
nitems > 1)
3170 #if defined(_RPMFI_INTERNAL) 3175 const char * empty = NULL;
3176 char *
const * paths = (
char *
const *) (isrpm ? &empty : fts->
paths);
3184 #if defined(_RPMFI_INTERNAL) 3191 while ((fts->
p =
Fts_read(fts->
t)) != NULL) {
3202 (
void) printf(
"\n");
3204 (void) printf(
"# %s\n", fts->
p->
fts_path);
3210 (void) printf(
"%*s# %s\n", indent,
"", fts->
p->
fts_path);
3211 (void) printf(
"%*s..\n", indent,
"");
3213 (
void) printf(
"\n");
3218 (void) fprintf(stderr,
"%s: %s: %s\n",
__progname,
3242 for (; p != NULL; p = p->
next) {
3248 (void) strcpy(tail, p->
name);
3257 (
void) printf(
_(
"missing: %s"), fts->
path);
3260 (void) putchar(
'\n');
3265 type = (p->
type ==
F_LINK ?
"symlink" :
"directory");
3268 (
void) printf(
_(
" (%s not created: user not specified)"), type);
3270 (void) printf(
_(
" (%s not created: group not specified))"),
type);
3273 (
void) printf(
_(
" (%s not created: %s)\n"), type,
3276 (
void) printf(
_(
" (%s created)\n"), type);
3281 if (p->
sb.st_uid == (uid_t)-1)
3283 else if (
lchown(fts->
path, (uid_t)-1, p->
sb.st_gid) == -1)
3284 what =
"user & group";
3289 (void) printf(
_(
"%s: %s not modified: %s\n"),
3294 (
void) printf(
_(
" (%s not created: mode not specified)"), type);
3296 (void) printf(
_(
" (%s not created: %s)"),
type, strerror(
errno));
3299 (void) printf(
_(
" (%s created)"),
type);
3304 (
void) putchar(
'\n');
3306 for (tp = tail; *tp !=
'\0'; ++tp);
3317 if (p->
sb.st_uid == (uid_t)-1)
3319 else if (
Chown(fts->
path, (uid_t)-1, p->
sb.st_gid) == -1)
3320 what =
"user & group";
3325 (void) printf(
_(
"%s: %s not modified: %s\n"),
3330 (
void) printf(
_(
"%s: permissions not set: %s\n"),
3332 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 3334 chflags(fts->
path, p->
sb.st_flags))
3335 (void) printf(
_(
"%s: file flags not set: %s\n"),
3344 #if defined(_RPMFI_INTERNAL) 3349 const char * empty = NULL;
3350 char *
const * paths = (
char *
const *) (isrpm ? &empty : fts->
paths);
3352 NODE * level = NULL;
3357 fts->
t =
Fts_open((
char *
const *)paths, ftsoptions, NULL);
3361 #if defined(_RPMFI_INTERNAL) 3368 while ((fts->
p =
Fts_read(fts->
t)) != NULL) {
3369 const char * fts_name = fts->
p->
fts_name;
3373 fprintf(stderr,
"==> level %d info 0x%x name %p[%d] \"%s\" accpath \"%s\" path \"%s\"\n", fts->
p->
fts_level, fts->
p->
fts_info, fts_name, fts_namelen, fts_name, fts->
p->
fts_accpath, fts->
p->
fts_path);
3376 if (fts->
p->
fts_level == 0 && fts_namelen == 0) {
3378 fts_namelen =
sizeof(
".") - 1;
3389 assert(specdepth == 0);
3391 level = root = fts->
root;
3393 level = root = root->
next;
3394 assert(level == level->
parent);
3399 for (level = level->
parent; level->
prev != NULL; level = level->
prev);
3406 (void) fprintf(stderr,
"%s: %s: %s\n",
__progname,
3417 for (ep = level; ep != NULL; ep = ep->
next)
3422 !strcmp(ep->
name, fts_name))
3447 (void) printf(
_(
", not removed: %s"), strerror(
errno));
3449 (
void) printf(
_(
", removed"));
3451 (void) putchar(
'\n');
3466 enum poptCallbackReason reason,
3467 const struct poptOption * opt,
const char * arg,
3475 if (opt->arg == NULL)
3479 if (_rpmfts->
spec1 == NULL) {
3480 if ((_rpmfts->
spec1 = fopen(arg,
"r")) != NULL)
3482 }
else if (_rpmfts->
spec2 == NULL) {
3483 if ((_rpmfts->
spec2 = fopen(arg,
"r")) != NULL)
3487 poptPrintUsage(con, stderr, 0);
3498 while ((p = strsep((
char **)&arg,
" \t,")) != NULL) {
3529 fprintf(stderr,
_(
"%s: Unknown option -%c\n"),
__progname, opt->val);
3530 poptPrintUsage(con, stderr, 0);
3539 { NULL,
'\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
3544 { NULL,
'L', POPT_ARG_NONE, NULL, (int)
'L',
3545 N_(
"Follow symlinks"), NULL },
3547 { NULL,
'P', POPT_ARG_NONE, NULL, (int)
'P',
3548 N_(
"Don't follow symlinks"), NULL },
3549 { NULL,
'X', POPT_ARG_NONE, NULL, (int)
'X',
3550 N_(
"Read fnmatch(3) exclude patterns from <file>"),
N_(
"<file>") },
3553 N_(
"Print file tree specification to stdout"), NULL },
3555 N_(
"Directories only"), NULL },
3557 N_(
"Don't complain about files not in the specification"), NULL },
3558 {
"file",
'f', POPT_ARG_STRING, NULL, (int)
'f',
3559 N_(
"Read file tree <spec>"),
N_(
"<spec>") },
3561 N_(
"Indent sub-directories"), NULL },
3562 {
"add",
'K', POPT_ARG_STRING, NULL, (int)
'K',
3563 N_(
"Add <key> to specification"),
N_(
"<key>") },
3564 {
"key",
'k', POPT_ARG_STRING, NULL, (int)
'k',
3565 N_(
"Use \"type\" keywords instead"),
N_(
"<key>") },
3567 N_(
"Loose permissions check"), NULL },
3569 N_(
"Don't include sub-directory comments"), NULL },
3571 N_(
"Use <path> rather than current directory"),
N_(
"<path>") },
3574 N_(
"Quiet mode"), NULL },
3576 N_(
"Remove files not in specification"), NULL },
3578 N_(
"Display crc for file(s) with <seed>"),
N_(
"<seed>") },
3580 N_(
"Touch files iff timestamp differs"), NULL },
3582 N_(
"Update owner/group/permissions to match specification"), NULL },
3584 N_(
"Same as -u, but ignore match status on exit"), NULL },
3586 N_(
"Treat missing uid/gid as warning"), NULL },
3589 N_(
"Don't cross mount points"), NULL },
3592 N_(
"Fts(3) traversal options:"), NULL },
3595 N_(
"Available digests:"), NULL },
3598 N_(
"Common options for all rpmio executables:"),
3604 { NULL, (char)-1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
3606 Usage: mtree [-cdeilnqrtUux] [-f spec] [-K key] [-k key] [-p path] [-s seed]\n\ 3612 #if defined(__linux__) 3614 static const char *my_getlogin(
void)
3618 const char *s = getlogin();
3623 struct passwd *pw = getpwuid(geteuid());
3626 if (pw != NULL && pw->pw_name != NULL && pw->pw_name[0] !=
'\0') {
3627 if (asprintf(&ss,
_(
"(no controlling terminal) %s"), pw->pw_name) < 0) {
3632 if (asprintf(&ss,
_(
"(no controlling terminal) #%d"), geteuid()) < 0) {
3641 #define __getlogin my_getlogin 3643 #define __getlogin getlogin 3665 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 3667 fts->
sb.st_flags = 0xffffffff;
3671 optCon =
rpmioInit(argc, argv, optionsTable);
3674 argv = (
char **) poptGetArgs(optCon);
3675 if (!(argv == NULL || argv[0] == NULL)) {
3676 poptPrintUsage(optCon, stderr, 0);
3681 mtree_error(
"-l and -u flags are mutually exclusive");
3690 mtree_error(
"-L and -P flags are mutually exclusive");
3697 if (fts->
paths == NULL || fts->
paths[0] == NULL) {
3703 for (i = 0; fts->
paths[i] != NULL; i++) {
3707 const char * lpath = NULL;
3709 size_t nb = (size_t)(lpath - fts->
paths[i]);
3710 int isdir = (lpath[strlen(lpath)-1] ==
'/');
3713 if (lpath[0] !=
'/') {
3721 if (rpath != fullpath)
3722 rpath =
_free(rpath);
3735 strncpy(fullpath, fts->
paths[i], nb);
3736 fullpath[nb] =
'\0';
3738 lpath =
_free(lpath);
3743 lpath = (isdir || (!
Stat(rpath, &sb) && S_ISDIR(sb.st_mode))
3748 rpath =
_free(rpath);
3761 char host[MAXHOSTNAMELEN];
3763 (void) time(&clock);
3764 (void) gethostname(host,
sizeof(host));
3765 (void) printf(
"#\t user: %s\n",
__getlogin());
3766 (void) printf(
"#\tmachine: %s\n", host);
3767 for (i = 0; fts->
paths[i] != NULL; i++)
3768 (
void) printf(
"#\t tree: %s\n", fts->
paths[i]);
3769 (void) printf(
"#\t date: %s", ctime(&clock));
3773 (void) fprintf(stderr,
_(
"%s: %s checksum: %u\n"),
__progname,
3777 if (fts->
spec2 != NULL) {
3788 (void) fprintf(stderr,
_(
"%s: %s checksum: %u\n"),
__progname,
3803 #if defined(_RPMFI_INTERNAL) 3809 if (fts->
spec1 != NULL && fileno(fts->
spec1) > 2) {
3810 (void) fclose(fts->
spec1);
3813 if (fts->
spec2 != NULL && fileno(fts->
spec2) > 2) {
3814 (void) fclose(fts->
spec2);
3818 #if defined(HAVE_STRUCT_STAT_ST_FLAGS) 3819 fts->f =
_free(fts->f);
static void unset(char *t, NODE *ip)
static const char * suffix[]
poptContext rpmioInit(int argc, char *const argv[], struct poptOption *optionsTable)
#define CWALKINDENTNAMELEN
static FTSENT * fts_sort(FTS *sp, FTSENT *head, int nitems)
struct poptOption rpmioDigestPoptTable[]
Digest options using popt.
rpmtime_t rpmswExit(rpmop op, ssize_t rc)
Exit timed operation.
FTS * Fts_open(char *const *argv, int options, int(*compar)(const FTSENT **, const FTSENT **))
Create a handle for file hierarchy traversal.
static int keycompare(const void *a, const void *b)
static unsigned parsekey(char *name, uint32_t *needvaluep)
static int mtreeCheckExcludes(const char *fname, const char *path)
void tagClean(headerTagIndices _rpmTags)
Free memory in header tag indices.
static struct rpmfts_s __rpmfts
#define KF_ISSET(_keys, _KEY)
int Symlink(const char *oldpath, const char *newpath)
symlink(3) clone.
char * xstrdup(const char *str)
FTSENT * Fts_children(FTS *sp, int instr)
Return list of children of the current node.
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
#define RPM_LIST_INIT(head)
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
int Utimes(const char *path, const struct timeval *times)
utimes(2) clone.
Structure(s) used for file info tag sets.
static void mtreeArgCallback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, void *data)
static const char copyright[]
static struct rpmop_s dc_totalops
static const char * algo2tagname(uint32_t algo)
char * gidToGname(gid_t gid)
struct poptOption rpmioFtsPoptTable[]
int(* fts_closedir)(DIR *dir)
rpmtime_t rpmswAdd(rpmop to, rpmop from)
Sum statistic counters.
int Stat(const char *path, struct stat *st)
stat(2) clone.
static const uint32_t crctab[]
static int mtreeCWalk(rpmfts fts)
static FTSENT * fts_alloc(FTS *sp, const char *name, int namelen)
static int dsort(const FTSENT **a, const FTSENT **b)
static void mtreeVisitF(rpmfts fts)
static struct rpmop_s dc_readops
rpmfi rpmfiFree(rpmfi fi)
Destroy a file info set.
const char * rpmfiFN(rpmfi fi)
Return current file name from file info set.
static void mtreeReadExcludes(const char *fn)
int main(int argc, char *argv[])
rpmfi rpmfiNew(const void *_ts, Header h, rpmTag tagN, int flags)
Create and load a file info set.
static u_short fts_stat(FTS *sp, FTSENT *p, int follow)
static void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int _flags)
Attach digest to fd.
int rpmfiFC(rpmfi fi)
Return file count from file info set.
void rpmswPrint(const char *name, rpmop op, FILE *fp)
Print operation statistics.
static rpmop fdstat_op(FD_t fd, fdOpX opx)
static struct rpmop_s dc_digestops
static const char * algo2name(uint32_t algo)
int Chown(const char *path, uid_t owner, gid_t group)
chown(2) clone.
static void shownode(NODE *n, enum mtreeKeys_e keys, const char *path)
static int crc(FD_t fd, uint32_t *cval, uint32_t *clen)
const char * Fstrerror(FD_t fd)
strerror(3) clone.
void * xcalloc(size_t nmemb, size_t size)
int Rmdir(const char *path)
rmdir(2) clone.
struct dirent *(* fts_readdir)(DIR *dir)
static void mtree_error(const char *fmt,...)
int gnameToGid(const char *thisGname, gid_t *gid)
static int strvis(char *dst, const char *src, int flag)
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
static int mtreeVSpec(rpmfts fts)
int Mkdir(const char *path, mode_t mode)
mkdir(2) clone.
int(* fts_lstat)(const char *path, struct stat *st)
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
static int mtreeVWalk(rpmfts fts)
rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char *fn, Header *hdrp)
Return package header from file handle, verifying digests/signatures.
static const char * rlink(const char *name)
static struct @9 excludes
static const char * ftype(unsigned type)
The FD_t File Handle data structure.
static void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, void *datap, size_t *lenp, int asAscii)
const char * rpmGenPath(const char *urlroot, const char *urlmdir, const char *urlfile)
Merge 3 args into path, any or all of which may be a url.
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
static int unvis(char *cp, char c, int *astate, int flag)
Header headerFree(Header h)
Dereference a header instance.
FTSENT * Fts_read(FTS *sp)
Return next node in the file hierarchy traversal.
int rpmswEnter(rpmop op, ssize_t rc)
Enter timed operation.
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
static struct poptOption optionsTable[]
static int strunvis(char *dst, const char *src)
#define RPM_LIST_INSERT_HEAD(head, elm, field)
int Fclose(FD_t fd)
fclose(3) clone.
#define TIMESPEC_TO_TIMEVAL(tv, ts)
#define RPM_LIST_ENTRY(type)
Cumulative statistics for an operation.
int rpmfiNext(rpmfi fi)
Return next file iterator index.
int Fts_set(FTS *sp, FTSENT *p, int instr)
Modify the traversal for a file set member.
int Readlink(const char *path, char *buf, size_t bufsiz)
readlink(2) clone.
static void output(int indent, int *offset, const char *fmt,...)
void * rpmfiOpendir(rpmfi fi, const char *name)
Return directory stream onto file info set.
enum rpmRC_e rpmRC
RPM return codes.
int Ferror(FD_t fd)
ferror(3) clone.
static int compare_nodes(NODE *n1, NODE *n2, const char *path)
static const char * inotype(mode_t mode)
rpmfi rpmfiInit(rpmfi fi, int fx)
Initialize file iterator index.
static int mtreeVisitD(rpmfts fts)
urltype urlPath(const char *url, const char **pathp)
Return path component of URL.
rpmts rpmtsFree(rpmts ts)
Destroy transaction set, closing the database as well.
static void set(char *t, NODE *ip)
static int vsnprintf(char *buf, int nb, const char *fmt, va_list ap)
static enum mtreeFlags_e mtreeFlags
rpmts rpmtsCreate(void)
Create an empty transaction set.
static int mtreeSWalk(NODE *t1, NODE *t2, const char *path)
struct rpmts_s * rpmts
The RPM Transaction Set.
int glob(const char *pattern, int flags, int(*errfunc) __P((const char *, int)), glob_t *pglob)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
char * uidToUname(uid_t uid)
Structures and prototypes used for an "rpmts" transaction set.
#define RPM_LIST_FOREACH(var, head, field)
static int chkSuffix(const char *fn, const char *suffix)
Check string for a suffix.
static int compare(rpmfts fts, NODE *const s)
int argiAdd(ARGI_t *argip, int ix, int val)
Add an int to an argi array.
static char * vis(char *dst, int c, int flag, int nextc)
#define _FTSCALLOC(_p, _n)
static NODE * mtreeSpec(rpmfts fts, FILE *fp)
int Fts_close(FTS *sp)
Destroy a file hierarchy traversal handle.
int(* fts_stat)(const char *path, struct stat *st)
static void mtreeMiss(rpmfts fts, NODE *p, char *tail)
#define RPM_LIST_HEAD(name, type)
DIR *(* fts_opendir)(const char *path)
int Chmod(const char *path, mode_t mode)
chmod(2) clone.
mtreeKeys_e
Bit field enum for mtree keys.
mtreeFlags_e
Bit field enum for mtree CLI options.
struct poptOption rpmioAllPoptTable[]
int rpmfiStat(rpmfi fi, const char *path, struct stat *st)
Return lstat(2) data of path from file info set.
int unameToUid(const char *thisUname, uid_t *uid)
poptContext rpmioFini(poptContext optCon)
int fnmatch(char *pattern, const char *string, int flags) const
In Memoriam: Steve Taylor staylor@redhat.com was here, now he's not.
char * Realpath(const char *path, char *resolved_path)
realpath(3) clone.
struct _ftsent * fts_link
#define FTS_ROOTPARENTLEVEL
static int mismatch(NODE *n1, NODE *n2, enum mtreeKeys_e differ, const char *path)
int Unlink(const char *path)
unlink(2) clone.