ar.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 916 行 · 第 1/2 页
C
916 行
#ifndef lintstatic char *sccsid = "@(#)ar.c 4.1 (ULTRIX) 7/17/90";#endif/* * ar - portable (ascii) format version */#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/param.h>#include <stdio.h>#include <ar.h>#include <signal.h>/************************************************************************ * * * Copyright (c) 1985,1986,1987,1988,1989 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * Modification History * * Tim Newhouse, 11-April-1989 * 007- Added calls to tempnam() when not using the 'l' option so that * the temp files will use the TMPDIR environment symbol if it is * defined. * * Tim Newhouse, 12-Jan-1989 * 006- Cloned match/trim routines for the -r option (rcmd) * because it was not getting the file name truncation correct * during the replace operation. Pretty much a duplicate of the * trim() and match() routines were used in a new routine rcmd_match * which is now used just by rcmd() to do the matching of file names * and still preserve the filename for later use in the opening of the * file. * * Mark Parenti, 08-Jun-1988 * 005- Changed signal handlers to void. * * Teoman Topcubasi, 15-Jan-1988 * 004- Added a '-' in front of the options. * * David L Ballenger, 16-Apr-1985 * 003- Change definition of tmpnam variable to tmpname so that it doesn't * conflict with definition of tmpnam() in <stdio.h>. * * Stephen Reilly, 15-Feb-84 * 002- The uid and gid are unsigned elements but are being store into * the ar files as signed elements * * Stephen Reilly, 10-Nov-83: * 001- The n switch was not documented and is not used * ***********************************************************************/struct stat stbuf;struct ar_hdr arbuf;struct lar_hdr { char lar_name[16]; long lar_date; u_short lar_uid; u_short lar_gid; u_short lar_mode; long lar_size;} larbuf;#define SKIP 1#define IODD 2#define OODD 4#define HEAD 8char *man = { "-mrxtdpq" }; /* 004 */char *opt = { "uvbailo" }; /* slr001 n was removed */int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};void sigdone();long lseek();int rcmd();int dcmd();int xcmd();int tcmd();int pcmd();int mcmd();int qcmd();int (*comfun)();char flg[26];char **namv;int namc;char *arnam;char *ponam;char *tdir = { "/tmp" };char *tmpname = { "vXXXXX" };char *tmp1name = { "v1XXXXX" };char *tmp2name = { "v2XXXXX" };char *tfname;char *tf1name;char *tf2name;char *file;char name[16];int af;int tf;int tf1;int tf2;int qf;int bastate;char buf[MAXBSIZE];int truncate; /* ok to truncate argument filenames */char *trim();char *mktemp();char *ctime();char *tempnam();main(argc, argv)char *argv[];{ register i; register char *cp; for(i=0; signum[i]; i++) if(signal(signum[i], SIG_IGN) != SIG_IGN) signal(signum[i], sigdone); if(argc < 3) usage(); cp = argv[1]; if (*cp == '-') /* 004 */ cp++; /* 004 */ for(; *cp; cp++) /* 004 */ switch(*cp) { case 'o': case 'l': case 'v': case 'u':/* case 'n': slr001 n not longer used */ case 'a': case 'b': case 'c': case 'i': flg[*cp - 'a']++; continue; case 'r': setcom(rcmd); continue; case 'd': setcom(dcmd); continue; case 'x': setcom(xcmd); continue; case 't': setcom(tcmd); continue; case 'p': setcom(pcmd); continue; case 'm': setcom(mcmd); continue; case 'q': setcom(qcmd); continue; default: fprintf(stderr, "ar: bad option `%c'\n", *cp); done(1); } if(flg['l'-'a'] == 0) { tmpname = "v"; tmp1name = "v1"; tmp2name = "v2"; } if(flg['i'-'a']) flg['b'-'a']++; if(flg['a'-'a'] || flg['b'-'a']) { bastate = 1; ponam = trim(argv[2]); argv++; argc--; if(argc < 3) usage(); } arnam = argv[2]; namv = argv+3; namc = argc-3; if(comfun == 0) { if(flg['u'-'a'] == 0) { fprintf(stderr, "ar: one of [%s] must be specified\n", man); done(1); } setcom(rcmd); } (*comfun)(); done(notfound());}setcom(fun)int (*fun)();{ if(comfun != 0) { fprintf(stderr, "ar: only one of [%s] allowed\n", man); done(1); } comfun = fun;}rcmd(){ register f; init(); getaf(); /* turn on trim()'s truncation to 15 chars - we need this when * movefil() calls trim to get the filename to store in the * archive file. */ truncate++; while(!getdir()) { bamatch(); if(namc == 0 || rcmd_match()) { f = stats(); if(f < 0) { if(namc) fprintf(stderr, "ar: cannot open %s\n", file); goto cp; } if(flg['u'-'a']) if(stbuf.st_mtime <= larbuf.lar_date) { close(f); goto cp; } mesg('r'); copyfil(af, -1, IODD+SKIP); movefil(f); continue; } cp: mesg('c'); copyfil(af, tf, IODD+OODD+HEAD); } /* turn off (reset) trim()'s job of truncation to 15 chars */ truncate--; cleanup();}dcmd(){ init(); if(getaf()) noar(); while(!getdir()) { if(match()) { mesg('d'); copyfil(af, -1, IODD+SKIP); continue; } mesg('c'); copyfil(af, tf, IODD+OODD+HEAD); } install();}xcmd(){ register f; struct timeval tv[2]; if(getaf()) noar(); while(!getdir()) { if(namc == 0 || match()) { f = creat(file, larbuf.lar_mode & 0777); if(f < 0) { fprintf(stderr, "ar: %s cannot create\n", file); goto sk; } mesg('x'); copyfil(af, f, IODD); close(f); if (flg['o'-'a']) { tv[0].tv_sec = tv[1].tv_sec = larbuf.lar_date; tv[0].tv_usec = tv[1].tv_usec = 0; utimes(file, tv); } continue; } sk: mesg('c'); copyfil(af, -1, IODD+SKIP); if (namc > 0 && !morefil()) done(0); }}pcmd(){ if(getaf()) noar(); while(!getdir()) { if(namc == 0 || match()) { if(flg['v'-'a']) { printf("\n<%s>\n\n", file); fflush(stdout); } copyfil(af, 1, IODD); continue; } copyfil(af, -1, IODD+SKIP); }}mcmd(){ init(); if(getaf()) noar(); if(flg['l' - 'a']) tf2name = mktemp(tmp2name); else tf2name = tempnam(tdir,tmp2name); close(creat(tf2name, 0600)); tf2 = open(tf2name, 2); if(tf2 < 0) { fprintf(stderr, "ar: cannot create third temp\n"); done(1); } while(!getdir()) { bamatch(); if(match()) { mesg('m'); copyfil(af, tf2, IODD+OODD+HEAD); continue; } mesg('c'); copyfil(af, tf, IODD+OODD+HEAD); } install();}tcmd(){ if(getaf()) noar(); while(!getdir()) { if(namc == 0 || match()) { if(flg['v'-'a']) longt(); printf("%s\n", trim(file)); } copyfil(af, -1, IODD+SKIP); }}qcmd(){ register i, f; if (flg['a'-'a'] || flg['b'-'a']) { fprintf(stderr, "ar: abi not allowed with q\n"); done(1); } truncate++; getqf(); for(i=0; signum[i]; i++) signal(signum[i], SIG_IGN); lseek(qf, 0l, 2); for(i=0; i<namc; i++) { file = namv[i]; if(file == 0) continue; namv[i] = 0; mesg('q'); f = stats(); if(f < 0) { fprintf(stderr, "ar: %s cannot open\n", file); continue; } tf = qf; movefil(f); qf = tf; }}init(){ if(flg['l'-'a']) tfname = mktemp(tmpname); else tfname = tempnam(tdir,tmpname); close(creat(tfname, 0600)); tf = open(tfname, 2); if(tf < 0) { fprintf(stderr, "ar: cannot create temp file\n"); done(1); } if (write(tf, ARMAG, SARMAG) != SARMAG) wrerr();}getaf(){ char mbuf[SARMAG]; af = open(arnam, 0); if(af < 0) return(1); if (read(af, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) { fprintf(stderr, "ar: %s not in archive format\n", arnam); done(1); } return(0);}getqf(){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?