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;
164 fprintf(stderr,
_(
"%s: Failed to open %s: %s\n"),
174 while (fgets(buf,
sizeof(buf), fp) !=
NULL) {
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;
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"),
247 const char *
msg = (rc ?
"FAILED" :
"OK");
252 if (rc == 0 &&
F_ISSET(dc, STATUS))
257 nb += strlen(dc->
dalgoName) +
sizeof(
":") - 1;
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)) {
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"),
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);
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)) {
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;
683 rpmdcVisitF(rpmdc dc)
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;
755 (
void) printf(
"# %s\n", dc->
p->
fts_path);
756 (
void) rpmdcVisitD(dc);
766 (
void) printf(
"%*s..\n", indent,
"");
796 #if !defined(POPT_ARG_ARGV)
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)
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) {
980 || (xx = rpmdcVisitF(dc)) != 0)
991 fprintf(stderr,
"%s: WARNING: %u of %u computed checksums did NOT match\n",
997 static int asAscii = 1;
static void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int _flags)
Attach digest to fd.
poptContext rpmioInit(int argc, char *const argv[], struct poptOption *optionsTable)
struct poptOption rpmioDigestPoptTable[]
Digest options using popt.
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.
rpmtime_t rpmswAdd(rpmop to, rpmop from)
Sum statistic counters.
ARGI_t argiFree(ARGI_t argi)
Destroy an argi array.
static const char * rpmdcPrintCoreutils(rpmdc dc, int rc)
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.
static char *size_t nb
fgets(3) analogue that reads \ continuations.
static const char hmackey[]
int main(int argc, const char **argv, char **envp)
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.
pgpHashAlgo rpmioDigestHashAlgo
const char *(* print)(rpmdc dc, int rc)
int rpmiobSlurp(const char *fn, rpmiob *iobp)
const char * Fstrerror(FD_t fd)
strerror(3) clone.
assert(key->size==sizeof(hdrNum))
static void rpmdcArgCallback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, void *data)
fprintf(stderr,"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, rsactx, sig, sigp)
void rpmswPrint(const char *name, rpmop op, FILE *fp)
Print operation statistics.
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)
int rpmDigestUpdate(DIGEST_CTX ctx, const void *data, size_t len)
Update context with next plain text buffer.
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
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)
static void fdInitHmac(FD_t fd, const void *key, size_t keylen)
Attach digest to fd.
The FD_t File Handle data structure.
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
DIGEST_CTX rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
Initialize digest.
static int rpmdcCalcFile(rpmdc dc)
FTSENT * Fts_read(FTS *sp)
Return next node in the file hierarchy traversal.
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)
static const char *char c
Return text between pl and matching pr characters.
int Ferror(FD_t fd)
ferror(3) clone.
#define F_ISSET(_dc, _FLAG)
static uint32_t rpmdcName2Algo(const char *dname)
return strcmp(ame->name, bme->name)
static int xisdigit(int c)
int rpmHmacInit(DIGEST_CTX ctx, const void *key, size_t keylen)
Compute key material and add to digest context.
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)
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.
static void
Print copy of spec file, filling in Group/Description/Summary from specspo.
unsigned char buf[BUFSIZ]
static void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, void *datap, size_t *lenp, int asAscii)
char * buf
Parse (and execute) macro undefinition.
static rpmop fdstat_op(FD_t fd, fdOpX opx)
int
Save source and expand field into target.
void rpmDigestFinal(rpmDigestDup(md5ctx),&md5sum,&md5len, 0)
struct poptOption rpmioAllPoptTable[]
poptContext rpmioFini(poptContext optCon)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
const unsigned char * digest