5 #define _RPMIOB_INTERNAL 16 #define _KFB(n) (1U << (n)) 17 #define _DFB(n) (_KFB(n) | 0x40000000) 19 #define F_ISSET(_dc, _FLAG) ((_dc)->flags & ((RPMDC_FLAGS_##_FLAG) & ~0x40000000)) 60 const char * (*print) (rpmdc
dc,
int rc);
69 unsigned char buf[BUFSIZ];
93 static const char hmackey[] =
"orboDeJITITejsirpADONivirpUkvarP";
100 uint32_t
dalgo = 0xffffffff;
103 if (!strcmp(dname,
"sha1new"))
106 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
107 if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
109 if (opt->longName == NULL)
111 if (!(opt->val > 0 && opt->val < 256))
113 if (strcmp(opt->longName, dname))
115 dalgo = (uint32_t) opt->val;
128 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
129 if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
131 if (opt->longName == NULL)
133 if (!(opt->val > 0 && opt->val < 256))
135 if ((uint32_t)opt->val !=
dalgo)
137 dalgoName = opt->longName;
157 if (strcmp(dc->
fn,
"-") == 0) {
164 fprintf(stderr,
_(
"%s: Failed to open %s: %s\n"),
174 while (fgets(buf,
sizeof(buf), fp) != NULL) {
175 const char * dname, *
digest, * path;
176 char *se = buf + (int)strlen(buf);
180 while (se > buf &&
xisspace((
int)se[-1]))
185 if (buf[0] ==
'\0')
continue;
187 if (buf[0] ==
'#')
continue;
190 dname = NULL; path = NULL;
191 for (digest = se = buf; (c = (int)*se) != 0; se++)
202 if (se[1] ==
' ' || se[1] ==
'*')
208 fprintf(stderr,
_(
"%s: %s line %u: No file path found.\n"),
218 if (dc->
dalgo == 0xffffffff) {
219 fprintf(stderr,
_(
"%s: %s line %u: Unknown digest name \"%s\"\n"),
233 if (dc->
fd != NULL) {
247 const char *msg = (rc ?
"FAILED" :
"OK");
252 if (rc == 0 &&
F_ISSET(dc, STATUS))
257 nb += strlen(dc->
dalgoName) +
sizeof(
":") - 1;
258 assert(dc->
digest != NULL);
261 nb +=
sizeof(
" *") - 1;
263 nb += strlen(dc->
fn);
272 if (rc || !
F_ISSET(dc, STATUS)) {
283 *te++ = (
F_ISSET(dc, BINARY) ?
'*' :
' ');
310 if (!(xx == 0 && iob != NULL)) {
311 fprintf(stderr,
_(
"%s: Failed to open %s\n"),
__progname, dc->
fn);
316 be = (
char *)(iob->b + iob->blen);
317 while (be > (
char *)iob->b && (be[-1] ==
'\n' || be[-1] ==
'\r')) {
323 be = strrchr((
char *)iob->b,
'=');
326 _(
"%s: %s: Manifest needs \"algo=digest\" as last line\n"),
333 while (be > (
char *)iob->b && !(be[-1] ==
'\n' || be[-1] ==
'\r'))
335 if (be <= (
char *)iob->b) {
336 fprintf(stderr,
_(
"%s: %s: Manifest is empty\n"),
344 fprintf(stderr,
_(
"%s: %s: Unknown digest algo name \"%s\"\n"),
360 if (strcmp(dc->
digest, digest)) {
362 _(
"%s: %s: Manifest digest check: Expected(%s) != (%s)\n"),
367 digest =
_free(digest);
372 for (f = (
char *)iob->b; *f; f = fe) {
373 static const char hexdigits[] =
"0123456789ABCDEFabcdef";
374 const char * _dn = NULL;
379 while (*fe && !(*fe ==
'\n' || *fe ==
'\r'))
381 while (*fe && (*fe ==
'\n' || *fe ==
'\r'))
393 while (*f && strchr(hexdigits, *f) != NULL)
396 fprintf(stderr,
_(
"%s: %s line %u: Malformed digest field.\n"),
405 fprintf(stderr,
_(
"%s: %s line %u: Malformed mtime field.\n"),
414 fprintf(stderr,
_(
"%s: %s line %u: Malformed size field.\n"),
421 fprintf(stderr,
_(
"%s: %s line %u: No file path.\n"),
427 if (_dn && *_dn ==
'/')
458 const struct stat * st = &dc->
sb;
462 if (rc == 0 &&
F_ISSET(dc, STATUS))
465 snprintf(_mtime,
sizeof(_mtime),
"%llu",
466 (
unsigned long long) st->st_mtime);
467 _mtime[
sizeof(_mtime)-1] =
'\0';
468 snprintf(_size,
sizeof(_size),
"%llu",
469 (
unsigned long long) st->st_size);
470 _size[
sizeof(_size)-1] =
'\0';
471 if ((_bn = strrchr(dc->
fn,
'/')) != NULL)
480 nb += 1 + strlen(_mtime);
481 nb += 1 + strlen(_size);
482 nb += 1 + strlen(_bn);
490 const char *msg = (rc ?
"FAILED" :
"OK");
491 if (rc || !
F_ISSET(dc, STATUS)) {
498 if (S_ISDIR(st->st_mode)) {
508 }
else if (S_ISREG(st->st_mode) ||
S_ISLNK(st->st_mode)) {
512 *te++ = (st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) ?
'X' :
'F';
533 static int asAscii = 1;
537 fprintf(stderr,
"\t%s(%p) fd %p fn %s\n", __FUNCTION__, dc, dc->
fd, dc->
fn);
539 assert(dc->
fd != NULL);
541 assert(dc->
digest != NULL);
552 {
const char *
t = (*dc->
print) (dc, rc);
553 if (dc->
ofd && t && *t) {
554 size_t nb = strlen(t);
577 fprintf(stderr,
"\t%s(%p) fn %s\n", __FUNCTION__, dc, dc->
fn);
587 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
588 if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
592 dc->
dalgo = opt->val;
615 fprintf(stderr,
"\t%s(%p) fn %s\n", __FUNCTION__, dc, dc->
fn);
624 }
while (dc->
nb > 0);
634 fprintf(stderr,
"\t%s(%p) fn %s\n", __FUNCTION__, dc, dc->
fn);
636 if (!S_ISREG(dc->
sb.st_mode)) {
643 fprintf(stderr,
_(
"open of %s failed: %s\n"), dc->
fn,
Fstrerror(dc->
fd));
660 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
661 if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
663 if (opt->longName == NULL)
665 if (!(opt->val > 0 && opt->val < 256))
667 dc->
dalgo = opt->val;
688 fprintf(stderr,
"*** %s(%p) fn %s\n", __FUNCTION__, dc, dc->
fn);
704 return strcmp((*a)->fts_name, (*b)->fts_name);
711 if (S_ISDIR((*a)->fts_statp->st_mode)) {
712 if (!S_ISDIR((*b)->fts_statp->st_mode))
714 }
else if (S_ISDIR((*b)->fts_statp->st_mode))
716 return strcmp((*a)->fts_name, (*b)->fts_name);
722 char *
const *
paths = (
char *
const *) dc->
paths;
729 fprintf(stderr,
"Fts_open: %s", strerror(
errno));
753 (
void) printf(
"# %s\n", dc->
p->
fts_path);
754 (void) rpmdcVisitD(dc);
763 (void) printf(
"%*s# %s\n", indent,
"", dc->
p->
fts_path);
764 (void) printf(
"%*s..\n", indent,
"");
772 (void) fprintf(stderr,
"%s: %s: %s\n",
__progname,
794 #if !defined(POPT_ARG_ARGV) 795 static int _poptSaveString(
const char ***argvp,
unsigned int argInfo,
const char * val)
803 while ((*argvp)[argc] != NULL)
805 *argvp =
xrealloc(*argvp, (argc + 1 + 1) *
sizeof(**argvp));
806 if ((argv = *argvp) != NULL) {
816 enum poptCallbackReason reason,
817 const struct poptOption * opt,
const char * arg,
823 if (opt->arg == NULL)
832 fprintf(stderr,
_(
"%s: Unknown option -%c\n"),
__progname, opt->val);
833 poptPrintUsage(con, stderr, 0);
843 #if !defined(POPT_ARG_ARGV) 845 { NULL,
'\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
851 N_(
"Print 0install manifest"), NULL },
854 N_(
"Read in binary mode"), NULL },
856 #if !defined(POPT_ARG_ARGV) 857 {
"check",
'c', POPT_ARG_STRING, NULL,
'c',
858 N_(
"Read digests from MANIFEST file and verify (may be used more than once)"),
861 {
"check",
'c', POPT_ARG_ARGV, &_dc.
manifests, 0,
862 N_(
"Read digests from MANIFEST file and verify (may be used more than once)"),
866 N_(
"Print file tree specification to stdout"), NULL },
868 N_(
"Directories only"), NULL },
871 N_(
"read in text mode (default)"), NULL },
874 N_(
"generate HMAC's instead"), NULL },
877 { NULL, -1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
879 The following two options are useful only when verifying digests:\ 884 N_(
"no output when verifying"), NULL },
886 N_(
"warn about improperly formatted checksum lines"), NULL },
889 N_(
"Available digests:"), NULL },
892 N_(
"Common options for all rpmio executables:"), NULL },
897 { NULL, -1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
899 When checking, the input should be a former output of this program. The\n\ 900 default mode is to print a line with digest, a character indicating type\n\ 901 (`*' for binary, ` ' for text), and name for each FILE.\n"), NULL },
951 av = poptGetArgs(optCon);
956 poptPrintUsage(optCon, stderr, 0);
966 for (i = 0; i < ac; i++)
976 while ((dc->
fn = *av++) != NULL) {
989 fprintf(stderr,
"%s: WARNING: %u of %u computed checksums did NOT match\n",
995 static int asAscii = 1;
998 assert(dc->
digest != NULL);
1000 (void)
Fwrite(t, strlen(t),
sizeof(*t), dc->
ofd);
poptContext rpmioInit(int argc, char *const argv[], struct poptOption *optionsTable)
struct poptOption rpmioDigestPoptTable[]
Digest options using popt.
rpmtime_t rpmswExit(rpmop op, ssize_t rc)
Exit timed operation.
static int rpmdcInitFile(rpmdc dc)
FTS * Fts_open(char *const *argv, int options, int(*compar)(const FTSENT **, const FTSENT **))
Create a handle for file hierarchy traversal.
static struct poptOption _optionsTable[]
dcFlags_e
Bit field enum for rpmdigest CLI options.
ARGI_t argiFree(ARGI_t argi)
Destroy an argi array.
static const char * rpmdcPrintCoreutils(rpmdc dc, int rc)
static int rpmdcSortLexical(const FTSENT **a, const FTSENT **b)
int main(int argc, char *argv[])
size_t Fwrite(const void *buf, size_t size, size_t nmemb, FD_t fd)
fwrite(3) clone.
char * xstrdup(const char *str)
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
Initialize digest.
static const char hmackey[]
rpmtime_t rpmswAdd(rpmop to, rpmop from)
Sum statistic counters.
int Fflush(FD_t fd)
fflush(3) clone.
static const char * rpmdcAlgo2Name(uint32_t dalgo)
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
static void fdInitHmac(FD_t fd, const void *key, size_t keylen)
Attach digest to fd.
pgpHashAlgo rpmioDigestHashAlgo
static void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int _flags)
Attach digest to fd.
void rpmswPrint(const char *name, rpmop op, FILE *fp)
Print operation statistics.
static rpmop fdstat_op(FD_t fd, fdOpX opx)
static int rpmdcSortDirsLast(const FTSENT **a, const FTSENT **b)
int rpmiobSlurp(const char *fn, rpmiob *iobp)
int rpmHmacInit(DIGEST_CTX ctx, const void *key, size_t keylen)
Compute key material and add to digest context.
const char * Fstrerror(FD_t fd)
strerror(3) clone.
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
static void rpmdcArgCallback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, void *data)
static int rpmdcFiniFile(rpmdc dc)
int argvCount(const ARGV_t argv)
Return no.
static int rpmdcParseCoreutils(rpmdc dc)
int Lstat(const char *path, struct stat *st)
lstat(2) clone.
static int xisspace(int c)
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
static int rpmdcVisitF(rpmdc dc)
static struct rpmdc_s _dc
static int rpmdcPrintFile(rpmdc dc)
static int rpmdcCWalk(rpmdc dc)
static int _poptSaveString(const char ***argvp, unsigned int argInfo, const char *val)
The FD_t File Handle data structure.
static void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, void *datap, size_t *lenp, int asAscii)
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
static int rpmdcCalcFile(rpmdc dc)
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 const char * rpmdcPrintZeroInstall(rpmdc dc, int rc)
int Fclose(FD_t fd)
fclose(3) clone.
Cumulative statistics for an operation.
int Fts_set(FTS *sp, FTSENT *p, int instr)
Modify the traversal for a file set member.
static int rpmdcParseZeroInstall(rpmdc dc)
const char *(* print)(rpmdc dc, int rc)
int Ferror(FD_t fd)
ferror(3) clone.
#define F_ISSET(_dc, _FLAG)
static uint32_t rpmdcName2Algo(const char *dname)
static int xisdigit(int c)
static int snprintf(char *buf, int nb, const char *fmt,...)
static int rpmdcLoadManifests(rpmdc dc)
static struct poptOption * optionsTable
char * stpcpy(char *dest, const char *src)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
int argiAdd(ARGI_t *argip, int ix, int val)
Add an int to an argi array.
int Fts_close(FTS *sp)
Destroy a file hierarchy traversal handle.
int rpmDigestFinal(DIGEST_CTX ctx, void *datap, size_t *lenp, int asAscii)
Return digest and destroy context.
unsigned char buf[BUFSIZ]
struct poptOption rpmioAllPoptTable[]
poptContext rpmioFini(poptContext optCon)