RPM Community Forums

Mailing List Message of <rpm-devel>

Re: [CVS] RPM: rpm/rpmio/ rpmmtree.c

From: Jeff Johnson <n3npq@mac.com>
Date: Sun 16 Mar 2008 - 21:35:16 CET
Message-Id: <192DBBEB-BB9F-432F-A731-5D9FAD87AA34@mac.com>
With this check-in, rpmmtree(8) functionality has largely congealed.

Here's a very iterse ntroduction to what rpmmtree(8) can do that *BSD  
mtree(8) cannot

My test script reads a WebDAV enabled URI file, computes several  
values, then verifies:

  	keys="adler32,crc32,sha512digest"
	uri="http://rpm5.org/files/popt/popt-1.13.tar.gz"
	rpmmtree="rpmmtree -p $uri -k $keys"
	$rpmmtree -c | tee /dev/tty | $rpmmtree
	echo "status: $?"

Here is output:

#          user: jbj
#       machine: wellfleet.jbj.org
#          tree: http://rpm5.org/files/popt/popt-1.13.tar.gz
#          date: Sun Mar 16 16:28:24 2008
     popt-1.13.tar.gz \
                 adler32=dd9ae016 crc32=0d57179e \
                  
sha512digest=0c8c321722792b35cc1b503163dcd655420469e564c0024c15d61d39687 
682b297ac05a0cdd4f2ac681f7c888638094e11976891724c41c7a0550a935916bced
status: 0

On a good day, rpmmtree(8) will traverse a single remote URI hierarchy,
just not the entire hierarchy yet. I've (still) not quite gotten to  
the HTML grubbing ...

Enjoy!

73 de Jeff

On Mar 16, 2008, at 4:19 PM, Jeff Johnson wrote:

