diff options
Diffstat (limited to 'tools/cpio/src/pax.c')
-rw-r--r-- | tools/cpio/src/pax.c | 757 |
1 files changed, 0 insertions, 757 deletions
diff --git a/tools/cpio/src/pax.c b/tools/cpio/src/pax.c deleted file mode 100644 index 50632b6b1..000000000 --- a/tools/cpio/src/pax.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * cpio - copy file archives in and out - * - * Gunnar Ritter, Freiburg i. Br., Germany, April 2003. - */ -/* - * Copyright (c) 2003 Gunnar Ritter - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source distribution. - */ - -#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 -#define USED __attribute__ ((used)) -#elif defined __GNUC__ -#define USED __attribute__ ((unused)) -#else -#define USED -#endif -#if defined (SU3) -static const char sccsid[] USED = "@(#)pax_su3.sl 1.26 (gritter) 6/26/05"; -#else -static const char sccsid[] USED = "@(#)pax.sl 1.26 (gritter) 6/26/05"; -#endif -/* Sccsid @(#)pax.c 1.26 (gritter) 6/26/05 */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <fnmatch.h> -#include <dirent.h> -#include <regex.h> -#include <wchar.h> -#include <time.h> -#include <inttypes.h> - -#include "iblok.h" -#include "cpio.h" - -static char **files; -static int filec; -static struct iblok *filinp; -static char *path; -static size_t pathsz; -static int pax_Hflag; - -static void setpres(const char *); -static size_t ofiles_pax(char **, size_t *); -static void prtime_pax(time_t); -static void parsesub(char *); - -void -flags(int ac, char **av) -{ - const char optstring[] = "rwab:cdf:HikKlLno:p:s:tuvx:X"; - int i; - int illegal = 0; - char *x; - -#if defined (SU3) - pax = PAX_TYPE_PAX2001; -#else - pax = PAX_TYPE_PAX1992; -#endif - dflag = 1; - uflag = 1; - ofiles = ofiles_pax; - prtime = prtime_pax; - while ((i = getopt(ac, av, optstring)) != EOF) { - switch (i) { - case 'r': - if (action && action != 'i') - action = 'p'; - else - action = 'i'; - break; - case 'w': - if (action && action != 'o') - action = 'p'; - else - action = 'o'; - break; - case 'a': - Aflag = 1; - break; - case 'b': - blksiz = strtol(optarg, &x, 10); - switch (*x) { - case 'b': - blksiz *= 512; - break; - case 'k': - blksiz *= 1024; - break; - case 'm': - blksiz *= 1048576; - break; - case 'w': - blksiz *= 2; - break; - } - if (blksiz <= 0) - msg(4, -2, - "Illegal size given for -b option.\n"); - Cflag = 1; - break; - case 'c': - fflag = 1; - break; - case 'd': - pax_dflag = 1; - break; - case 'f': - Oflag = Iflag = optarg; - break; - case 'H': - pax_Hflag = 1; - break; - case 'i': - rflag = 1; - break; - case 'k': - pax_kflag = 1; - break; - case 'K': - kflag = 1; - break; - case 'l': - lflag = 1; - break; - case 'L': - Lflag = 1; - break; - case 'n': - pax_nflag = 1; - break; - case 'o': - pax_options(optarg, 1); - break; - case 'p': - setpres(optarg); - break; - case 's': - pax_sflag = 1; - parsesub(optarg); - break; - case 't': - aflag = 1; - break; - case 'u': - uflag = 0; - pax_uflag = 1; - break; - case 'v': - vflag = 1; - break; - case 'x': - if (strcmp(optarg, "cpio") == 0) - fmttype = FMT_ODC; - else { - if (setfmt(optarg) < 0) - illegal = 1; - } - break; - case 'X': - pax_Xflag = 1; - break; - default: - illegal = 1; - } - } - switch (action) { - case 0: - if (rflag || pax_kflag || pax_uflag || pax_preserve) - illegal = 1; - action = 'i'; - tflag = 1; - setvbuf(stdout, NULL, _IOLBF, 0); - /*FALLTHRU*/ - case 'i': - if (aflag || pax_Xflag || lflag) - illegal = 1; - for (i = optind; i < ac; i++) { - addg(av[i], 0); - if (pax_dflag == 0) { - char *da; - int j; - - da = smalloc(strlen(av[i]) + 2); - for (j = 0; av[i][j]; j++) - da[j] = av[i][j]; - da[j++] = '/'; - da[j++] = '*'; - da[j] = 0; - addg(da, 1); - free(da); - } - } - break; - case 'o': - if (fflag || pax_kflag || pax_nflag || kflag) - illegal = 1; - if (Aflag && Oflag == NULL) { - msg(3, 0, "-a requires the -f option\n"); - illegal = 1; - } - if (optind != ac) { - files = &av[optind]; - filec = ac - optind; - } else - filinp = ib_alloc(0, 0); - if (pax_uflag) - Aflag = 1; - if (Aflag == 0 && fmttype == FMT_NONE) - fmttype = FMT_ODC; - break; - case 'p': - if (fflag || blksiz || Oflag || Iflag || fmttype != FMT_NONE || - kflag) - illegal = 1; - if (optind == ac) - illegal = 1; - else if (optind+1 != ac) { - files = &av[optind]; - filec = ac - optind - 1; - optind = ac - 1; - } else - filinp = ib_alloc(0, 0); - break; - } - if (illegal) - usage(); -} - -void -usage(void) -{ - fprintf(stderr, "USAGE:\n\ -\t%s [-cdnvK] [-b size] [-f file] [-s replstr] [-x hdr] [patterns]\n\ -\t%s -r[cdiknuvK] [-b size] [-f file] [-p priv] [-s replstr] [-x hdr] [patterns]\n\ -\t%s -w[adituvLX] [-b size] [-f file] [-s replstr] [-x hdr] [files]\n\ -\t%s -rw[diklntuvLX] [-p priv] [-s replstr] [files] directory\n", - progname, progname, progname, progname); - exit(1); -} - -static void -setpres(const char *s) -{ - s--; - while (*++s) { - pax_preserve &= ~PAX_P_EVERY; - switch (*s) { - case 'a': - pax_preserve |= PAX_P_ATIME; - break; - case 'e': - pax_preserve |= PAX_P_EVERY; - break; - case 'm': - pax_preserve |= PAX_P_MTIME; - break; - case 'o': - pax_preserve |= PAX_P_OWNER; - break; - case 'p': - pax_preserve |= PAX_P_MODE; - break; - default: - msg(2, 0, "ignoring unknown option \"-p%c\"\n", - *s&0377); - } - } - if (pax_preserve & PAX_P_EVERY) - pax_preserve |= PAX_P_OWNER|PAX_P_MODE; -} - -int -gmatch(const char *s, const char *p) -{ - int val; -#ifdef __GLIBC__ - /* avoid glibc's broken [^...] */ - extern char **environ; - char **savenv = environ; - char *newenv[] = { "POSIXLY_CORRECT=", NULL }; - environ = newenv; -#endif /* __GLIBC__ */ - val = fnmatch(p, s, 0) == 0; -#ifdef __GLIBC__ - environ = savenv; -#endif /* __GLIBC__ */ - return val; -} - -static const char * -nextfile(void) -{ - char *line = NULL; - size_t linsiz = 0, linlen; - - if (filinp) { - pax_Hflag = 0; - if ((linlen=ib_getlin(filinp, &line, &linsiz, srealloc)) == 0) { - filinp = NULL; - return NULL; - } - if (line[linlen-1] == '\n') - line[--linlen] = '\0'; - return line; - } else if (filec > 0) { - filec--; - return *files++; - } else - return NULL; -} - -static size_t -catpath(size_t pend, const char *base) -{ - size_t blen = strlen(base); - - if (pend + blen + 2 >= pathsz) - path = srealloc(path, pathsz = pend + blen + 16); - if (pend == 0 || path[pend-1] != '/') - path[pend++] = '/'; - strcpy(&path[pend], base); - return pend + blen; -} - -/* - * Descend the directory hierarchies given using stdin or arguments - * and return file names one per one. - */ -static size_t -ofiles_pax(char **name, size_t *namsiz) -{ - static DIR **dt; - static int dti, dts; - static int *pend; - static dev_t *curdev; - static ino_t *curino; - struct stat st; - struct dirent *dp; - const char *nf; - int i; - - if (dt == NULL) { - dt = scalloc(dts = 1, sizeof *dt); - pend = scalloc(dts, sizeof *pend); - curdev = scalloc(dts, sizeof *curdev); - curino = scalloc(dts, sizeof *curino); - } - for (;;) { - if (dti >= 0 && dt[dti] != NULL) { - if ((dp = readdir(dt[dti])) != NULL) { - if (dp->d_name[0] == '.' && - (dp->d_name[1] == '\0' || - dp->d_name[1] == '.' && - dp->d_name[2] == '\0')) - continue; - if (dti+1 <= dts) { - dt = srealloc(dt, sizeof *dt * ++dts); - pend = srealloc(pend, sizeof *pend*dts); - curdev = srealloc(curdev, sizeof *curdev - * dts); - curino = srealloc(curino, sizeof *curino - * dts); - } - pend[dti+1] = catpath(pend[dti], dp->d_name); - if (pax_Hflag) - Lflag = dti < 0; - if ((Lflag ? stat : lstat)(path, &st) < 0) { - emsg(2, "Error with %s of \"%s\"", - lflag? "stat" : "lstat", - path); - errcnt++; - } else if ((st.st_mode&S_IFMT) == S_IFDIR && - (pax_Xflag == 0 || - curdev[0] == st.st_dev)) { - if (Lflag) { - for (i = 0; i <= dti; i++) - if (st.st_dev == - curdev[i] && - st.st_ino == - curino[i]) { - if (pax == - PAX_TYPE_PAX2001) - msg(4, 1, - "Symbolic link " - "loop at " - "\"%s\"\n", - path); - break; - } - if (i <= dti) - break; - } - if ((dt[dti+1]=opendir(path)) == NULL) { - emsg(2, "Cannot open directory " - "\"%s\"", path); - errcnt++; - } else { - dti++; - curdev[dti] = st.st_dev; - curino[dti] = st.st_ino; - continue; - } - } else - break; - } else { - path[pend[dti]] = '\0'; - closedir(dt[dti]); - dt[dti--] = NULL; - if (pax_Hflag) - Lflag = dti < 0; - break; - } - } else { - if (pax_Hflag) - Lflag = 1; - while ((nf = nextfile()) != NULL && - (Lflag ? stat : lstat)(nf, &st) < 0) { - emsg(2, "Error with stat of \"%s\"", nf); - errcnt++; - } - if (nf == NULL) - return 0; - dti = 0; - if (path) - free(path); - pend[dti] = strlen(nf); - strcpy(path = smalloc(pathsz = pend[dti]+1), nf); - if (pax_dflag || (st.st_mode&S_IFMT) != S_IFDIR) { - dti = -1; - break; - } - curdev[dti] = st.st_dev; - curino[dti] = st.st_ino; - if ((dt[dti] = opendir(path)) == NULL) { - emsg(2, "Cannot open directory \"%s\"", path); - errcnt++; - } - } - } - if (*name == NULL || *namsiz < pathsz) { - free(*name); - *name = smalloc(*namsiz=pathsz); - } - strcpy(*name, path); - return pend[dti+1]; -} - -struct pax_had { - struct pax_had *p_next; - const char *p_name; - time_t p_mtime; -}; - -static int pprime = 7919; - -static int -phash(const char *s) -{ - uint32_t h = 0, g; - - s--; - while (*++s) { - h = (h << 4) + (*s & 0377); - if (g = h & 0xf0000000) { - h = h ^ (g >> 24); - h = h ^ g; - } - } - return h % pprime; -} - -static int -plook(const char *name, struct pax_had **pp) -{ - static struct pax_had **pt; - uint32_t h, had; - - if (pt == NULL) - pt = scalloc(pprime, sizeof *pt); - (*pp) = pt[h = phash(name)]; - while (*pp != NULL) { - if (strcmp((*pp)->p_name, name) == 0) - break; - *pp = (*pp)->p_next; - } - had = *pp != NULL; - if (*pp == NULL) { - *pp = scalloc(1, sizeof **pp); - (*pp)->p_name = sstrdup(name); - (*pp)->p_next = pt[h]; - pt[h] = *pp; - } - return had; -} - -int -pax_track(const char *name, time_t mtime) -{ - struct pax_had *pp; - struct stat st; - - if (pax_uflag == 0 && (pax_nflag == 0 || patterns)) - return 1; - if (action == 'i' && pax_uflag) { - if (lstat(name, &st) == 0 && mtime < st.st_mtime) - return 0; - } - if (action != 'i' || pax_nflag) { - if (plook(name, &pp) != 0) { - if (action != 'i' && pax_uflag == 0) - return 0; - if (mtime > pp->p_mtime) { - pp->p_mtime = mtime; - return 1; - } - return 0; - } else - pp->p_mtime = mtime; - } - return 1; -} - -static void -prtime_pax(time_t t) -{ - char b[30]; - time_t now; - - time(&now); - if (t > now || t < now - (6*30*86400)) - strftime(b, sizeof b, "%b %e %Y", localtime(&t)); - else - strftime(b, sizeof b, "%b %e %H:%M", localtime(&t)); - printf(" %s ", b); -} - -struct replacement { - regex_t r_re; - const char *r_rhs; - int r_nbra; - enum { - REPL_0 = 0, - REPL_G = 1, - REPL_P = 2 - } r_flags; -} *rep; - -#define NBRA 9 -static int ren, res; -static int mb_cur_max; - -static wchar_t -nextc(char **sc, int *np) -{ - char *p = *sc; - wchar_t wcbuf; - int len; - - if (**sc == '\0') { - *np = 0; - return 0; - } - if (mb_cur_max == 1 || (**sc&0200) == 0) { - *np = 1; - return *(*sc)++ & 0377; - } - if ((len = mbtowc(&wcbuf, p, mb_cur_max)) < 0) - msg(3, -2, "Invalid multibyte character for \"-s\" option\n"); - *np = len; - *sc += len; - return wcbuf; -} - -static void -parsesub(char *s) -{ - int len; - char *ps = NULL; - wchar_t seof = nextc(&s, &len); - wint_t c, d; - int nbra = 0; - int reflags; - - if (seof == 0) - goto unt; - mb_cur_max = MB_CUR_MAX; - ps = s; - do { - if ((c = nextc(&s, &len)) == seof) - break; - if (c == '\\') { - if ((c = nextc(&s, &len)) == '(') - nbra++; - continue; - } else if (c == '[') { - d = WEOF; - do { - if ((c = nextc(&s, &len)) == '\0') - continue; - if (d == '[' && (c == ':' || c == '.' || - c == '=')) { - d = c; - do { - if ((c=nextc(&s, &len)) == '\0') - continue; - } while (c != d || *s != ']'); - nextc(&s, &len); - c = WEOF; /* reset d and continue */ - } - d = c; - } while (c != ']'); - } - } while (*s != '\0'); - if (c != seof) - unt: msg(3, -2, "Unterminated argument for \"-s\" option.\n"); - s[-len] = '\0'; - if (ren <= res) - rep = srealloc(rep, ++res * sizeof *rep); - reflags = REG_ANGLES; - if (pax >= PAX_TYPE_PAX2001) - reflags |= REG_AVOIDNULL; - if (regcomp(&rep[ren].r_re, ps, reflags) != 0) - msg(3, -2, "Regular expression error in \"-s\" option\n"); - rep[ren].r_rhs = s; - rep[ren].r_nbra = nbra; - while ((c = nextc(&s, &len)) != 0) { - if (c == '\\') - c = nextc(&s, &len); - else if (c == seof) - break; - } - rep[ren].r_flags = 0; - if (c == seof) { - s[-len] = '\0'; - while ((c = nextc(&s, &len)) != '\0') { - switch (c) { - case 'g': - rep[ren].r_flags |= REPL_G; - break; - case 'p': - rep[ren].r_flags |= REPL_P; - break; - default: - msg(2, 0, "Ignoring unknown -s flag \"%c\"\n", - c); - } - } - } - ren++; -} - -#define put(c) ((new = innew+1>=newsize ? srealloc(new, newsize+=32) : new), \ - new[innew++] = (c)) - -int -pax_sname(char **oldp, size_t *olds) -{ - char *new = NULL; - size_t newsize = 0; - regmatch_t bralist[NBRA+1]; - int c, i, k, l, y, z; - int innew = 0, ef = 0; - char *inp = *oldp; - - for (z = 0; z < ren; z++) { - in: if (regexec(&rep[z].r_re, inp, NBRA+1, bralist, ef) != 0) { - if (ef == 0) - continue; - goto out; - } - for (i = 0; i < bralist[0].rm_so; i++) - put(inp[i]); - k = 0; - while (c = rep[z].r_rhs[k++] & 0377) { - y = -1; - if (c == '&') - y = 0; - else if (c == '\\') { - c = rep[z].r_rhs[k++] & 0377; - if (c >= '1' && c < rep[z].r_nbra+'1') - y = c - '0'; - } - if (y >= 0) - for (l = bralist[y].rm_so; l < bralist[y].rm_eo; - l++) - put(inp[l]); - else - put(c); - } - k = innew; - for (i = bralist[0].rm_eo; inp[i]; i++) - put(inp[i]); - put('\0'); - if (rep[z].r_flags & REPL_G) { - ef = REG_NOTBOL; - inp = &inp[bralist[0].rm_eo]; - innew = k; - if (bralist[0].rm_so == bralist[0].rm_eo) { - if (inp[0] && (nextc(&inp, &l), inp[0])) - innew++; - else - goto out; - } - goto in; - } - out: if (rep[z].r_flags & REPL_P) - fprintf(stderr, "%s >> %s\n", *oldp, new); - free(*oldp); - *oldp = new; - *olds = newsize; - return *new != '\0'; - } - return 1; -} - -void -pax_onexit(void) -{ - struct glist *gp; - - for (gp = patterns; gp; gp = gp->g_nxt) { - if (gp->g_art) - continue; - if (gp->g_gotcha == 0 && (gp->g_nxt == NULL || - gp->g_nxt->g_art == 0 || - gp->g_gotcha == 0)) { - msg(3, 0, "Pattern not matched: \"%s\"\n", gp->g_pat); - errcnt++; - } - } -} |