X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=ar_subs.c;h=382462cd6540f148abe3258affcc8650a0426d8c;hb=bfabbf6f00b4c263db351e7ad9ca4821cafd3b33;hp=eaf3362cd9bff4f6a09a48eb257b981deb70f5db;hpb=537d34cbb40c3babaa12ef59cfbb292416ff5c30;p=debian%2Fpax diff --git a/ar_subs.c b/ar_subs.c index eaf3362..382462c 100644 --- a/ar_subs.c +++ b/ar_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar_subs.c,v 1.14 1998/09/20 02:22:21 millert Exp $ */ +/* $OpenBSD: ar_subs.c,v 1.32 2008/05/06 06:54:28 henning Exp $ */ /* $NetBSD: ar_subs.c,v 1.5 1995/03/21 09:07:06 cgd Exp $ */ /*- @@ -17,11 +17,7 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -40,9 +36,9 @@ #ifndef lint #if 0 -static char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94"; +static const char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94"; #else -static char rcsid[] = "$OpenBSD: ar_subs.c,v 1.14 1998/09/20 02:22:21 millert Exp $"; +static const char rcsid[] = "$OpenBSD: ar_subs.c,v 1.32 2008/05/06 06:54:28 henning Exp $"; #endif #endif /* not lint */ @@ -61,9 +57,9 @@ static char rcsid[] = "$OpenBSD: ar_subs.c,v 1.14 1998/09/20 02:22:21 millert Ex #include "pax.h" #include "extern.h" -static void wr_archive __P((register ARCHD *, int is_app)); -static int get_arc __P((void)); -static int next_head __P((register ARCHD *)); +static void wr_archive(ARCHD *, int is_app); +static int get_arc(void); +static int next_head(ARCHD *); extern sigset_t s_mask; /* @@ -80,16 +76,11 @@ u_long flcnt; /* number of files processed */ * (no pattern matches all). */ -#ifdef __STDC__ void list(void) -#else -void -list() -#endif { - register ARCHD *arcn; - register int res; + ARCHD *arcn; + int res; ARCHD archd; time_t now; @@ -114,6 +105,17 @@ list() * step through the archive until the format says it is done */ while (next_head(arcn) == 0) { + if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) { + /* + * we need to read, to get the real filename + */ + off_t cnt; + if (!(*frmt->rd_data)(arcn, arcn->type == PAX_GLF + ? -1 : -2, &cnt)) + (void)rd_skip(cnt + arcn->pad); + continue; + } + /* * check for pattern, and user specified options match. * When all patterns are matched we are done. @@ -162,16 +164,11 @@ list() * pattern(s) (no patterns extracts all members) */ -#ifdef __STDC__ void extract(void) -#else -void -extract() -#endif { - register ARCHD *arcn; - register int res; + ARCHD *arcn; + int res; off_t cnt; ARCHD archd; struct stat sb; @@ -202,6 +199,15 @@ extract() * says it is done */ while (next_head(arcn) == 0) { + if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) { + /* + * we need to read, to get the real filename + */ + if (!(*frmt->rd_data)(arcn, arcn->type == PAX_GLF + ? -1 : -2, &cnt)) + (void)rd_skip(cnt + arcn->pad); + continue; + } /* * check for pattern, and user specified options match. When @@ -221,7 +227,7 @@ extract() /* * with -u or -D only extract when the archive member is newer - * than the file with the same name in the file system (nos + * than the file with the same name in the file system (no * test of being the same type is required). * NOTE: this test is done BEFORE name modifications as * specified by pax. this operation can be confusing to the @@ -262,7 +268,7 @@ extract() } /* - * Non standard -Y and -Z flag. When the exisiting file is + * Non standard -Y and -Z flag. When the existing file is * same age or newer skip */ if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) { @@ -287,7 +293,7 @@ extract() if (vflag > 1) ls_list(arcn, now, listf); else { - (void)fputs(arcn->name, listf); + (void)safe_print(arcn->name, listf); vfpart = 1; } } @@ -322,7 +328,7 @@ extract() (void)putc('\n', listf); vfpart = 0; } - continue; + goto popd; } /* * we have a file with data here. If we can not create it, skip @@ -331,7 +337,7 @@ extract() if ((fd = file_creat(arcn)) < 0) { (void)rd_skip(arcn->skip + arcn->pad); purg_lnk(arcn); - continue; + goto popd; } /* * extract the file from the archive and skip over padding and @@ -346,6 +352,7 @@ extract() if (!res) (void)rd_skip(cnt + arcn->pad); +popd: /* * if required, chdir around. */ @@ -373,21 +380,14 @@ extract() * previously written archive. */ -#ifdef __STDC__ static void -wr_archive(register ARCHD *arcn, int is_app) -#else -static void -wr_archive(arcn, is_app) - register ARCHD *arcn; - int is_app; -#endif +wr_archive(ARCHD *arcn, int is_app) { - register int res; - register int hlk; - register int wr_one; + int res; + int hlk; + int wr_one; off_t cnt; - int (*wrf)(); + int (*wrf)(ARCHD *); int fd = -1; time_t now; @@ -398,11 +398,22 @@ wr_archive(arcn, is_app) if (((hlk = frmt->hlk) == 1) && (lnk_start() < 0)) return; + /* + * if this is not append, and there are no files, we do not write a + * trailer + */ + wr_one = is_app; + /* * start up the file traversal code and format specific write */ - if ((ftree_start() < 0) || ((*frmt->st_wr)() < 0)) + if (ftree_start() < 0) { + if (is_app) + goto trailer; return; + } else if (((*frmt->st_wr)() < 0)) + return; + wrf = frmt->wr; /* @@ -412,11 +423,6 @@ wr_archive(arcn, is_app) if (iflag && (name_start() < 0)) return; - /* - * if this not append, and there are no files, we do no write a trailer - */ - wr_one = is_app; - now = time(NULL); /* @@ -436,8 +442,10 @@ wr_archive(arcn, is_app) */ if ((res = chk_ftime(arcn)) < 0) break; - if (res > 0) + if (res > 0) { + ftree_skipped_newer(arcn); continue; + } } /* @@ -480,7 +488,7 @@ wr_archive(arcn, is_app) if ((res > 0) || (docrc && (set_crc(arcn, fd) < 0))) { /* * unable to obtain the crc we need, close the file, - * purge link table entry + * purge link table entry */ rdfile_close(arcn, &fd); purg_lnk(arcn); @@ -491,7 +499,7 @@ wr_archive(arcn, is_app) if (vflag > 1) ls_list(arcn, now, listf); else { - (void)fputs(arcn->name, listf); + (void)safe_print(arcn->name, listf); vfpart = 1; } } @@ -507,7 +515,7 @@ wr_archive(arcn, is_app) } wr_one = 1; if (res > 0) { - /* + /* * format write says no file data needs to be stored * so we are done messing with this file */ @@ -544,8 +552,9 @@ wr_archive(arcn, is_app) break; } +trailer: /* - * tell format to write trailer; pad to block boundry; reset directory + * tell format to write trailer; pad to block boundary; reset directory * mode/access times, and check if all patterns supplied by the user * were matched. block off signals to avoid chance for multiple entry * into the cleanup code @@ -570,7 +579,7 @@ wr_archive(arcn, is_app) * is called to add the new members. * PAX IMPLEMENTATION DETAIL NOTE: * -u is implemented by adding the new members to the end of the archive. - * Care is taken so that these do not end up as links to the older + * Care is taken so that these do not end up as links to the older * version of the same file already stored in the archive. It is expected * when extraction occurs these newer versions will over-write the older * ones stored "earlier" in the archive (this may be a bad assumption as @@ -583,16 +592,11 @@ wr_archive(arcn, is_app) * over write existing files that it creates. */ -#ifdef __STDC__ void append(void) -#else -void -append() -#endif { - register ARCHD *arcn; - register int res; + ARCHD *arcn; + int res; ARCHD archd; FSUB *orgfrmt; int udev; @@ -603,7 +607,7 @@ append() /* * Do not allow an append operation if the actual archive is of a - * different format than the user specified foramt. + * different format than the user specified format. */ if (get_arc() < 0) return; @@ -699,7 +703,7 @@ append() lnk_end(); /* - * try to postion for write, if this fails quit. if any error occurs, + * try to position for write, if this fails quit. if any error occurs, * we will refuse to write */ if (appnd_start(tlen) < 0) @@ -712,7 +716,7 @@ append() (void)fputs("done.\n", listf); vfpart = 0; } - + /* * go to the writing phase to add the new members */ @@ -724,13 +728,8 @@ append() * write a new archive */ -#ifdef __STDC__ void archive(void) -#else -void -archive() -#endif { ARCHD archd; @@ -755,20 +754,15 @@ archive() * (except the files are forced to be under the destination directory). */ -#ifdef __STDC__ void copy(void) -#else -void -copy() -#endif { - register ARCHD *arcn; - register int res; - register int fddest; - register char *dest_pt; - register int dlen; - register int drem; + ARCHD *arcn; + int res; + int fddest; + char *dest_pt; + int dlen; + int drem; int fdsrc = -1; struct stat sb; ARCHD archd; @@ -779,13 +773,18 @@ copy() * set up the destination dir path and make sure it is a directory. We * make sure we have a trailing / on the destination */ - dlen = l_strncpy(dirbuf, dirptr, sizeof(dirbuf) - 1); + dlen = strlcpy(dirbuf, dirptr, sizeof(dirbuf)); + if (dlen >= sizeof(dirbuf) || + (dlen == sizeof(dirbuf) - 1 && dirbuf[dlen - 1] != '/')) { + paxwarn(1, "directory name is too long %s", dirptr); + return; + } dest_pt = dirbuf + dlen; if (*(dest_pt-1) != '/') { *dest_pt++ = '/'; + *dest_pt = '\0'; ++dlen; } - *dest_pt = '\0'; drem = PAXPATHLEN - dlen; if (stat(dirptr, &sb) < 0) { @@ -800,7 +799,7 @@ copy() /* * start up the hard link table; file traversal routines and the - * modification time and access mode database + * modification time and access mode database */ if ((lnk_start() < 0) || (ftree_start() < 0) || (dir_start() < 0)) return; @@ -843,17 +842,12 @@ copy() /* * create the destination name */ - if (*(arcn->name) == '/') - res = 1; - else - res = 0; - if ((arcn->nlen - res) > drem) { + if (strlcpy(dest_pt, arcn->name + (*arcn->name == '/'), + drem + 1) > drem) { paxwarn(1, "Destination pathname too long %s", arcn->name); continue; } - (void)strncpy(dest_pt, arcn->name + res, drem); - dirbuf[PAXPATHLEN] = '\0'; /* * if existing file is same age or newer skip @@ -861,10 +855,11 @@ copy() res = lstat(dirbuf, &sb); *dest_pt = '\0'; - if (res == 0) { + if (res == 0) { + ftree_skipped_newer(arcn); if (uflag && Dflag) { if ((arcn->sb.st_mtime<=sb.st_mtime) && - (arcn->sb.st_ctime<=sb.st_ctime)) + (arcn->sb.st_ctime<=sb.st_ctime)) continue; } else if (Dflag) { if (arcn->sb.st_ctime <= sb.st_ctime) @@ -891,7 +886,7 @@ copy() } /* - * Non standard -Y and -Z flag. When the exisiting file is + * Non standard -Y and -Z flag. When the existing file is * same age or newer skip */ if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) { @@ -907,7 +902,7 @@ copy() } if (vflag) { - (void)fputs(arcn->name, listf); + (void)safe_print(arcn->name, listf); vfpart = 1; } ++flcnt; @@ -1007,21 +1002,15 @@ copy() * the specs for rd_wrbuf() for more details) */ -#ifdef __STDC__ -static int -next_head(register ARCHD *arcn) -#else static int -next_head(arcn) - register ARCHD *arcn; -#endif +next_head(ARCHD *arcn) { - register int ret; - register char *hdend; - register int res; - register int shftsz; - register int hsz; - register int in_resync = 0; /* set when we are in resync mode */ + int ret; + char *hdend; + int res; + int shftsz; + int hsz; + int in_resync = 0; /* set when we are in resync mode */ int cnt = 0; /* counter for trailer function */ int first = 1; /* on 1st read, EOF isn't premature. */ @@ -1032,7 +1021,7 @@ next_head(arcn) res = hsz = frmt->hsz; hdend = hdbuf; shftsz = hsz - 1; - for(;;) { + for (;;) { /* * keep looping until we get a contiguous FULL buffer * (frmt->hsz is the proper size) @@ -1096,7 +1085,7 @@ next_head(arcn) /* * this format has trailers outside of valid headers */ - if ((ret = (*frmt->trail)(hdbuf,in_resync,&cnt)) == 0){ + if ((ret = (*frmt->trail)(arcn,hdbuf,in_resync,&cnt)) == 0){ /* * valid trailer found, drain input as required */ @@ -1143,7 +1132,7 @@ next_head(arcn) * the header. NOTE: the parameters are different than trailer routines * which encode trailers outside of the header! */ - if (frmt->inhead && ((*frmt->trail)(arcn) == 0)) { + if (frmt->inhead && ((*frmt->trail)(arcn,NULL,0,NULL) == 0)) { /* * valid trailer found, drain input as required */ @@ -1165,18 +1154,13 @@ next_head(arcn) * 0 if archive found -1 otherwise */ -#ifdef __STDC__ static int get_arc(void) -#else -static int -get_arc() -#endif { - register int i; - register int hdsz = 0; - register int res; - register int minhd = BLKMULT; + int i; + int hdsz = 0; + int res; + int minhd = BLKMULT; char *hdend; int notice = 0; @@ -1193,7 +1177,7 @@ get_arc() res = BLKMULT; hdsz = 0; hdend = hdbuf; - for(;;) { + for (;;) { for (;;) { /* * fill the buffer with at least the smallest header @@ -1239,7 +1223,7 @@ get_arc() if ((*fsub[ford[i]].id)(hdbuf, hdsz) < 0) continue; frmt = &(fsub[ford[i]]); - /* + /* * yuck, to avoid slow special case code in the extract * routines, just push this header back as if it was * not seen. We have left extra space at start of the