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;
126 const char * dalgoName = NULL;
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) ?
'*' :
' ');
311 if (!(xx == 0 && iob != NULL)) {
312 fprintf(stderr,
_(
"%s: Failed to open %s\n"),
__progname, dc->
fn);
317 be = (
char *)(iob->b + iob->blen);
318 while (be > (
char *)iob->b && (be[-1] ==
'\n' || be[-1] ==
'\r')) {
324 be = strrchr((
char *)iob->b,
'=');
327 _(
"%s: %s: Manifest needs \"algo=digest\" as last line\n"),
334 while (be > (
char *)iob->b && !(be[-1] ==
'\n' || be[-1] ==
'\r'))
336 if (be <= (
char *)iob->b) {
337 fprintf(stderr,
_(
"%s: %s: Manifest is empty\n"),
345 fprintf(stderr,
_(
"%s: %s: Unknown digest algo name \"%s\"\n"),
361 if (strcmp(dc->
digest, digest)) {
363 _(
"%s: %s: Manifest digest check: Expected(%s) != (%s)\n"),
368 digest =
_free(digest);
373 for (f = (
char *)iob->b; *f; f = fe) {
374 static const char hexdigits[] =
"0123456789ABCDEFabcdef";
375 const char * _dn = NULL;
380 while (*fe && !(*fe ==
'\n' || *fe ==
'\r'))
382 while (*fe && (*fe ==
'\n' || *fe ==
'\r'))
394 while (*f && strchr(hexdigits, *f) != NULL)
397 fprintf(stderr,
_(
"%s: %s line %u: Malformed digest field.\n"),
406 fprintf(stderr,
_(
"%s: %s line %u: Malformed mtime field.\n"),
415 fprintf(stderr,
_(
"%s: %s line %u: Malformed size field.\n"),
422 fprintf(stderr,
_(
"%s: %s line %u: No file path.\n"),
428 if (_dn && *_dn ==
'/')
459 const struct stat * st = &dc->
sb;
463 if (rc == 0 &&
F_ISSET(dc, STATUS))
466 snprintf(_mtime,
sizeof(_mtime),
"%llu",
467 (
unsigned long long) st->st_mtime);
468 _mtime[
sizeof(_mtime)-1] =
'\0';
469 snprintf(_size,
sizeof(_size),
"%llu",
470 (
unsigned long long) st->st_size);
471 _size[
sizeof(_size)-1] =
'\0';
473 if ((_bn = strrchr(dc->
fn,
'/')) != NULL)
482 nb += 1 + strlen(_mtime);
483 nb += 1 + strlen(_size);
484 nb += 1 + strlen(_bn);
492 const char *msg = (rc ?
"FAILED" :
"OK");
493 if (rc || !
F_ISSET(dc, STATUS)) {
499 if (S_ISDIR(st->st_mode)) {
509 }
else if (S_ISREG(st->st_mode) ||
S_ISLNK(st->st_mode)) {
513 *te++ = (st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) ?
'X' :
'F';
535 static int asAscii = 1;
539 fprintf(stderr,
"\t%s(%p) fd %p fn %s\n", __FUNCTION__, dc, dc->
fd, dc->
fn);
541 assert(dc->
fd != NULL);
543 assert(dc->
digest != NULL);
554 {
const char * t = (*dc->
print) (dc, rc);
555 if (dc->
ofd && t && *t) {
556 size_t nb = strlen(t);
579 fprintf(stderr,
"\t%s(%p) fn %s\n", __FUNCTION__, dc, dc->
fn);
589 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
590 if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
594 dc->
dalgo = opt->val;
617 fprintf(stderr,
"\t%s(%p) fn %s\n", __FUNCTION__, dc, dc->
fn);
626 }
while (dc->
nb > 0);
636 fprintf(stderr,
"\t%s(%p) fn %s\n", __FUNCTION__, dc, dc->
fn);
638 if (!S_ISREG(dc->
sb.st_mode)) {
645 fprintf(stderr,
_(
"open of %s failed: %s\n"), dc->
fn,
Fstrerror(dc->
fd));
662 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
663 if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)
665 if (opt->longName == NULL)
667 if (!(opt->val > 0 && opt->val < 256))
669 dc->
dalgo = opt->val;
690 fprintf(stderr,
"*** %s(%p) fn %s\n", __FUNCTION__, dc, dc->
fn);
706 return strcmp((*a)->fts_name, (*b)->fts_name);
713 if (S_ISDIR((*a)->fts_statp->st_mode)) {
714 if (!S_ISDIR((*b)->fts_statp->st_mode))
716 }
else if (S_ISDIR((*b)->fts_statp->st_mode))
718 return strcmp((*a)->fts_name, (*b)->fts_name);
724 char *
const * paths = (
char *
const *) dc->
paths;
731 fprintf(stderr,
"Fts_open: %s", strerror(
errno));
755 (
void) printf(
"# %s\n", dc->
p->
fts_path);
756 (void) rpmdcVisitD(dc);
765 (void) printf(
"%*s# %s\n", indent,
"", dc->
p->
fts_path);
766 (void) printf(
"%*s..\n", indent,
"");
774 (void) fprintf(stderr,
"%s: %s: %s\n",
__progname,
796 #if !defined(POPT_ARG_ARGV)
797 static int _poptSaveString(
const char ***argvp,
unsigned int argInfo,
const char * val)
805 while ((*argvp)[argc] != NULL)
807 *argvp =
xrealloc(*argvp, (argc + 1 + 1) *
sizeof(**argvp));
808 if ((argv = *argvp) != NULL) {
818 enum poptCallbackReason reason,
819 const struct poptOption * opt,
const char *
arg,
825 if (opt->arg == NULL)
834 fprintf(stderr,
_(
"%s: Unknown option -%c\n"),
__progname, opt->val);
835 poptPrintUsage(con, stderr, 0);
845 #if !defined(POPT_ARG_ARGV)
847 { NULL,
'\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
853 N_(
"Print 0install manifest"), NULL },
856 N_(
"Read in binary mode"), NULL },
858 #if !defined(POPT_ARG_ARGV)
859 {
"check",
'c', POPT_ARG_STRING, NULL,
'c',
860 N_(
"Read digests from MANIFEST file and verify (may be used more than once)"),
863 {
"check",
'c', POPT_ARG_ARGV, &_dc.
manifests, 0,
864 N_(
"Read digests from MANIFEST file and verify (may be used more than once)"),
868 N_(
"Print file tree specification to stdout"), NULL },
870 N_(
"Directories only"), NULL },
873 N_(
"read in text mode (default)"), NULL },
876 N_(
"generate HMAC's instead"), NULL },
879 { NULL, -1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
881 The following two options are useful only when verifying digests:\
886 N_(
"no output when verifying"), NULL },
888 N_(
"warn about improperly formatted checksum lines"), NULL },
891 N_(
"Available digests:"), NULL },
894 N_(
"Common options for all rpmio executables:"), NULL },
899 { NULL, -1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
901 When checking, the input should be a former output of this program. The\n\
902 default mode is to print a line with digest, a character indicating type\n\
903 (`*' for binary, ` ' for text), and name for each FILE.\n"), NULL },
953 av = poptGetArgs(optCon);
958 poptPrintUsage(optCon, stderr, 0);
968 for (i = 0; i < ac; i++)
978 while ((dc->
fn = *av++) != NULL) {
991 fprintf(stderr,
"%s: WARNING: %u of %u computed checksums did NOT match\n",
997 static int asAscii = 1;
1000 assert(dc->
digest != NULL);
1002 (void)
Fwrite(t, strlen(t),
sizeof(*t), dc->
ofd);
poptContext rpmioInit(int argc, char *const argv[], struct poptOption *optionsTable)
Initialize most everything needed by an rpmio executable context.
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 context.
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
const char *(* print)(rpmdc dc, int rc)
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.
const char const bson * data
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.
const char const char int arg
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)
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[]
Popt option table for options shared by all modes and executables.
poptContext rpmioFini(poptContext optCon)
Destroy most everything needed by an rpm CLI executable context.