>   RPM Package Manager, CVS Repository
>   http://rpm5.org/cvs/
>    
> ______________________________________________________________________ 
> ______
>
>   Server: rpm5.org                         Name:   Jeff Johnson
>   Root:   /v/rpm/cvs                       Email:  jbj@rpm5.org
>   Module: rpm                              Date:   16-Mar-2008  
> 21:19:24
>   Branch: HEAD                             Handle: 2008031620192400
>
>   Modified files:
>     rpm/rpmio               rpmmtree.c
>
>   Log:
>     - jbj: rpmmtree: enable all rpmio digests.
>
>   Summary:
>     Revision    Changes     Path
>     1.25        +100 -89    rpm/rpmio/rpmmtree.c
>    
> ______________________________________________________________________ 
> ______
>
>   patch -p0 <<'@@ .'
>   Index: rpm/rpmio/rpmmtree.c
>    
> ====================================================================== 
> ======
>   $ cvs diff -u -r1.24 -r1.25 rpmmtree.c
>   --- rpm/rpmio/rpmmtree.c	16 Mar 2008 18:07:27 -0000	1.24
>   +++ rpm/rpmio/rpmmtree.c	16 Mar 2008 20:19:24 -0000	1.25
>   @@ -107,12 +107,8 @@
>        MTREE_KEYS_FLAGS		= _KFB(15),	/*!< file flags */
>        MTREE_KEYS_NOCHANGE		= _KFB(16),	/*!< do not change owner/ 
> mode */
>        MTREE_KEYS_OPT		= _KFB(17),	/*!< existence optional */
>   -	/* 18-23 unused */
>   -    MTREE_KEYS_MD5		= _KFB(24),	/*!< MD5 digest */
>   -    MTREE_KEYS_RMD160		= _KFB(25),	/*!< RIPEMD-160 digest */
>   -    MTREE_KEYS_SHA1		= _KFB(26),	/*!< SHA-1 digest */
>   -    MTREE_KEYS_SHA256		= _KFB(27),	/*!< SHA-256 digest */
>   -	/* 28-31 unused */
>   +    MTREE_KEYS_DIGEST		= _KFB(18),	/*!< digest */
>   +	/* 19-31 unused */
>    };
>
>    typedef struct _node {
>   @@ -154,6 +150,9 @@
>        ARGV_t paths;
>        unsigned keys;
>    /*@null@*/
>   +    ARGI_t algos;
>   +
>   +/*@null@*/
>        const char * fullpath;
>    /*@null@*/
>        char * path;
>   @@ -288,32 +287,48 @@
>    /*@observer@*/
>    	const char *name;		/* key name */
>    	unsigned val;			/* value */
>   -#define	NEEDVALUE	0x01
>   -	unsigned flags;
>   +#define	NEEDVALUE	0xffffffff
>   +	uint32_t flags;
>    } KEY;
>
>    /* NB: the following table must be sorted lexically. */
>    /*@unchecked@*/ /*@observer@*/
>    static KEY keylist[] = {
>   -	{"cksum",	MTREE_KEYS_CKSUM,	NEEDVALUE},
>   -	{"flags",	MTREE_KEYS_FLAGS,	NEEDVALUE},
>   -	{"gid",		MTREE_KEYS_GID,		NEEDVALUE},
>   -	{"gname",	MTREE_KEYS_GNAME,	NEEDVALUE},
>   -	{"ignore",	MTREE_KEYS_IGN,		0},
>   -	{"link",	MTREE_KEYS_SLINK,	NEEDVALUE},
>   -	{"md5digest",	MTREE_KEYS_MD5,		NEEDVALUE},
>   -	{"mode",	MTREE_KEYS_MODE,	NEEDVALUE},
>   -	{"nlink",	MTREE_KEYS_NLINK,	NEEDVALUE},
>   -	{"nochange",	MTREE_KEYS_NOCHANGE,	0},
>   -	{"optional",	MTREE_KEYS_OPT,		0},
>   -	{"rmd160digest",MTREE_KEYS_RMD160,	NEEDVALUE},
>   -	{"sha1digest",	MTREE_KEYS_SHA1,	NEEDVALUE},
>   -	{"sha256digest",MTREE_KEYS_SHA256,	NEEDVALUE},
>   -	{"size",	MTREE_KEYS_SIZE,	NEEDVALUE},
>   -	{"time",	MTREE_KEYS_TIME,	NEEDVALUE},
>   -	{"type",	MTREE_KEYS_TYPE,	NEEDVALUE},
>   -	{"uid",		MTREE_KEYS_UID,		NEEDVALUE},
>   -	{"uname",	MTREE_KEYS_UNAME,	NEEDVALUE},
>   +    { "adler32",	MTREE_KEYS_DIGEST,	PGPHASHALGO_ADLER32 },
>   +    { "cksum",		MTREE_KEYS_CKSUM,	NEEDVALUE },
>   +    { "crc32",		MTREE_KEYS_DIGEST,	PGPHASHALGO_CRC32 },
>   +    { "crc64",		MTREE_KEYS_DIGEST,	PGPHASHALGO_CRC64 },
>   +    { "flags",		MTREE_KEYS_FLAGS,	NEEDVALUE },
>   +    { "gid",		MTREE_KEYS_GID,		NEEDVALUE },
>   +    { "gname",		MTREE_KEYS_GNAME,	NEEDVALUE },
>   +    { "haval160digest",	MTREE_KEYS_DIGEST,	 
> PGPHASHALGO_HAVAL_5_160 },
>   +    { "ignore",		MTREE_KEYS_IGN,		0 },
>   +    { "jlu32",		MTREE_KEYS_DIGEST,	PGPHASHALGO_JLU32 },
>   +    { "link",		MTREE_KEYS_SLINK,	NEEDVALUE },
>   +    { "md2digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_MD2 },
>   +    { "md4digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_MD4 },
>   +    { "md5digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_MD5 },
>   +    { "mode",		MTREE_KEYS_MODE,	NEEDVALUE },
>   +    { "nlink",		MTREE_KEYS_NLINK,	NEEDVALUE },
>   +    { "nochange",	MTREE_KEYS_NOCHANGE,	0 },
>   +    { "optional",	MTREE_KEYS_OPT,		0 },
>   +    { "rmd128digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_RIPEMD128 },
>   +    { "rmd160digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_RIPEMD160 },
>   +    { "rmd256digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_RIPEMD256 },
>   +    { "rmd320digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_RIPEMD320 },
>   +    { "salsa10",	MTREE_KEYS_DIGEST,	PGPHASHALGO_SALSA10 },
>   +    { "salsa20",	MTREE_KEYS_DIGEST,	PGPHASHALGO_SALSA20 },
>   +    { "sha1digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_SHA1 },
>   +    { "sha224digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_SHA224 },
>   +    { "sha256digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_SHA256 },
>   +    { "sha384digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_SHA384 },
>   +    { "sha512digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_SHA512 },
>   +    { "tiger192digest",	MTREE_KEYS_DIGEST,	PGPHASHALGO_TIGER192 },
>   +    { "size",		MTREE_KEYS_SIZE,	NEEDVALUE },
>   +    { "time",		MTREE_KEYS_TIME,	NEEDVALUE },
>   +    { "type",		MTREE_KEYS_TYPE,	NEEDVALUE },
>   +    { "uid",		MTREE_KEYS_UID,		NEEDVALUE },
>   +    { "uname",		MTREE_KEYS_UNAME,	NEEDVALUE },
>    };
>
>    static int
>   @@ -324,7 +339,7 @@
>    }
>
>    static unsigned
>   -parsekey(char *name, /*@out@*/ int *needvaluep)
>   +parsekey(char *name, /*@out@*/ uint32_t *needvaluep)
>    	/*@globals fileSystem @*/
>    	/*@modifies *needvaluep, fileSystem @*/
>
>   @@ -342,7 +357,7 @@
>    	mtree_error("unknown keyword %s", name);
>
>        if (needvaluep != NULL)
>   -	*needvaluep = k->flags & NEEDVALUE ? 1 : 0;
>   +	*needvaluep = k->flags;
>        return k->val;
>    }
>
>   @@ -1328,7 +1343,7 @@
>        char *kw;
>
>        for (; (kw = strtok(t, "= \t\n")) != NULL; t = NULL) {
>   -	int needvalue;
>   +	uint32_t needvalue;
>    	enum mtreeKeys_e type = parsekey(kw, &needvalue);
>    	char *val = NULL;
>    	char *ep;
>   @@ -1342,10 +1357,6 @@
>    	    if (*ep != '\0')
>    		mtree_error("invalid checksum %s", val);
>    	    /*@switchbreak@*/ break;
>   -	case MTREE_KEYS_MD5:
>   -	    (void) argiAdd(&ip->algos, -1, PGPHASHALGO_MD5);
>   -	    (void) argvAdd(&ip->digests, val);
>   -	    /*@switchbreak@*/ break;
>    	case MTREE_KEYS_FLAGS:
>    #if defined(__linux__)
>    #else
>   @@ -1386,16 +1397,8 @@
>    	    if (*ep != '\0')
>    		mtree_error("invalid link count %s", val);
>    	    /*@switchbreak@*/ break;
>   -	case MTREE_KEYS_RMD160:
>   -	    (void) argiAdd(&ip->algos, -1, PGPHASHALGO_RIPEMD160);
>   -	    (void) argvAdd(&ip->digests, val);
>   -	    /*@switchbreak@*/ break;
>   -	case MTREE_KEYS_SHA1:
>   -	    (void) argiAdd(&ip->algos, -1, PGPHASHALGO_SHA1);
>   -	    (void) argvAdd(&ip->digests, val);
>   -	    /*@switchbreak@*/ break;
>   -	case MTREE_KEYS_SHA256:
>   -	    (void) argiAdd(&ip->algos, -1, PGPHASHALGO_SHA256);
>   +	case MTREE_KEYS_DIGEST:
>   +	    (void) argiAdd(&ip->algos, -1, needvalue);
>    	    (void) argvAdd(&ip->digests, val);
>    	    /*@switchbreak@*/ break;
>    	case MTREE_KEYS_SIZE:
>   @@ -2251,20 +2254,9 @@
>
>        /* Only files can have digests. */
>        if (S_ISREG(st->st_mode)) {
>   -	ARGI_t algos = NULL;
>   -
>   -	/* Mark all digests that need calculating. */
>   -	if (KF_ISSET(keys, MD5))
>   -	    (void) argiAdd(&algos, -1, PGPHASHALGO_MD5);
>   -	if (KF_ISSET(keys, RMD160))
>   -	    (void) argiAdd(&algos, -1, PGPHASHALGO_RIPEMD160);
>   -	if (KF_ISSET(keys, SHA1))
>   -	    (void) argiAdd(&algos, -1, PGPHASHALGO_SHA1);
>   -	if (KF_ISSET(keys, SHA256))
>   -	    (void) argiAdd(&algos, -1, PGPHASHALGO_SHA256);
>
>    	/* Any digests to calculate? */
>   -	if (KF_ISSET(keys, CKSUM) || algos != NULL) {
>   +	if (KF_ISSET(keys, CKSUM) || fts->algos != NULL) {
>    	    FD_t fd = Fopen(fts_accpath, "r.ufdio");
>    	    uint32_t len, val;
>    	    int i;
>   @@ -2280,9 +2272,9 @@
>    	    }
>
>    	    /* Setup all digest calculations.  Reversed order is  
> effete ... */
>   -	    if (algos != NULL)
>   -	    for (i = algos->nvals; i-- > 0;)
>   -		fdInitDigest(fd, algos->vals[i], 0);
>   +	    if (fts->algos != NULL)
>   +	    for (i = fts->algos->nvals; i-- > 0;)
>   +		fdInitDigest(fd, fts->algos->vals[i], 0);
>
>    	    /* Compute the cksum and digests. */
>    	    if (KF_ISSET(keys, CKSUM))
>   @@ -2309,14 +2301,15 @@
>    	    }
>
>    	    /* Output all the digests. */
>   -	    if (algos != NULL)
>   -	    for (i = 0; i < (int) algos->nvals; i++) {
>   +	    if (fts->algos != NULL)
>   +	    for (i = 0; i < (int) fts->algos->nvals; i++) {
>    		static int asAscii = 1;
>   -		uint32_t algo = algos->vals[i];
>    		const char * digest = NULL;
>    		size_t digestlen = 0;
>   +		uint32_t algo;
>    		const char * tagname;
>
>   +		algo = fts->algos->vals[i];
>    		fdFiniDigest(fd, algo, &digest, &digestlen, asAscii);
>    #ifdef	NOTYET	/* XXX can't exit in a library API. */
>    assert(digest != NULL);
>   @@ -2327,50 +2320,57 @@
>    		tagname = NULL;
>    		switch (algo) {
>    		case PGPHASHALGO_MD5:
>   -		    tagname = "md5";	/*@switchbreak@*/ break;
>   +		    tagname = "md5digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_SHA1:
>   -		    tagname = "sha1";	/*@switchbreak@*/ break;
>   +		    tagname = "sha1digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_RIPEMD160:
>   -		    tagname = "rmd160";	/*@switchbreak@*/ break;
>   +		    tagname = "rmd160digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_MD2:
>   -		    tagname = "md2";	/*@switchbreak@*/ break;
>   +		    tagname = "md2digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_TIGER192:
>   -		    tagname = "tiger192";	/*@switchbreak@*/ break;
>   +		    tagname = "tiger192digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_HAVAL_5_160:
>   -		    tagname = "haval";	/*@switchbreak@*/ break;
>   +		    tagname = "haval160digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_SHA256:
>   -		    tagname = "sha256";	/*@switchbreak@*/ break;
>   +		    tagname = "sha256digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_SHA384:
>   -		    tagname = "sha384";	/*@switchbreak@*/ break;
>   +		    tagname = "sha384digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_SHA512:
>   -		    tagname = "sha512";	/*@switchbreak@*/ break;
>   +		    tagname = "sha512digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_MD4:
>   -		    tagname = "md4";	/*@switchbreak@*/ break;
>   +		    tagname = "md4digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_RIPEMD128:
>   -		    tagname = "rmd128";	/*@switchbreak@*/ break;
>   +		    tagname = "rmd128digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_CRC32:
>   +		    tagname = "crc32";		/*@switchbreak@*/ break;
>    		    /*@switchbreak@*/ break;
>    		case PGPHASHALGO_ADLER32:
>   +		    tagname = "adler32";	/*@switchbreak@*/ break;
>    		    /*@switchbreak@*/ break;
>    		case PGPHASHALGO_CRC64:
>   +		    tagname = "crc64";		/*@switchbreak@*/ break;
>    		    /*@switchbreak@*/ break;
>    		case PGPHASHALGO_JLU32:
>   +		    tagname = "jlu32";		/*@switchbreak@*/ break;
>    		    /*@switchbreak@*/ break;
>    		case PGPHASHALGO_SHA224:
>   -		    tagname = "sha224";	/*@switchbreak@*/ break;
>   +		    tagname = "sha224digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_RIPEMD256:
>   -		    tagname = "rmd256";	/*@switchbreak@*/ break;
>   +		    tagname = "rmd256digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_RIPEMD320:
>   -		    tagname = "rmd320";	/*@switchbreak@*/ break;
>   +		    tagname = "rmd320digest";	/*@switchbreak@*/ break;
>    		case PGPHASHALGO_SALSA10:
>   +		    tagname = "salsa10";	/*@switchbreak@*/ break;
>    		    /*@switchbreak@*/ break;
>    		case PGPHASHALGO_SALSA20:
>   +		    tagname = "salsa20";	/*@switchbreak@*/ break;
>    		    /*@switchbreak@*/ break;
>    		default:
>   +		    tagname = 0;
>    		    /*@switchbreak@*/ break;
>    		}
>    		if (tagname != NULL)
>   -		    output(indent, &offset, "%sdigest=%s", tagname, digest);
>   +		    output(indent, &offset, "%s=%s", tagname, digest);
>    		digest = _free(digest);
>    		digestlen = 0;
>    	    }
>   @@ -2716,8 +2716,18 @@
>    	/*@fallthrough@*/
>        case 'K':
>    /*@-unrecog@*/
>   -	while ((p = strsep((char **)&arg, " \t,")) != NULL)
>   -	    _rpmfts->keys |= parsekey(p, NULL);
>   +	while ((p = strsep((char **)&arg, " \t,")) != NULL) {
>   +	    uint32_t needvalue;
>   +	    enum mtreeKeys_e type = parsekey(p, &needvalue);
>   +	    if (type == 0) {
>   +		/* XXX unknown key error. */
>   +		continue;
>   +	    }
>   +	    _rpmfts->keys |= type;
>   +	    /* XXX dupes can occur */
>   +	    if (KF_ISSET(_rpmfts->keys, DIGEST) && needvalue)
>   +		(void) argiAdd(&_rpmfts->algos, -1, needvalue);
>   +	}
>    /*@=unrecog@*/
>    	break;
>    #if !defined(POPT_ARG_ARGV)
>   @@ -2874,7 +2884,7 @@
>    {
>        rpmfts fts = _rpmfts;
>        poptContext optCon;
>   -    int rc;
>   +    int rc = 1;		/* assume failure */
>
>        LIST_INIT(&excludes);
>        fts->keys = KEYDEFAULT;
>   @@ -2887,14 +2897,7 @@
>        argv = (char **) poptGetArgs(optCon);
>        if (!(argv == NULL || argv[0] == NULL)) {
>    	poptPrintUsage(optCon, stderr, 0);
>   -	exit(EXIT_FAILURE);
>   -    }
>   -
>   -    if (MF_ISSET(CREATE) || MF_ISSET(SEEDED)) {
>   -	char fullpath[MAXPATHLEN];
>   -	if (!getcwd(fullpath, sizeof fullpath))
>   -	    mtree_error("getcwd: %s", strerror(errno));
>   -	fts->fullpath = xstrdup(fullpath);
>   +	goto exit;
>        }
>
>        if (MF_ISSET(LOOSE) && MF_ISSET(UPDATE))
>   @@ -2914,10 +2917,17 @@
>    	break;
>        }
>
>   -    if (fts->paths == NULL) {
>   +    if (fts->paths == NULL || fts->paths[0] == NULL) {
>   +	char fullpath[MAXPATHLEN];
>   +	if (!getcwd(fullpath, sizeof fullpath))
>   +	    mtree_error("getcwd: %s", strerror(errno));
>   +	fts->fullpath = xstrdup(fullpath);
>    	fts->paths = xmalloc(2 * sizeof(fts->paths[0]));
>    	fts->paths[0] = xstrdup(".");
>    	fts->paths[1] = NULL;
>   +    } else {
>   +	/* XXX incorrect for multi-root'd trees. */
>   +	fts->fullpath = xstrdup(fts->paths[0]);
>        }
>
>        /* XXX prohibits -s 0 invocation */
>   @@ -2967,6 +2977,7 @@
>            rpmswPrint("digest:", &dc_digestops);
>        }
>
>   +exit:
>        fts->paths = argvFree(fts->paths);
>        fts->fullpath = _free(fts->fullpath);
>        /* XXX TODO: clean excludes */
>   @@ .
> ______________________________________________________________________
> RPM Package Manager                                    http://rpm5.org
> CVS Sources Repository                                rpm-cvs@rpm5.org
Received on Sun Mar 16 21:35:35 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.