Index: head/usr.sbin/pkg_install/info/info.h =================================================================== --- head/usr.sbin/pkg_install/info/info.h (revision 71964) +++ head/usr.sbin/pkg_install/info/info.h (revision 71965) @@ -1,63 +1,64 @@ /* $FreeBSD$ */ /* * FreeBSD install - a package for the installation and maintainance * of non-core utilities. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Jordan K. Hubbard * 23 August 1993 * * Include and define various things wanted by the info command. * */ #ifndef _INST_INFO_H_INCLUDE #define _INST_INFO_H_INCLUDE #ifndef MAXINDEXSIZE #define MAXINDEXSIZE 59 #endif #ifndef MAXNAMESIZE #define MAXNAMESIZE 20 #endif #define SHOW_COMMENT 0x0001 #define SHOW_DESC 0x0002 #define SHOW_PLIST 0x0004 #define SHOW_INSTALL 0x0008 #define SHOW_DEINSTALL 0x0010 #define SHOW_REQUIRE 0x0020 #define SHOW_PREFIX 0x0040 #define SHOW_INDEX 0x0080 #define SHOW_FILES 0x0100 #define SHOW_DISPLAY 0x0200 #define SHOW_REQBY 0x0400 #define SHOW_MTREE 0x0800 #define SHOW_SIZE 0x1000 #define SHOW_ORIGIN 0x2000 +#define SHOW_CKSUM 0x4000 extern int Flags; extern Boolean AllInstalled; extern Boolean Quiet; extern char *InfoPrefix; extern char PlayPen[]; extern char *CheckPkg; extern void show_file(char *, char *); extern void show_plist(char *, Package *, plist_t); extern void show_files(char *, Package *); extern void show_index(char *, char *); extern void show_size(char *, Package *); extern void show_origin(char *, Package *); #endif /* _INST_INFO_H_INCLUDE */ Index: head/usr.sbin/pkg_install/info/main.c =================================================================== --- head/usr.sbin/pkg_install/info/main.c (revision 71964) +++ head/usr.sbin/pkg_install/info/main.c (revision 71965) @@ -1,186 +1,190 @@ /* * * FreeBSD install - a package for the installation and maintainance * of non-core utilities. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Jordan K. Hubbard * 18 July 1993 * * This is the info module. * */ #include #include "lib.h" #include "info.h" #ifndef lint static const char rcsid[] = "$FreeBSD$"; #endif -static char Options[] = "acdDe:fhiIkl:LmopqrRst:v"; +static char Options[] = "acdDe:fghiIkl:LmopqrRst:v"; int Flags = 0; Boolean AllInstalled = FALSE; Boolean Quiet = FALSE; char *InfoPrefix = ""; char PlayPen[FILENAME_MAX]; char *CheckPkg = NULL; static void usage __P((void)); int main(int argc, char **argv) { int ch; char **pkgs, **start; char *pkgs_split; pkgs = start = argv; if (argc == 1) { AllInstalled = TRUE; Flags = SHOW_INDEX; } else while ((ch = getopt(argc, argv, Options)) != -1) { switch(ch) { case 'a': AllInstalled = TRUE; break; case 'v': Verbose = TRUE; /* Reasonable definition of 'everything' */ Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL | SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE; break; case 'I': Flags |= SHOW_INDEX; break; case 'p': Flags |= SHOW_PREFIX; break; case 'c': Flags |= SHOW_COMMENT; break; case 'd': Flags |= SHOW_DESC; break; case 'D': Flags |= SHOW_DISPLAY; break; case 'f': Flags |= SHOW_PLIST; + break; + + case 'g': + Flags |= SHOW_CKSUM; break; case 'i': Flags |= SHOW_INSTALL; break; case 'k': Flags |= SHOW_DEINSTALL; break; case 'r': Flags |= SHOW_REQUIRE; break; case 'R': Flags |= SHOW_REQBY; break; case 'L': Flags |= SHOW_FILES; break; case 'm': Flags |= SHOW_MTREE; break; case 's': Flags |= SHOW_SIZE; break; case 'o': Flags |= SHOW_ORIGIN; break; case 'l': InfoPrefix = optarg; break; case 'q': Quiet = TRUE; break; case 't': strcpy(PlayPen, optarg); break; case 'e': CheckPkg = optarg; break; case 'h': case '?': default: usage(); break; } } argc -= optind; argv += optind; /* Set some reasonable defaults */ if (!Flags) Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY; /* Get all the remaining package names, if any */ while (*argv) { while ((pkgs_split = strrchr(*argv, (int)'/')) != NULL) { *pkgs_split++ = '\0'; /* * If character after the '/' is alphanumeric, then we've found the * package name. Otherwise we've come across a trailing '/' and * need to continue our quest. */ if (isalpha(*pkgs_split)) { *argv = pkgs_split; break; } } *pkgs++ = *argv++; } /* If no packages, yelp */ if (pkgs == start && !AllInstalled && !CheckPkg) warnx("missing package name(s)"), usage(); *pkgs = NULL; return pkg_perform(start); } static void usage() { fprintf(stderr, "%s\n%s\n%s\n", "usage: pkg_info [-cdDfiIkLmopqrRsv] [-e package] [-l prefix]", " [-t template] [pkg-name ...]", " pkg_info -a [flags]"); exit(1); } Index: head/usr.sbin/pkg_install/info/perform.c =================================================================== --- head/usr.sbin/pkg_install/info/perform.c (revision 71964) +++ head/usr.sbin/pkg_install/info/perform.c (revision 71965) @@ -1,238 +1,240 @@ #ifndef lint static const char rcsid[] = "$FreeBSD$"; #endif /* * FreeBSD install - a package for the installation and maintainance * of non-core utilities. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Jordan K. Hubbard * 23 Aug 1993 * * This is the main body of the info module. * */ #include "lib.h" #include "info.h" #include #include #include static int fname_cmp(const FTSENT **, const FTSENT **); static int pkg_do(char *); int pkg_perform(char **pkgs) { int i, err_cnt = 0; char *tmp; signal(SIGINT, cleanup); tmp = getenv(PKG_DBDIR); if (!tmp) tmp = DEF_LOG_DIR; /* Overriding action? */ if (CheckPkg) { char buf[FILENAME_MAX]; snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg); return abs(access(buf, R_OK)); } else if (AllInstalled) { FTS *ftsp; FTSENT *f; char *paths[2]; if (!isdir(tmp)) return 1; paths[0] = tmp; paths[1] = NULL; ftsp = fts_open(paths, FTS_LOGICAL | FTS_NOCHDIR | FTS_NOSTAT, fname_cmp); if (ftsp != NULL) { while ((f = fts_read(ftsp)) != NULL) { if (f->fts_info == FTS_D && f->fts_level == 1) { err_cnt += pkg_do(f->fts_name); fts_set(ftsp, f, FTS_SKIP); } } fts_close(ftsp); } } else for (i = 0; pkgs[i]; i++) err_cnt += pkg_do(pkgs[i]); return err_cnt; } static char *Home; static int pkg_do(char *pkg) { Boolean installed = FALSE, isTMP = FALSE; char log_dir[FILENAME_MAX]; char fname[FILENAME_MAX]; Package plist; FILE *fp; struct stat sb; char *cp = NULL; int code = 0; if (isURL(pkg)) { if ((cp = fileGetURL(NULL, pkg)) != NULL) { strcpy(fname, cp); isTMP = TRUE; } } else if (fexists(pkg) && isfile(pkg)) { int len; if (*pkg != '/') { if (!getcwd(fname, FILENAME_MAX)) upchuck("getcwd"); len = strlen(fname); snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg); } else strcpy(fname, pkg); cp = fname; } else { if ((cp = fileFindByPath(NULL, pkg)) != NULL) strncpy(fname, cp, FILENAME_MAX); } if (cp) { /* * Apply a crude heuristic to see how much space the package will * take up once it's unpacked. I've noticed that most packages * compress an average of 75%, but we're only unpacking the + files so * be very optimistic. */ if (stat(fname, &sb) == FAIL) { warnx("can't stat package file '%s'", fname); code = 1; goto bail; } Home = make_playpen(PlayPen, sb.st_size / 2); if (unpack(fname, "+*")) { warnx("error during unpacking, no info for '%s' available", pkg); code = 1; goto bail; } } /* It's not an ininstalled package, try and find it among the installed */ else { char *tmp; sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, pkg); if (!fexists(log_dir)) { warnx("can't find package `%s' installed or in a file!", pkg); return 1; } if (chdir(log_dir) == FAIL) { warnx("can't change directory to '%s'!", log_dir); return 1; } installed = TRUE; } /* Suck in the contents list */ plist.head = plist.tail = NULL; fp = fopen(CONTENTS_FNAME, "r"); if (!fp) { warnx("unable to open %s file", CONTENTS_FNAME); code = 1; goto bail; } /* If we have a prefix, add it now */ read_plist(&plist, fp); fclose(fp); /* * Index is special info type that has to override all others to make * any sense. */ if (Flags & SHOW_INDEX) { char tmp[FILENAME_MAX]; snprintf(tmp, FILENAME_MAX, "%-19s ", pkg); show_index(tmp, COMMENT_FNAME); } else { /* Start showing the package contents */ if (!Quiet) printf("%sInformation for %s:\n\n", InfoPrefix, pkg); if (Flags & SHOW_COMMENT) show_file("Comment:\n", COMMENT_FNAME); if (Flags & SHOW_REQUIRE) show_plist("Depends on:\n", &plist, PLIST_PKGDEP); if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME)) show_file("Required by:\n", REQUIRED_BY_FNAME); if (Flags & SHOW_DESC) show_file("Description:\n", DESC_FNAME); if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME)) show_file("Install notice:\n", DISPLAY_FNAME); if (Flags & SHOW_PLIST) show_plist("Packing list:\n", &plist, (plist_t)-1); if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME)) show_file("Install script:\n", INSTALL_FNAME); if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME)) show_file("Post-Install script:\n", POST_INSTALL_FNAME); if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME)) show_file("De-Install script:\n", DEINSTALL_FNAME); if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME)) show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME); if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME)) show_file("mtree file:\n", MTREE_FNAME); if (Flags & SHOW_PREFIX) show_plist("Prefix(s):\n", &plist, PLIST_CWD); if (Flags & SHOW_FILES) show_files("Files:\n", &plist); if ((Flags & SHOW_SIZE) && installed) show_size("Package Size:\n", &plist); + if ((Flags & SHOW_CKSUM) && installed) + show_cksum("Mismatched Checksums:\n", &plist); if (Flags & SHOW_ORIGIN) show_origin("Origin:\n", &plist); if (!Quiet) puts(InfoPrefix); } free_plist(&plist); bail: leave_playpen(); if (isTMP) unlink(fname); return code; } void cleanup(int sig) { static int in_cleanup = 0; if (!in_cleanup) { in_cleanup = 1; leave_playpen(); } if (sig) exit(1); } static int fname_cmp(const FTSENT **a, const FTSENT **b) { return strcmp((*a)->fts_name, (*b)->fts_name); } Index: head/usr.sbin/pkg_install/info/pkg_info.1 =================================================================== --- head/usr.sbin/pkg_install/info/pkg_info.1 (revision 71964) +++ head/usr.sbin/pkg_install/info/pkg_info.1 (revision 71965) @@ -1,188 +1,190 @@ .\" .\" FreeBSD install - a package for the installation and maintainance .\" of non-core utilities. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" Jordan K. Hubbard .\" .\" .\" @(#)pkg_info.1 .\" $FreeBSD$ .\" .Dd November 25, 1994 .Dt PKG_INFO 1 .Os FreeBSD .Sh NAME .Nm pkg_info .Nd a utility for displaying information on software packages .Sh SYNOPSIS .Nm -.Op Fl cdDfiIkLmopqrRsv +.Op Fl cdDfgiIkLmopqrRsv .Op Fl e Ar package .Op Fl l Ar prefix .Op Fl t Ar template .Op Ar pkg-name ... .Nm .Fl a .Op Ar flags .Sh DESCRIPTION The .Nm command is used to dump out information for packages, either packed up in files with the .Xr pkg_create 1 command or already installed on the system with the .Xr pkg_add 1 command. .Sh OPTIONS The following command line options are supported: .Bl -tag -width indent .It Ar pkg-name ... The named packages are described. A package name may either be the name of an installed package, the pathname to a package distribution file or a URL to an ftp available package. .It Fl a Show all currently installed packages. .It Fl v Turn on verbose output. .It Fl p Show the installation prefix for each package. .It Fl q Be .Dq quiet in emitting report headers and such, just dump the raw info (basically, assume a non-human reading). .It Fl c Show the comment (one liner) field for each package. .It Fl d Show the long description field for each package. .It Fl D Show the install-message file for each package. .It Fl f Show the packing list instructions for each package. +.It Fl g +Show files that don't match the recorded checksum. .It Fl i Show the install script (if any) for each package. .It Fl I Show an index line for each package. This option takes precedence over all other package formatting options. .It Fl k Show the de-install script (if any) for each package. .It Fl r Show the requirements script (if any) for each package. .It Fl R Show the list of installed packages which require each package. .It Fl m Show the mtree file (if any) for each package. .It Fl L Show the files within each package. This is different from just viewing the packing list, since full pathnames for everything are generated. .It Fl s Show the total size occupied by files installed within each package. .It Fl o Show the .Dq origin path recorded on package generation. This path intended to give an idea as to where the underlying port, from which package was generated, is located in the .Fx .Em "Ports Collection" . .It Fl e Ar pkg-name If the package identified by .Ar pkg-name is currently installed, return 0, otherwise return 1. This option allows you to easily test for the presence of another (perhaps prerequisite) package from a script. .It Fl l Ar str Prefix each information category header (see .Fl q ) shown with .Ar str . This is primarily of use to front-end programs who want to request a lot of different information fields at once for a package, but don't necessary want the output intermingled in such a way that they can't organize it. This lets you add a special token to the start of each field. .It Fl t Ar template Use .Ar template as the input to .Xr mktemp 3 when creating a .Dq staging area . By default, this is the string .Pa /tmp/instmp.XXXXXX , but it may be necessary to override it in the situation where space in your .Pa /tmp directory is limited. Be sure to leave some number of `X' characters for .Xr mktemp 3 to fill in with a unique ID. .Bd -filled -offset indent -compact Note: This should really not be necessary with .Nm , since very little information is extracted from each package and one would have to have a very small .Pa /tmp indeed to overflow it. .Ed .El .Sh TECHNICAL DETAILS Package info is either extracted from package files named on the command line, or from already installed package information in .Pa /var/db/pkg/ . .Sh ENVIRONMENT .Ev PKG_TMPDIR points to the directory where .Nm creates its temporary files. If this variable is not set, .Ev TMPDIR is used. If both are unset, the builtin defaults are used. .Pp .Ev PKG_DBDIR specifies an alternative location for the installed package database. .Sh FILES .Bl -tag -width /var/db/pkg -compact .It Pa /var/tmp Used if the environment variables .Ev PKG_TMPDIR and .Ev TMPDIR are not set, or if the directories named have insufficient space. .It Pa /tmp The next choice if .Pa /var/tmp does not exist or has insufficient space. .It Pa /usr/tmp The last choice if .Pa /tmp is unsuitable. .It Pa /var/db/pkg Default location of the installed package database. .El .Sh SEE ALSO .Xr pkg_add 1 , .Xr pkg_create 1 , .Xr pkg_delete 1 , .Xr pkg_version 1 , .Xr mktemp 3 , .Xr mtree 8 .Sh AUTHORS .An Jordan Hubbard for most of the work. .An John Kohl for NetBSD refinements. .Sh BUGS Sure to be some. Index: head/usr.sbin/pkg_install/info/show.c =================================================================== --- head/usr.sbin/pkg_install/info/show.c (revision 71964) +++ head/usr.sbin/pkg_install/info/show.c (revision 71965) @@ -1,273 +1,303 @@ #ifndef lint static const char rcsid[] = "$FreeBSD$"; #endif /* * FreeBSD install - a package for the installation and maintainance * of non-core utilities. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Jordan K. Hubbard * 23 Aug 1993 * * Various display routines for the info module. * */ #include "lib.h" #include "info.h" #include #include #include #include +#include void show_file(char *title, char *fname) { FILE *fp; char line[1024]; int n; if (!Quiet) printf("%s%s", InfoPrefix, title); fp = fopen(fname, "r"); if (!fp) printf("ERROR: show_file: Can't open '%s' for reading!\n", fname); else { while ((n = fread(line, 1, 1024, fp)) != 0) fwrite(line, 1, n, stdout); fclose(fp); } printf("\n"); /* just in case */ } void show_index(char *title, char *fname) { FILE *fp; char line[MAXINDEXSIZE+2]; if (!Quiet) printf("%s%s", InfoPrefix, title); fp = fopen(fname, "r"); if (!fp) { warnx("show_file: can't open '%s' for reading", fname); return; } if(fgets(line, MAXINDEXSIZE+1, fp)) { if(line[MAXINDEXSIZE-1] != '\n') line[MAXINDEXSIZE] = '\n'; line[MAXINDEXSIZE+1] = 0; fputs(line, stdout); } fclose(fp); } /* Show a packing list item type. If type is -1, show all */ void show_plist(char *title, Package *plist, plist_t type) { PackingList p; Boolean ign = FALSE; if (!Quiet) printf("%s%s", InfoPrefix, title); p = plist->head; while (p) { if (p->type != type && type != -1) { p = p->next; continue; } switch(p->type) { case PLIST_FILE: if (ign) { printf(Quiet ? "%s\n" : "File: %s (ignored)\n", p->name); ign = FALSE; } else printf(Quiet ? "%s\n" : "File: %s\n", p->name); break; case PLIST_CWD: printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", p->name); break; case PLIST_SRC: printf(Quiet ? "@srcdir %s\n" : "\tSRCDIR to %s\n", p->name); break; case PLIST_CMD: printf(Quiet ? "@exec %s\n" : "\tEXEC '%s'\n", p->name); break; case PLIST_UNEXEC: printf(Quiet ? "@unexec %s\n" : "\tUNEXEC '%s'\n", p->name); break; case PLIST_CHMOD: printf(Quiet ? "@chmod %s\n" : "\tCHMOD to %s\n", p->name ? p->name : "(clear default)"); break; case PLIST_CHOWN: printf(Quiet ? "@chown %s\n" : "\tCHOWN to %s\n", p->name ? p->name : "(clear default)"); break; case PLIST_CHGRP: printf(Quiet ? "@chgrp %s\n" : "\tCHGRP to %s\n", p->name ? p->name : "(clear default)"); break; case PLIST_COMMENT: printf(Quiet ? "@comment %s\n" : "\tComment: %s\n", p->name); break; case PLIST_IGNORE: ign = TRUE; break; case PLIST_IGNORE_INST: printf(Quiet ? "@ignore_inst ??? doesn't belong here.\n" : "\tIgnore next file installation directive (doesn't belong)\n"); ign = TRUE; break; case PLIST_NAME: printf(Quiet ? "@name %s\n" : "\tPackage name: %s\n", p->name); break; case PLIST_DISPLAY: printf(Quiet ? "@display %s\n" : "\tInstall message file: %s\n", p->name); break; case PLIST_PKGDEP: printf(Quiet ? "@pkgdep %s\n" : "\t%s\n", p->name); break; case PLIST_MTREE: printf(Quiet ? "@mtree %s\n" : "\tPackage mtree file: %s\n", p->name); break; case PLIST_DIR_RM: printf(Quiet ? "@dirrm %s\n" : "\tDeinstall directory remove: %s\n", p->name); break; default: cleanup(0); errx(2, __FUNCTION__ ": unknown command type %d (%s)", p->type, p->name); break; } p = p->next; } } /* Show all files in the packing list (except ignored ones) */ void show_files(char *title, Package *plist) { PackingList p; Boolean ign = FALSE; char *dir = "."; if (!Quiet) printf("%s%s", InfoPrefix, title); p = plist->head; while (p) { switch(p->type) { case PLIST_FILE: if (!ign) printf("%s/%s\n", dir, p->name); ign = FALSE; break; case PLIST_CWD: dir = p->name; break; case PLIST_IGNORE: ign = TRUE; break; /* Silence GCC in the -Wall mode */ default: break; } p = p->next; } } /* Calculate and show size of all installed package files (except ignored ones) */ void show_size(char *title, Package *plist) { PackingList p; Boolean ign = FALSE; char *dir = "."; struct stat sb; char tmp[FILENAME_MAX]; unsigned long size = 0; long blksize; int headerlen; char *descr; descr = getbsize(&headerlen, &blksize); if (!Quiet) printf("%s%s", InfoPrefix, title); for (p = plist->head; p != NULL; p = p->next) { switch (p->type) { case PLIST_FILE: if (!ign) { snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name); if (!lstat(tmp, &sb)) { size += sb.st_size; if (Verbose) printf("%lu\t%s\n", (unsigned long) howmany(sb.st_size, blksize), tmp); } } ign = FALSE; break; case PLIST_CWD: dir = p->name; break; case PLIST_IGNORE: ign = TRUE; break; /* Silence GCC in the -Wall mode */ default: break; } } if (!Quiet) printf("%lu\t(%s)\n", howmany(size, blksize), descr); else printf("%lu\n", size); +} + +/* Show files that don't match the recorded checksum */ +void +show_cksum(char *title, Package *plist) +{ + PackingList p; + char *dir = "."; + char tmp[FILENAME_MAX]; + + if (!Quiet) + printf("%s%s", InfoPrefix, title); + + for (p = plist->head; p != NULL; p = p->next) + if (p->type == PLIST_CWD) + dir = p->name; + else if (p->type == PLIST_FILE) { + snprintf(tmp, FILENAME_MAX, "%s/%s", dir, p->name); + if (!fexists(tmp)) + warnx("%s doesn't exist\n", tmp); + else if (p->next && p->next->type == PLIST_COMMENT && !strncmp(p->next->name, "MD5:", 4)) { + char *cp, buf[33]; + if ((cp = MD5File(tmp, buf)) != NULL) + if (strcmp(cp, p->next->name + 4)) + printf("%s fails the original MD5 checksum\n", tmp); + else if (Verbose) + printf("%s matched the original MD5 checksum\n", tmp); + } + } } /* Show an "origin" path (usually category/portname) */ void show_origin(char *title, Package *plist) { PackingList p; if (!Quiet) printf("%s%s", InfoPrefix, title); for (p = plist->head; p != NULL; p = p->next) if (p->type == PLIST_COMMENT && !strncmp(p->name, "ORIGIN:", 7)) { printf("%s\n", p->name + 7); break; } }