36 "@(#) Copyright (c) 1989, 1990, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
46 #if !defined(HAVE_ASPRINTF)
50 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__)
51 #define HAVE_ST_FLAGS 1
56 #if defined(__linux__)
57 #define st_mtimespec st_mtim
60 #if defined(__QNXNTO__)
61 #define st_mtimespec st_mtime
69 #undef _RPMFI_INTERNAL
70 #if defined(_RPMFI_INTERNAL)
71 #define _RPMAV_INTERNAL
80 #define RPM_LIST_HEAD(name, type) \
81 struct name { struct type *lh_first; }
82 #define RPM_LIST_ENTRY(type) \
83 struct { struct type *le_next;struct type **le_prev; }
84 #define RPM_LIST_EMPTY(head) \
85 ((head)->lh_first == NULL)
86 #define RPM_LIST_FIRST(head) \
88 #define RPM_LIST_NEXT(elm, field) \
89 ((elm)->field.le_next)
90 #define RPM_LIST_INIT(head) \
91 do { RPM_LIST_FIRST((head)) = NULL; } while (0)
92 #define RPM_LIST_INSERT_HEAD(head, elm, field) \
93 do { if ((RPM_LIST_NEXT((elm), field) = RPM_LIST_FIRST((head))) != NULL) \
94 RPM_LIST_FIRST((head))->field.le_prev = &RPM_LIST_NEXT((elm), field);\
95 RPM_LIST_FIRST((head)) = (elm); \
96 (elm)->field.le_prev = &RPM_LIST_FIRST((head)); } while (0)
97 #define RPM_LIST_FOREACH(var, head, field) \
98 for ((var) = RPM_LIST_FIRST((head)); (var); (var) = RPM_LIST_NEXT((var), field))
100 #define _MTREE_INTERNAL
103 #define _KFB(n) (1U << (n))
104 #define _MFB(n) (_KFB(n) | 0x40000000)
131 #if defined(_MTREE_INTERNAL)
172 #define F_BLOCK 0x001
209 #if defined(HAVE_ST_FLAGS)
224 #if defined(_RPMFI_INTERNAL)
274 #define MF_ISSET(_FLAG) ((mtreeFlags & ((MTREE_FLAGS_##_FLAG) & ~0x40000000)) != MTREE_FLAGS_NONE)
277 (MTREE_KEYS_GID | MTREE_KEYS_MODE | MTREE_KEYS_NLINK | MTREE_KEYS_SIZE | \
278 MTREE_KEYS_SLINK | MTREE_KEYS_TIME | MTREE_KEYS_UID)
280 #define MISMATCHEXIT 2
282 #if !defined(S_ISTXT) && defined(S_ISVTX)
283 #define S_ISTXT S_ISVTX
285 #define MBITS (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
320 __attribute__ ((format (printf, 1, 2)))
333 (void) vfprintf(stderr, fmt, ap);
335 (void) fprintf(stderr,
"\n");
337 (void)fprintf(stderr,
_(
"%s: failed at line %d of the specification\n"),
347 #define NEEDVALUE 0xffffffff
406 if (needvaluep != NULL)
416 if (needvaluep != NULL)
417 *needvaluep = k->flags;
425 const char * tagname = NULL;
448 default: tagname = NULL;
break;
453 #if defined(HAVE_ST_FLAGS)
455 flags_to_string(u_long fflags)
458 char *
string = fflagstostr(fflags);
459 if (
string != NULL && *
string ==
'\0') {
472 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
473 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
474 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
475 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
476 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
477 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
478 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
479 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
480 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
481 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
482 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
483 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
484 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
485 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
486 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
487 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
488 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
489 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
490 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
491 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
492 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
493 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
494 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
495 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
496 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
497 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
498 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
499 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
500 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
501 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
502 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
503 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
504 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
505 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
506 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
507 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
508 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
509 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
510 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
511 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
512 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
513 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
514 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
515 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
516 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
517 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
518 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
519 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
520 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
521 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
522 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
532 crc(
FD_t fd, uint32_t * cval, uint32_t * clen)
539 #define COMPUTE(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
543 { uint8_t buf[16 * 1024];
545 while ((nr =
Fread(buf,
sizeof(buf[0]),
sizeof(buf), fd)) != 0) {
547 for (len += nr, p = buf; nr--; ++p) {
559 for (; len != 0; len >>= 8) {
564 *cval = (crc ^ 0xffffffff);
574 #define VIS_OCTAL 0x01
575 #define VIS_CSTYLE 0x02
584 #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
585 #define VIS_SAFE 0x20
590 #define VIS_NOSLASH 0x40
595 #define UNVIS_VALID 1
596 #define UNVIS_VALIDPUSH 2
597 #define UNVIS_NOCHAR 3
598 #define UNVIS_SYNBAD -1
599 #define UNVIS_ERROR -2
606 static char *
vis(
char *dst,
int c,
int flag,
int nextc)
608 static int strvis(
char *dst,
const char *src,
int flag)
611 static int strnvis(
char *dst,
const char *src,
size_t siz,
int flag)
613 static int strvisx(
char *dst,
const char *src,
size_t len,
int flag)
616 static int strunvis(
char *dst,
const char *src)
618 static int unvis(
char *cp,
char c,
int *astate,
int flag)
621 #define isoctal(c) (((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7')
622 #define isvisible(c) \
623 (((unsigned)(c) <= (unsigned)UCHAR_MAX && isascii((unsigned char)(c)) && \
624 isgraph((unsigned char)(c))) \
625 || ((flag & VIS_SP) == 0 && (c) == (int)' ') \
626 || ((flag & VIS_TAB) == 0 && (c) == (int)'\t') \
627 || ((flag & VIS_NL) == 0 && (c) == (int)'\n') \
628 || ((flag & VIS_SAFE) \
629 && ((c) == (int)'\b' || (c) == (int)'\007' || (c) == (int)'\r')))
635 vis(
char * dst,
int c,
int flag,
int nextc)
689 if (((c & 0177) == (int)
' ') || (flag &
VIS_OCTAL)) {
691 *dst++ = ((
unsigned char)c >> 6 & 07) +
'0';
692 *dst++ = ((
unsigned char)c >> 3 & 07) +
'0';
693 *dst++ = ((
unsigned char)c & 07) +
'0';
707 *dst++ = (char)(c + (
int)
'@');
732 strvis(
char * dst,
const char * src,
int flag)
737 for (start = dst; (c = *src) !=
'\0';)
738 dst =
vis(dst, (
int)c, flag, (int)*++src);
740 return (dst - start);
745 strnvis(
char * dst,
const char * src,
size_t siz,
int flag)
750 for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
766 dst =
vis(dst, (
int)c, flag, (
int)*++src);
776 while ((c = *src) !=
'\0')
777 dst +=
vis(tbuf, (
int)c, flag, (
int)*++src) - tbuf;
779 return (dst - start);
785 strvisx(
char * dst,
const char * src,
size_t len,
int flag)
790 for (start = dst; len > 1; len--) {
792 dst =
vis(dst, (
int)c, flag, (
int)*++src);
795 dst =
vis(dst, (
int)*src, flag, (
int)
'\0');
797 return (dst - start);
812 #if !defined(isoctal)
813 #define isoctal(c) (((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7')
820 unvis(
char *cp,
char c,
int *astate,
int flag)
848 case '0':
case '1':
case '2':
case '3':
849 case '4':
case '5':
case '6':
case '7':
935 *cp = (*cp << 3) + (c -
'0');
948 *cp = (*cp << 3) + (c -
'0');
979 while ((c = *src++) !=
'\0') {
981 switch (
unvis(dst, c, &state, 0)) {
998 return (dst - start);
1004 #if defined(__linux__) || defined(__LCLINT__) || defined(__QNXNTO__)
1005 #if !defined(HAVE_GETMODE) || !defined(HAVE_SETMODE)
1008 #define SET_LEN_INCR 4
1010 typedef struct bitcmd {
1016 #define CMD2_CLR 0x01
1017 #define CMD2_SET 0x02
1018 #define CMD2_GBITS 0x04
1019 #define CMD2_OBITS 0x08
1020 #define CMD2_UBITS 0x10
1022 #if !defined(HAVE_GETMODE)
1030 getmode(
const void * bbox, mode_t omode)
1034 mode_t clrval, newmode, value;
1036 set = (
const BITCMD *)bbox;
1038 for (value = 0;;
set++)
1047 value = (newmode & S_IRWXU) >> 6;
1051 value = (newmode & S_IRWXG) >> 3;
1055 value = newmode & S_IRWXO;
1056 common:
if ((
set->cmd2 & CMD2_CLR) !=
'\0') {
1057 clrval = (
set->cmd2 & CMD2_SET) !=
'\0' ? S_IRWXO : value;
1058 if ((
set->cmd2 & CMD2_UBITS) !=
'\0')
1059 newmode &= ~((clrval<<6) &
set->bits);
1060 if ((
set->cmd2 & CMD2_GBITS) !=
'\0')
1061 newmode &= ~((clrval<<3) &
set->bits);
1062 if ((
set->cmd2 & CMD2_OBITS) !=
'\0')
1063 newmode &= ~(clrval &
set->bits);
1065 if ((
set->cmd2 & CMD2_SET) !=
'\0') {
1066 if ((
set->cmd2 & CMD2_UBITS) !=
'\0')
1067 newmode |= (value<<6) &
set->bits;
1068 if ((
set->cmd2 & CMD2_GBITS) !=
'\0')
1069 newmode |= (value<<3) &
set->bits;
1070 if ((
set->cmd2 & CMD2_OBITS) !=
'\0')
1071 newmode |= value &
set->bits;
1076 newmode |=
set->bits;
1080 newmode &= ~
set->bits;
1084 if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
1085 newmode |=
set->bits;
1090 #ifdef SETMODE_DEBUG
1091 (
void) printf(
"getmode:%04o -> %04o\n", omode, newmode);
1098 #if !defined(HAVE_SETMODE)
1099 #ifdef SETMODE_DEBUG
1101 dumpmode(BITCMD *
set)
1103 for (;
set->cmd; ++
set)
1104 (
void) printf(
"cmd: '%c' bits %04o%s%s%s%s%s%s\n",
1105 set->cmd,
set->bits,
set->cmd2 ?
" cmd2:" :
"",
1106 set->cmd2 & CMD2_CLR ?
" CLR" :
"",
1107 set->cmd2 & CMD2_SET ?
" SET" :
"",
1108 set->cmd2 & CMD2_UBITS ?
" UBITS" :
"",
1109 set->cmd2 & CMD2_GBITS ?
" GBITS" :
"",
1110 set->cmd2 & CMD2_OBITS ?
" OBITS" :
"");
1114 #define ADDCMD(a, b, c, d) \
1115 if (set >= endset) { \
1117 setlen += SET_LEN_INCR; \
1118 newset = realloc(saveset, sizeof(*newset) * setlen); \
1119 if (newset == NULL) { \
1120 if (saveset != NULL) \
1125 set = newset + (set - saveset); \
1127 endset = newset + (setlen - 2); \
1129 set = addcmd(set, (a), (b), (c), (d))
1131 #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
1134 addcmd( BITCMD *
set,
int op,
int who,
int oparg,
unsigned mask)
1140 set->bits = who ? who : (int) STANDARD_BITS;
1148 set->cmd = (char)op;
1149 set->bits = (who ? (unsigned)who : mask) & oparg;
1155 set->cmd = (char)op;
1157 set->cmd2 = (char)( ((who & S_IRUSR) ? CMD2_UBITS : 0) |
1158 ((who & S_IRGRP) ? CMD2_GBITS : 0) |
1159 ((who & S_IROTH) ? CMD2_OBITS : 0));
1160 set->bits = (mode_t)~0;
1162 set->cmd2 =(char)(CMD2_UBITS | CMD2_GBITS | CMD2_OBITS);
1166 if (oparg == (
int)
'+')
1167 set->cmd2 |= CMD2_SET;
1168 else if (oparg == (
int)
'-')
1169 set->cmd2 |= CMD2_CLR;
1170 else if (oparg == (
int)
'=')
1171 set->cmd2 |= CMD2_SET|CMD2_CLR;
1184 compress_mode( BITCMD *
set)
1188 int setbits, clrbits, Xbits, op;
1190 for (nset =
set;;) {
1192 while ((op = (
int)nset->cmd) != (
int)
'+' && op != (
int)
'-' && op != (
int)
'X') {
1198 for (setbits = clrbits = Xbits = 0;; nset++) {
1199 if ((op = (
int)nset->cmd) == (
int)
'-') {
1200 clrbits |= nset->bits;
1201 setbits &= ~nset->bits;
1202 Xbits &= ~nset->bits;
1203 }
else if (op == (
int)
'+') {
1204 setbits |= nset->bits;
1205 clrbits &= ~nset->bits;
1206 Xbits &= ~nset->bits;
1207 }
else if (op == (
int)
'X')
1208 Xbits |= nset->bits & ~setbits;
1215 set->bits = clrbits;
1221 set->bits = setbits;
1236 setmode(
const char * p)
1242 BITCMD *
set, *saveset, *endset;
1243 sigset_t sigset, sigoset;
1245 int equalopdone = 0;
1246 int permXbits, setlen;
1258 (void) sigfillset(&sigset);
1259 (void) sigprocmask(SIG_BLOCK, &sigset, &sigoset);
1260 (void) umask(mask = umask(0));
1262 (void) sigprocmask(SIG_SETMASK, &sigoset, NULL);
1264 setlen = SET_LEN + 2;
1266 if ((
set = malloc((
unsigned)(
sizeof(*set) * setlen))) == NULL)
1269 endset =
set + (setlen - 2);
1276 perml = strtol(p, NULL, 8);
1278 if (perml < 0 || (perml & ~(STANDARD_BITS|S_ISTXT)))
1284 perm = (int)(mode_t)perml;
1285 while (*++p !=
'\0')
1286 if (*p < '0' || *p >
'7') {
1290 ADDCMD((
int)
'=', (
int)(STANDARD_BITS|S_ISTXT), perm, (
unsigned)mask);
1300 for (who = 0;; ++p) {
1303 who |= STANDARD_BITS;
1306 who |= S_ISUID|S_IRWXU;
1309 who |= S_ISGID|S_IRWXG;
1319 getop:
if ((op = *p++) !=
'+' && op !=
'-' && op !=
'=') {
1327 for (perm = 0, permXbits = 0;; ++p) {
1330 perm |= S_IRUSR|S_IRGRP|S_IROTH;
1337 if (who == 0 || (who & ~S_IRWXO))
1338 perm |= S_ISUID|S_ISGID;
1345 if (who == 0 || (who & ~S_IRWXO)) {
1351 perm |= S_IWUSR|S_IWGRP|S_IWOTH;
1354 permXbits = (int)(S_IXUSR|S_IXGRP|S_IXOTH);
1357 perm |= S_IXUSR|S_IXGRP|S_IXOTH;
1368 ADDCMD((
int)op, who, perm, (
unsigned)mask);
1373 if (op ==
'+' && permXbits) {
1374 ADDCMD((
int)
'X', who, permXbits, (
unsigned)mask);
1377 ADDCMD((
int)*p, who, (
int)op, (
unsigned)mask);
1385 if (perm || (op ==
'=' && !equalopdone)) {
1388 ADDCMD((
int)op, who, perm, (
unsigned)mask);
1392 ADDCMD((
int)
'X', who, permXbits, (
unsigned)mask);
1406 #ifdef SETMODE_DEBUG
1407 (void) printf(
"Before compress_mode()\n");
1410 compress_mode(saveset);
1411 #ifdef SETMODE_DEBUG
1412 (void) printf(
"After compress_mode()\n");
1431 for (; (kw = strtok(t,
"= \t\n")) != NULL; t = NULL) {
1437 if (needvalue && (val = strtok(NULL,
" \t\n")) == NULL)
1442 ip->cksum = strtoul(val, &ep, 10);
1447 #if defined(HAVE_ST_FLAGS)
1448 if (!strcmp(val,
"none")) {
1449 ip->sb.st_flags = 0;
1452 {
unsigned long fset, fclr;
1453 if (strtofflags(&val, &fset, &fclr))
1455 ip->sb.st_flags = fset;
1460 ip->sb.st_gid = strtoul(val, &ep, 10);
1473 if ((m = setmode(val)) == NULL)
1475 ip->sb.st_mode = getmode(m, 0);
1479 ip->sb.st_nlink = strtoul(val, &ep, 10);
1484 (void)
argiAdd(&ip->algos, -1, (
int)needvalue);
1485 (void)
argvAdd(&ip->digests, val);
1489 ip->sb.st_size = strtoul(val, &ep, 10);
1495 ip->slink =
xmalloc(strlen(val) + 1);
1496 if (
strunvis(ip->slink, val) == -1) {
1497 fprintf(stderr,
_(
"%s: filename (%s) encoded incorrectly\n"),
1500 strcpy(ip->slink, val);
1504 #if defined(TIMEVAL_TO_TIMESPEC)
1505 ip->sb.st_mtimespec.tv_sec = strtoul(val, &ep, 10);
1509 ip->sb.st_mtimespec.tv_nsec = strtoul(val, &ep, 10);
1513 ip->sb.st_mtime = strtoul(val, &ep, 10);
1517 (void) strtoul(val, &ep, 10);
1525 if (!strcmp(val,
"block"))
1529 if (!strcmp(val,
"char"))
1533 if (!strcmp(val,
"dir"))
1537 if (!strcmp(val,
"file"))
1539 if (!strcmp(val,
"fifo"))
1543 if (!strcmp(val,
"link"))
1547 if (!strcmp(val,
"socket"))
1555 ip->sb.st_uid = strtoul(val, &ep, 10);
1582 while ((p = strtok(t,
"\n\t ")) != NULL)
1586 #define KF_ISSET(_keys, _KEY) ((_keys) & (MTREE_KEYS_##_KEY))
1592 NODE *centry = NULL;
1597 NODE *forest = NULL;
1605 memset(&ginfo, 0,
sizeof(ginfo));
1606 for (fts->
lineno = 1; fgets(buf, (
int)
sizeof(buf), fp) != NULL;
1607 ++fts->
lineno, c_cur = c_next, c_next = 0)
1614 if ((p = strchr(buf,
'\n')) == NULL)
1618 if (p[-1] ==
'\\') {
1627 for (p = buf; *p && isspace(*p); ++p);
1630 if (*p ==
'\0' || *p ==
'#')
1634 (void)fprintf(stderr,
"line %3d: {%s}\n", fts->
lineno, p);
1642 if ((p = strtok(p,
"\n\t ")) == NULL)
1648 if (strcmp(p + 1,
"set"))
1653 if (strcmp(p + 1,
"unset"))
1655 unset(NULL, &ginfo);
1659 #if !defined(_RPMFI_INTERNAL)
1660 if (strchr(p,
'/') != NULL)
1664 if (!strcmp(p,
"..")) {
1680 centry =
xcalloc(1,
sizeof(*centry) + strlen(p));
1683 if (strpbrk(p,
MAGIC) != NULL)
1686 fprintf(stderr,
_(
"%s: filename (%s) encoded incorrectly\n"),
1688 strcpy(centry->
name, p);
1693 last = root = centry;
1697 }
else if (centry->
name[0] ==
'.' && centry->
name[1] ==
'\0') {
1698 centry->
prev = root;
1699 last = root = root->
next = centry;
1703 last = last->
child = centry;
1706 centry->
prev = last;
1707 last = last->
next = centry;
1722 case F_CHAR:
return "char";
1723 case F_DIR:
return "dir";
1724 case F_FIFO:
return "fifo";
1725 case F_FILE:
return "file";
1726 case F_LINK:
return "link";
1727 case F_SOCK:
return "socket";
1728 default:
return "unknown";
1738 switch(mode & S_IFMT) {
1739 case S_IFBLK:
return "block";
1740 case S_IFCHR:
return "char";
1741 case S_IFDIR:
return "dir";
1742 case S_IFIFO:
return "fifo";
1743 case S_IFREG:
return "file";
1744 case S_IFLNK:
return "link";
1748 default:
return "unknown";
1779 #define FF(a, b, c, d) \
1780 (((a)->flags & (c)) && ((b)->flags & (c)) && ((a)->d) != ((b)->d))
1781 #define FS(a, b, c, d) \
1782 (((a)->flags & (c)) && ((b)->flags & (c)) && strcmp((a)->d,(b)->d))
1783 #define FM(a, b, c, d) \
1784 (((a)->flags & (c)) && ((b)->flags & (c)) && memcmp(&(a)->d,&(b)->d, sizeof (a)->d))
1793 printf(
" cksum=%lu", (
unsigned long) n->
cksum);
1795 printf(
" gid=%lu", (
unsigned long) n->
sb.st_gid);
1799 printf(
" gname=%s", gname);
1801 printf(
" gid=%lu", (
unsigned long) n->
sb.st_gid);
1804 printf(
" mode=%o", (
unsigned) n->
sb.st_mode);
1806 printf(
" nlink=%lu", (
unsigned long) n->
sb.st_nlink);
1809 printf(
" size=%llu", (
unsigned long long)n->
sb.st_size);
1812 printf(
" uid=%lu", (
unsigned long) n->
sb.st_uid);
1816 printf(
" uname=%s", uname);
1818 printf(
" uid=%lu", (
unsigned long) n->
sb.st_uid);
1825 if (n->
algos != NULL)
1826 for (i = 0; i < (int) n->
algos->
nvals; i++) {
1829 if (tagname != NULL)
1830 printf(
" %s=%s", tagname, n->
digests[i]);
1834 #if defined(HAVE_ST_FLAGS)
1836 printf(
" flags=%s", flags_to_string(n->
sb.st_flags));
1857 if (!(differ & keys))
1878 if (n1 == NULL && n2 != NULL) {
1879 differs = n2->
flags;
1880 xx =
mismatch(n1, n2, differs, path);
1883 if (n1 != NULL && n2 == NULL) {
1884 differs = n1->
flags;
1885 xx =
mismatch(n1, n2, differs, path);
1890 xx =
mismatch(n1, n2, differs, path);
1927 for (i = 0; i < (int) n1->
algos->
nvals; i++) {
1937 #if defined(HAVE_ST_FLAGS)
1943 xx =
mismatch(n1, n2, differs, path);
1954 NODE *c1 = (t1 != NULL ? t1->
child : NULL);
1955 NODE *c2 = (t2 != NULL ? t2->
child : NULL);
1958 while (c1 != NULL || c2 != NULL) {
1963 n1 = (c1 != NULL ? c1->
next : NULL);
1964 n2 = (c2 != NULL ? c2->
next : NULL);
1965 if (c1 != NULL && c2 != NULL) {
1985 if (asprintf(&np,
"%s%s/", path, c2->
name)) {
1991 }
else if (c2 == NULL && c1->
type ==
F_DIR) {
1992 if (asprintf(&np,
"%s%s/", path, c1->
name)) {
1998 }
else if (c1 == NULL || c2 == NULL) {
2001 if (asprintf(&np,
"%s%s/", path, c1->
name)) {
2042 if ((len =
Readlink(name, lbuf,
sizeof(lbuf)-1)) == -1)
2048 #define SKIPDOTSLASH(_f) ((_f)[0] == '.' && (_f)[1] == '/' ? (_f) + 2 : (_f))
2050 #define COMPAREINDENTNAMELEN 8
2053 (void) printf(_("%s changed\n"), SKIPDOTSLASH(p->fts_path)); \
2084 default:
return "Unknown";
2102 const char *tab =
"";
2106 if (!S_ISBLK(st->st_mode))
2110 if (!S_ISCHR(st->st_mode))
2114 if (!S_ISDIR(st->st_mode))
2118 if (!S_ISFIFO(st->st_mode))
2122 if (!S_ISREG(st->st_mode))
2133 (void) printf(
_(
"\ttype expected %s found %s)\n"),
2143 (void) printf(
_(
"%s%s expected %lu found %lu"), tab,
"user",
2144 (
unsigned long)s->
sb.st_uid, (
unsigned long)st->st_uid);
2146 if (
Chown(fts_accpath, s->
sb.st_uid, -1))
2147 (
void) printf(
_(
" not modified: %s)\n"), strerror(
errno));
2149 (
void) printf(
_(
" modified)\n"));
2151 (
void) printf(
"\n");
2156 (void) printf(
_(
"%s%s expected %lu found %lu"), tab,
"gid",
2157 (
unsigned long)s->
sb.st_gid, (
unsigned long)st->st_gid);
2159 if (
Chown(fts_accpath, -1, s->
sb.st_gid))
2160 (
void) printf(
_(
" not modified: %s)\n"), strerror(
errno));
2162 (
void) printf(
_(
" modified)\n"));
2164 (
void) printf(
"\n");
2169 mode_t tmode = s->
sb.st_mode;
2170 mode_t mode = (st->st_mode &
MBITS);
2177 if (!((tmode & ~(S_IRWXU|S_IRWXG|S_IRWXO))
2178 || (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO))))
2179 if ((mode | tmode) == tmode)
2183 (void) printf(
_(
"%s%s expected %#o found %#o"), tab,
"permissions",
2184 (unsigned)s->
sb.st_mode, (
unsigned)(st->st_mode &
MBITS));
2186 if (
Chmod(fts_accpath, s->
sb.st_mode))
2187 (
void) printf(
_(
" not modified: %s)\n"), strerror(
errno));
2189 (
void) printf(
_(
" modified)\n"));
2191 (
void) printf(
"\n");
2197 s->
sb.st_nlink != st->st_nlink)
2200 (void) printf(
_(
"%s%s expected %lu found %lu)\n"), tab,
"link_count",
2201 (
unsigned long)s->
sb.st_nlink, (
unsigned long)st->st_nlink);
2204 if (
KF_ISSET(keys, SIZE) && s->
sb.st_size != st->st_size) {
2207 (void) printf(
_(
"%s%s expected %llu found %llu\n"), tab,
"size",
2208 (
unsigned long long)s->
sb.st_size,
2209 (
unsigned long long)st->st_size);
2222 struct timeval tv[2];
2225 #if defined(TIMESPEC_TO_TIMEVAL)
2226 TIMESPEC_TO_TIMEVAL(&tv[0], &s->
sb.st_mtimespec);
2227 TIMESPEC_TO_TIMEVAL(&tv[1], &st->st_mtimespec);
2229 tv[0].tv_sec = (long)s->
sb.st_mtime;
2231 tv[1].tv_sec = (
long)st->st_mtime;
2235 if (tv[0].tv_sec != tv[1].tv_sec || tv[0].tv_usec != tv[1].tv_usec) {
2236 time_t t1 = (time_t)tv[0].tv_sec;
2237 time_t t2 = (time_t)tv[1].tv_sec;
2239 (void) printf(
_(
"%s%s expected %.24s "), tab,
"modification time", ctime(&t1));
2240 (void) printf(
_(
"found %.24s"), ctime(&t2));
2243 if (
Utimes(fts_accpath, tv))
2244 (
void) printf(
_(
" not modified: %s)\n"), strerror(
errno));
2246 (
void) printf(
_(
" modified\n"));
2248 (
void) printf(
"\n");
2255 FD_t fd =
Fopen(fts_accpath,
"r.ufdio");
2259 if (fd == NULL ||
Ferror(fd)) {
2261 (void) printf(
"%scksum: %s: %s\n", tab, fts_accpath,
Fstrerror(fd));
2266 if (s->
algos != NULL)
2272 i =
crc(fd, &val, &vlen);
2274 char buffer[16 * 1024];
2275 while (
Fread(buffer,
sizeof(buffer[0]),
sizeof(buffer), fd) > 0)
2277 i = (
Ferror(fd) ? 1 : 0);
2281 (void) printf(
"%scksum: %s: %s\n", tab, fts_accpath,
Fstrerror(fd));
2287 if (s->
cksum != val) {
2289 (void) printf(
_(
"%s%s expected %lu found %lu\n"), tab,
"cksum",
2290 (
unsigned long) s->
cksum, (
unsigned long) val);
2296 if (s->
algos != NULL)
2297 for (i = 0; i < (int) s->
algos->
nvals; i++) {
2298 static int asAscii = 1;
2300 const char * digest = NULL;
2301 size_t digestlen = 0;
2304 assert(digest != NULL);
2305 if (strcmp(digest, s->
digests[i])) {
2307 printf(
_(
"%s%s expected %s found %s\n"), tab,
algo2name(algo),
2311 digest =
_free(digest);
2327 (void) printf(
_(
"%s%s expected %s found %s\n"), tab,
"link_ref",
2330 #if defined(HAVE_ST_FLAGS)
2331 if (
KF_ISSET(keys, FLAGS) && s->
sb.st_flags != st->st_flags) {
2335 fflags = fflagstostr(s->
sb.st_flags);
2336 (void) printf(
_(
"%s%s expected \"%s\""), tab,
"flags", fflags);
2337 fflags =
_free(fflags);
2339 fflags = fflagstostr(st->st_flags);
2340 (void) printf(
_(
" found \"%s\""), fflags);
2341 fflags =
_free(fflags);
2344 if (chflags(fts_accpath, s->
sb.st_flags))
2345 (void) printf(
" not modified: %s)\n", strerror(
errno));
2347 (
void) printf(
" modified)\n");
2350 (void) printf(
"\n");
2359 #define _FTSCALLOC(_p, _n) \
2361 (_p) = _free(_p); (_p) = xcalloc((_n), sizeof(*(_p))); \
2370 const FTSENT *
const parent = fts->
p;
2376 #if defined(HAVE_ST_FLAGS)
2377 unsigned long maxflags = 0;
2392 #if defined(HAVE_ST_FLAGS)
2397 for (; p != NULL; p = p->
fts_link) {
2400 if (
MF_ISSET(DIRSONLY) || !S_ISDIR(st->st_mode))
2404 { mode_t st_mode = st->st_mode &
MBITS;
2405 if (st_mode < fts->maxm && ++fts->
m[st_mode] > maxmode) {
2406 sb.st_mode = st_mode;
2407 maxmode = fts->
m[st_mode];
2411 if (st->st_gid < fts->
maxg && ++fts->
g[st->st_gid] > maxgid) {
2412 sb.st_gid = st->st_gid;
2413 maxgid = fts->
g[st->st_gid];
2416 if (st->st_uid < fts->
maxu && ++fts->
u[st->st_uid] > maxuid) {
2417 sb.st_uid = st->st_uid;
2418 maxuid = fts->
u[st->st_uid];
2420 #if defined(HAVE_ST_FLAGS)
2427 #define FLAGS2IDX(f) ((f & 0xf) | ((f >> 12) & 0xf0))
2429 {
unsigned long st_flags = FLAGS2IDX(st->st_flags);
2430 if (st_flags < fts->maxf && ++fts->f[st_flags] > maxflags) {
2432 sb.st_flags = st->st_flags;
2433 maxflags = fts->f[st_flags];
2444 if (((
KF_ISSET(keys, UNAME) ||
KF_ISSET(keys, UID)) && (fts->
sb.st_uid != sb.st_uid))
2446 || (
KF_ISSET(keys, MODE) && (fts->
sb.st_mode != sb.st_mode))
2447 #
if defined(HAVE_ST_FLAGS)
2448 || (
KF_ISSET(keys, FLAGS) && (fts->
sb.st_flags != sb.st_flags))
2454 (void) printf(
"/set type=dir");
2456 (
void) printf(
"/set type=file");
2460 (void) printf(
" uname=%s", uname);
2462 fprintf(stderr,
_(
"%s: Could not get uname for uid=%lu\n"),
2466 (
unsigned long)sb.st_uid);
2469 (void) printf(
" uid=%lu", (
unsigned long)sb.st_uid);
2473 (void) printf(
" gname=%s", gname);
2475 fprintf(stderr,
_(
"%s: Could not get gname for gid=%lu\n"),
2479 (
unsigned long) sb.st_gid);
2482 (void) printf(
" gid=%lu", (
unsigned long)sb.st_gid);
2484 (
void) printf(
" mode=%#o", (
unsigned)sb.st_mode);
2486 (void) printf(
" nlink=1");
2487 #if defined(HAVE_ST_FLAGS)
2489 const char * fflags = flags_to_string(sb.st_flags);
2490 (void) printf(
" flags=%s", fflags);
2491 fflags =
_free(fflags);
2494 (void) printf(
"\n");
2500 #define CWALKINDENTNAMELEN 15
2501 #define MAXLINELEN 80
2513 (void)
vsnprintf(buf,
sizeof(buf), fmt, ap);
2516 if (*offset + strlen(buf) >
MAXLINELEN - 3) {
2520 *offset += printf(
" %s", buf) + 1;
2530 unsigned short fts_info = fts->
p->
fts_info;
2535 {
const char * fts_name = fts->
p->
fts_name;
2540 if (fts->
p->
fts_level == 0 && fts_namelen == 0) {
2542 fts_namelen =
sizeof(
".") - 1;
2545 escname =
xmalloc(fts_namelen * 4 + 1);
2549 if (
MF_ISSET(INDENT) || S_ISDIR(st->st_mode))
2550 offset = printf(
"%*s%s", indent,
"", escname);
2552 offset = printf(
"%*s %s", indent,
"", escname);
2553 escname =
_free(escname);
2561 if (!S_ISREG(st->st_mode) && !
MF_ISSET(DIRSONLY))
2563 if (st->st_uid != fts->
sb.st_uid) {
2567 output(indent, &offset,
"uname=%s", uname);
2569 fprintf(stderr,
_(
"%s: Could not get uname for uid=%lu\n"),
2573 (
unsigned long)st->st_uid);
2576 output(indent, &offset,
"uid=%u", st->st_uid);
2578 if (st->st_gid != fts->
sb.st_gid) {
2582 output(indent, &offset,
"gname=%s", gname);
2584 fprintf(stderr,
_(
"%s: Could not get gname for gid=%lu\n"),
2588 (
unsigned long) st->st_gid);
2591 output(indent, &offset,
"gid=%lu", (
unsigned long)st->st_gid);
2594 output(indent, &offset,
"mode=%#o", (st->st_mode &
MBITS));
2595 if (
KF_ISSET(keys, NLINK) && st->st_nlink != 1)
2596 output(indent, &offset,
"nlink=%lu", (
unsigned long)st->st_nlink);
2597 if (
KF_ISSET(keys, SIZE) && S_ISREG(st->st_mode))
2598 output(indent, &offset,
"size=%llu", (
unsigned long long)st->st_size);
2601 #if defined(TIMESPEC_TO_TIMEVAL)
2602 TIMESPEC_TO_TIMEVAL(&tv, &st->st_mtimespec);
2604 tv.tv_sec = (long)st->st_mtime;
2607 output(indent, &offset,
"time=%lu.%lu",
2608 (
unsigned long) tv.tv_sec,
2609 (
unsigned long) tv.tv_usec);
2613 if (S_ISREG(st->st_mode)) {
2617 FD_t fd =
Fopen(fts_accpath,
"r.ufdio");
2621 if (fd == NULL ||
Ferror(fd)) {
2623 (void) fprintf(stderr,
_(
"%s: %s: cksum: %s\n"),
2633 if (fts->
algos != NULL)
2639 i =
crc(fd, &val, &len);
2641 char buffer[16 * 1024];
2642 while (
Fread(buffer,
sizeof(buffer[0]),
sizeof(buffer), fd) > 0)
2644 i = (
Ferror(fd) ? 1 : 0);
2648 (void) fprintf(stderr,
_(
"%s: %s: cksum: %s\n"),
2659 output(indent, &offset,
"cksum=%lu", (
unsigned long)val);
2663 if (fts->
algos != NULL)
2664 for (i = 0; i < (int) fts->
algos->
nvals; i++) {
2665 static int asAscii = 1;
2666 const char * digest = NULL;
2667 size_t digestlen = 0;
2673 assert(digest != NULL);
2679 if (tagname != NULL)
2680 output(indent, &offset,
"%s=%s", tagname, digest);
2682 digest =
_free(digest);
2699 char * escname =
xmalloc(strlen(name) * 4 + 1);
2701 output(indent, &offset,
"link=%s", escname);
2702 escname =
_free(escname);
2706 #if defined(HAVE_ST_FLAGS)
2707 char * fflags = fflagstostr(st->st_flags);
2709 if (fflags != NULL && fflags[0] !=
'\0')
2710 output(indent, &offset,
"flags=%s", fflags);
2712 output(indent, &offset,
"flags=none");
2715 output(indent, &offset,
"flags=none");
2718 (void) putchar(
'\n');
2765 char buffer[16 * 1024];
2768 fprintf(stderr,
_(
"%s: open of %s failed: %s\n"),
__progname,
2770 if (fd != NULL) (void)
Fclose(fd);
2774 while (fgets(buffer, (
int)
sizeof(buffer), fp) != NULL) {
2779 buffer[
sizeof(buffer)-1] =
'\0';
2780 for (line = buffer; *line !=
'\0'; line++)
2781 if (strchr(
" \t\n\r", line[1]) == NULL)
break;
2782 if (*line ==
'\0' || *line ==
'#')
2784 for (len = strlen(line); len > 0; len--)
2785 if (strchr(
" \t\n\r", line[len-1]) == NULL)
break;
2791 e->
pathname = (strchr(line,
'/') != NULL ? 1 : 0);
2810 #define MATCH(g, n) (fnmatch((g), (n), FNM_PATHNAME) == 0)
2827 if (S_ISDIR((*a)->fts_statp->st_mode)) {
2828 if (!S_ISDIR((*b)->fts_statp->st_mode))
2830 }
else if (S_ISDIR((*b)->fts_statp->st_mode))
2832 return strcmp((*a)->fts_name, (*b)->fts_name);
2835 #if defined(_RPMFI_INTERNAL)
2842 static int chkSuffix(
const char * fn,
const char * suffix)
2845 size_t flen = strlen(fn);
2846 size_t slen = strlen(suffix);
2847 return (flen > slen && !strcmp(fn + flen - slen, suffix));
2850 static int _rpmfiStat(
const char * path,
struct stat * st)
2855 rpmfi fi = _rpmfts->fi;
2856 size_t len = strlen(fts->
paths[0]);
2862 fprintf(stderr,
"*** _rpmfiStat(%s, %p) fi %p rc %d\n", path+len, st, fi, rc);
2867 static int _rpmfiClosedir( DIR * dir)
2871 rpmfi fi = _rpmfts->fi;
2874 fprintf(stderr,
"*** _rpmfiClosedir(%p) fi %p\n", dir, fi);
2879 static struct dirent * _rpmfiReaddir(DIR * dir)
2883 rpmfi fi = _rpmfts->fi;
2887 fprintf(stderr,
"*** _rpmfiReaddir(%p) fi %p %p \"%s\"\n", dir, fi, dp, (dp != NULL ? dp->d_name :
""));
2895 uint8_t * rpmfiParentDirNotWithin(
rpmfi fi)
2898 size_t * dnlens =
xmalloc(fi->dc *
sizeof(*dnlens));
2899 uint8_t * noparent = memset(
xmalloc(fi->dc), 1, fi->dc);
2902 for (i = 0; i < (int)fi->dc; i++)
2903 dnlens[i] = strlen(fi->dnl[i]);
2906 for (i = 0; i < (int)fi->fc; i++) {
2907 size_t dnlen, bnlen;
2909 if (!S_ISDIR(fi->fmodes[i]))
2912 dnlen = dnlens[fi->dil[i]];
2913 bnlen = strlen(fi->bnl[i]);
2915 for (j = 0; j < (int)fi->dc; j++) {
2917 if (!noparent[j] || j == (
int)fi->dil[i])
2919 if (dnlens[j] != (dnlen+bnlen+1))
2921 if (strncmp(fi->dnl[j], fi->dnl[fi->dil[i]], dnlen))
2923 if (strncmp(fi->dnl[j]+dnlen, fi->bnl[i], bnlen))
2925 if (fi->dnl[j][dnlen+bnlen] !=
'/' || fi->dnl[j][dnlen+bnlen+1] !=
'\0')
2929 noparent[j] = (uint8_t)0;
2933 dnlens =
_free(dnlens);
2937 static Header rpmftsReadHeader(rpmfts fts,
const char * path)
2967 static rpmfi rpmftsLoadFileInfo(rpmfts fts,
const char * path)
2972 size_t nb = strlen(fn);
2976 h = rpmftsReadHeader(fts, fn);
2987 static DIR * _rpmfiOpendir(
const char * path)
2996 if (fts->ts == NULL)
2999 if (fts->fi == NULL) {
3000 rpmfi fi = rpmftsLoadFileInfo(fts, path);
3001 uint8_t * noparent = rpmfiParentDirNotWithin(fi);
3003 const char ** fnames = NULL;
3011 if (!S_ISDIR(fi->fmodes[i]) && !noparent[fi->dil[i]])
3014 fmodes[ac++] = fi->fmodes[i];
3017 dir = (DIR *)
avOpendir(path, fnames, fmodes);
3020 fmodes =
_free(fmodes);
3021 noparent =
_free(noparent);
3024 const char * dn = path + strlen(fts->
paths[0]);
3030 fprintf(stderr,
"*** _rpmfiOpendir(%s) dir %p\n", path, dir);
3035 #define ALIGNBYTES (__alignof__ (long double) - 1)
3036 #define ALIGN(p) (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES)
3053 len =
sizeof(*p) + namelen;
3061 memmove(p->
fts_name, name, namelen);
3078 static void _rpmfiSetFts(rpmfts fts)
3082 char *
const * argv = (
char *
const *) fts->
paths;
3085 int (*compar) (
const FTSENT **,
const FTSENT **) = sp->compar;
3087 register FTSENT *p, *root;
3094 fprintf(stderr,
"*** _rpmfiSetFts(%p)\n", fts);
3105 if (*argv != NULL) {
3111 for (root = NULL,
nitems = 0; *argv != NULL; ++argv, ++
nitems) {
3112 len = strlen(*argv);
3116 p->fts_parent = parent;
3117 p->fts_accpath = p->fts_name;
3123 p->fts_info =
FTS_D;
3126 p->fts_name[len-1] =
'\0';
3127 {
struct stat * st = p->fts_statp;
3128 int xx =
Stat(p->fts_accpath, st);
3130 st->st_mode &= ~S_IFMT;
3131 st->st_mode |= S_IFDIR;
3132 p->fts_dev = st->st_dev;
3133 p->fts_ino = st->st_ino;
3134 p->fts_nlink = st->st_nlink;
3136 p->fts_name[len-1] =
'/';
3137 p->fts_info =
FTS_D;
3162 if (compar &&
nitems > 1)
3183 #if defined(_RPMFI_INTERNAL)
3188 const char * empty = NULL;
3189 char *
const * paths = (
char *
const *) (isrpm ? &empty : fts->
paths);
3197 #if defined(_RPMFI_INTERNAL)
3204 while ((fts->
p =
Fts_read(fts->
t)) != NULL) {
3215 (
void) printf(
"\n");
3217 (void) printf(
"# %s\n", fts->
p->
fts_path);
3223 (void) printf(
"%*s# %s\n", indent,
"", fts->
p->
fts_path);
3224 (void) printf(
"%*s..\n", indent,
"");
3226 (
void) printf(
"\n");
3231 (void) fprintf(stderr,
"%s: %s: %s\n",
__progname,
3255 for (; p != NULL; p = p->
next) {
3261 (void) strcpy(tail, p->
name);
3270 (
void) printf(
_(
"missing: %s"), fts->
path);
3273 (void) putchar(
'\n');
3278 type = (p->
type ==
F_LINK ?
"symlink" :
"directory");
3281 (
void) printf(
_(
" (%s not created: user not specified)"), type);
3283 (void) printf(
_(
" (%s not created: group not specified))"), type);
3286 (
void) printf(
_(
" (%s not created: %s)\n"), type,
3289 (
void) printf(
_(
" (%s created)\n"), type);
3294 if (p->
sb.st_uid == (uid_t)-1)
3296 else if (
lchown(fts->
path, (uid_t)-1, p->
sb.st_gid) == -1)
3297 what =
"user & group";
3302 (void) printf(
_(
"%s: %s not modified: %s\n"),
3307 (
void) printf(
_(
" (%s not created: mode not specified)"), type);
3309 (void) printf(
_(
" (%s not created: %s)"),type, strerror(
errno));
3312 (void) printf(
_(
" (%s created)"), type);
3317 (
void) putchar(
'\n');
3319 for (tp = tail; *tp !=
'\0'; ++tp);
3330 if (p->
sb.st_uid == (uid_t)-1)
3332 else if (
Chown(fts->
path, (uid_t)-1, p->
sb.st_gid) == -1)
3333 what =
"user & group";
3338 (void) printf(
_(
"%s: %s not modified: %s\n"),
3343 (
void) printf(
_(
"%s: permissions not set: %s\n"),
3345 #if defined(HAVE_ST_FLAGS)
3347 chflags(fts->
path, p->
sb.st_flags))
3348 (void) printf(
_(
"%s: file flags not set: %s\n"),
3357 #if defined(_RPMFI_INTERNAL)
3362 const char * empty = NULL;
3363 char *
const * paths = (
char *
const *) (isrpm ? &empty : fts->
paths);
3365 NODE * level = NULL;
3370 fts->
t =
Fts_open((
char *
const *)paths, ftsoptions, NULL);
3374 #if defined(_RPMFI_INTERNAL)
3381 while ((fts->
p =
Fts_read(fts->
t)) != NULL) {
3382 const char * fts_name = fts->
p->
fts_name;
3386 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);
3389 if (fts->
p->
fts_level == 0 && fts_namelen == 0) {
3391 fts_namelen =
sizeof(
".") - 1;
3402 assert(specdepth == 0);
3404 level = root = fts->
root;
3406 level = root = root->
next;
3407 assert(level == level->
parent);
3412 for (level = level->
parent; level->
prev != NULL; level = level->
prev);
3419 (void) fprintf(stderr,
"%s: %s: %s\n",
__progname,
3430 for (ep = level; ep != NULL; ep = ep->
next)
3435 !strcmp(ep->
name, fts_name))
3460 (void) printf(
_(
", not removed: %s"), strerror(
errno));
3462 (
void) printf(
_(
", removed"));
3464 (void) putchar(
'\n');
3479 enum poptCallbackReason reason,
3480 const struct poptOption * opt,
const char * arg,
3488 if (opt->arg == NULL)
3492 if (_rpmfts->
spec1 == NULL) {
3493 if ((_rpmfts->
spec1 = fopen(arg,
"r")) != NULL)
3495 }
else if (_rpmfts->
spec2 == NULL) {
3496 if ((_rpmfts->
spec2 = fopen(arg,
"r")) != NULL)
3500 poptPrintUsage(con, stderr, 0);
3511 while ((p = strsep((
char **)&arg,
" \t,")) != NULL) {
3518 _rpmfts->
keys |= type;
3542 fprintf(stderr,
_(
"%s: Unknown option -%c\n"),
__progname, opt->val);
3543 poptPrintUsage(con, stderr, 0);
3552 { NULL,
'\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
3557 { NULL,
'L', POPT_ARG_NONE, NULL, (int)
'L',
3558 N_(
"Follow symlinks"), NULL },
3560 { NULL,
'P', POPT_ARG_NONE, NULL, (int)
'P',
3561 N_(
"Don't follow symlinks"), NULL },
3562 { NULL,
'X', POPT_ARG_NONE, NULL, (int)
'X',
3563 N_(
"Read fnmatch(3) exclude patterns from <file>"),
N_(
"<file>") },
3566 N_(
"Print file tree specification to stdout"), NULL },
3568 N_(
"Directories only"), NULL },
3570 N_(
"Don't complain about files not in the specification"), NULL },
3571 {
"file",
'f', POPT_ARG_STRING, NULL, (int)
'f',
3572 N_(
"Read file tree <spec>"),
N_(
"<spec>") },
3574 N_(
"Indent sub-directories"), NULL },
3575 {
"add",
'K', POPT_ARG_STRING, NULL, (int)
'K',
3576 N_(
"Add <key> to specification"),
N_(
"<key>") },
3577 {
"key",
'k', POPT_ARG_STRING, NULL, (int)
'k',
3578 N_(
"Use \"type\" keywords instead"),
N_(
"<key>") },
3580 N_(
"Loose permissions check"), NULL },
3582 N_(
"Don't include sub-directory comments"), NULL },
3584 N_(
"Use <path> rather than current directory"),
N_(
"<path>") },
3587 N_(
"Quiet mode"), NULL },
3589 N_(
"Remove files not in specification"), NULL },
3591 N_(
"Display crc for file(s) with <seed>"),
N_(
"<seed>") },
3593 N_(
"Touch files iff timestamp differs"), NULL },
3595 N_(
"Update owner/group/permissions to match specification"), NULL },
3597 N_(
"Same as -u, but ignore match status on exit"), NULL },
3599 N_(
"Treat missing uid/gid as warning"), NULL },
3602 N_(
"Don't cross mount points"), NULL },
3605 N_(
"Fts(3) traversal options:"), NULL },
3608 N_(
"Available digests:"), NULL },
3611 N_(
"Common options for all rpmio executables:"),
3617 { NULL, (char)-1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
3619 Usage: mtree [-cdeilnqrtUux] [-f spec] [-K key] [-k key] [-p path] [-s seed]\n\
3625 #if defined(__linux__)
3627 static const char *my_getlogin(
void)
3631 const char *s = getlogin();
3636 struct passwd *pw = getpwuid(geteuid());
3639 if (pw != NULL && pw->pw_name != NULL && pw->pw_name[0] !=
'\0') {
3640 if (asprintf(&ss,
_(
"(no controlling terminal) %s"), pw->pw_name) < 0) {
3645 if (asprintf(&ss,
_(
"(no controlling terminal) #%d"), geteuid()) < 0) {
3654 #define __getlogin my_getlogin
3656 #define __getlogin getlogin
3678 #if defined(HAVE_ST_FLAGS)
3680 fts->
sb.st_flags = 0xffffffff;
3687 argv = (
char **) poptGetArgs(optCon);
3688 if (!(argv == NULL || argv[0] == NULL)) {
3689 poptPrintUsage(optCon, stderr, 0);
3694 mtree_error(
"-l and -u flags are mutually exclusive");
3703 mtree_error(
"-L and -P flags are mutually exclusive");
3710 if (fts->
paths == NULL || fts->
paths[0] == NULL) {
3716 for (i = 0; fts->
paths[i] != NULL; i++) {
3720 const char * lpath = NULL;
3722 size_t nb = (size_t)(lpath - fts->
paths[i]);
3723 int isdir = (lpath[strlen(lpath)-1] ==
'/');
3726 if (lpath[0] !=
'/') {
3734 if (rpath != fullpath)
3735 rpath =
_free(rpath);
3748 strncpy(fullpath, fts->
paths[i], nb);
3749 fullpath[nb] =
'\0';
3751 lpath =
_free(lpath);
3756 lpath = (isdir || (!
Stat(rpath, &sb) && S_ISDIR(sb.st_mode))
3761 rpath =
_free(rpath);
3774 char host[MAXHOSTNAMELEN];
3776 (void) time(&clock);
3777 (void) gethostname(host,
sizeof(host));
3778 (void) printf(
"#\t user: %s\n",
__getlogin());
3779 (void) printf(
"#\tmachine: %s\n", host);
3780 for (i = 0; fts->
paths[i] != NULL; i++)
3781 (
void) printf(
"#\t tree: %s\n", fts->
paths[i]);
3782 (void) printf(
"#\t date: %s", ctime(&clock));
3786 (void) fprintf(stderr,
_(
"%s: %s checksum: %u\n"),
__progname,
3790 if (fts->
spec2 != NULL) {
3801 (void) fprintf(stderr,
_(
"%s: %s checksum: %u\n"),
__progname,
3816 #if defined(_RPMFI_INTERNAL)
3822 if (fts->
spec1 != NULL && fileno(fts->
spec1) > 2) {
3823 (void) fclose(fts->
spec1);
3826 if (fts->
spec2 != NULL && fileno(fts->
spec2) > 2) {
3827 (void) fclose(fts->
spec2);
3831 #if defined(HAVE_ST_FLAGS)
3832 fts->f =
_free(fts->f);