ar.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 916 行 · 第 1/2 页
C
916 行
char mbuf[SARMAG]; if ((qf = open(arnam, 2)) < 0) { if(!flg['c'-'a']) fprintf(stderr, "ar: creating %s\n", arnam); if ((qf = creat(arnam, 0666)) < 0) { fprintf(stderr, "ar: cannot create %s\n", arnam); done(1); } if (write(qf, ARMAG, SARMAG) != SARMAG) wrerr(); } else if (read(qf, mbuf, SARMAG) != SARMAG || strncmp(mbuf, ARMAG, SARMAG)) { fprintf(stderr, "ar: %s not in archive format\n", arnam); done(1); }}usage(){ printf("usage: ar [%s][%s] archive files ...\n", man, opt); done(1);}noar(){ fprintf(stderr, "ar: %s does not exist\n", arnam); done(1);}voidsigdone(){ done(100);}done(c){ if(tfname) unlink(tfname); if(tf1name) unlink(tf1name); if(tf2name) unlink(tf2name); exit(c);}notfound(){ register i, n; n = 0; for(i=0; i<namc; i++) if(namv[i]) { fprintf(stderr, "ar: %s not found\n", namv[i]); n++; } return(n);}morefil(){ register i, n; n = 0; for(i=0; i<namc; i++) if(namv[i]) n++; return(n);}cleanup(){ register i, f; truncate++; for(i=0; i<namc; i++) { file = namv[i]; if(file == 0) continue; namv[i] = 0; mesg('a'); f = stats(); if(f < 0) { fprintf(stderr, "ar: %s cannot open\n", file); continue; } movefil(f); } install();}install(){ register i; for(i=0; signum[i]; i++) signal(signum[i], SIG_IGN); if(af < 0) if(!flg['c'-'a']) fprintf(stderr, "ar: creating %s\n", arnam); close(af); af = creat(arnam, 0666); if(af < 0) { fprintf(stderr, "ar: cannot create %s\n", arnam); done(1); } if(tfname) { lseek(tf, 0l, 0); while((i = read(tf, buf, sizeof(buf))) > 0) if (write(af, buf, i) != i) wrerr(); } if(tf2name) { lseek(tf2, 0l, 0); while((i = read(tf2, buf, sizeof(buf))) > 0) if (write(af, buf, i) != i) wrerr(); } if(tf1name) { lseek(tf1, 0l, 0); while((i = read(tf1, buf, sizeof(buf))) > 0) if (write(af, buf, i) != i) wrerr(); }}/* * insert the file 'file' * into the temporary file */movefil(f){ char buf[sizeof(arbuf)+1]; sprintf(buf, "%-16s%-12ld%-6u%-6u%-8o%-10ld%-2s", trim(file), stbuf.st_mtime, (unsigned short) stbuf.st_uid, /* slr002 */ (unsigned short) stbuf.st_gid, /* slr002 */ stbuf.st_mode, stbuf.st_size, ARFMAG); strncpy((char *)&arbuf, buf, sizeof(arbuf)); larbuf.lar_size = stbuf.st_size; copyfil(f, tf, OODD+HEAD); close(f);}stats(){ register f; f = open(file, 0); if(f < 0) return(f); if(fstat(f, &stbuf) < 0) { close(f); return(-1); } return(f);}/* * copy next file * size given in arbuf */copyfil(fi, fo, flag){ register i, o; int pe; if(flag & HEAD) { for (i=sizeof(arbuf.ar_name)-1; i>=0; i--) { if (arbuf.ar_name[i]==' ') continue; else if (arbuf.ar_name[i]=='\0') arbuf.ar_name[i] = ' '; else break; } if (write(fo, (char *)&arbuf, sizeof arbuf) != sizeof arbuf) wrerr(); } pe = 0; while(larbuf.lar_size > 0) { i = o = sizeof(buf); if(larbuf.lar_size < i) { i = o = larbuf.lar_size; if(i&1) { buf[i] = '\n'; if(flag & IODD) i++; if(flag & OODD) o++; } } if(read(fi, buf, i) != i) pe++; if((flag & SKIP) == 0) if (write(fo, buf, o) != o) wrerr(); larbuf.lar_size -= sizeof(buf); } if(pe) phserr();}getdir(){ register char *cp; register i; i = read(af, (char *)&arbuf, sizeof arbuf); if(i != sizeof arbuf) { if(tf1name) { i = tf; tf = tf1; tf1 = i; } return(1); } if (strncmp(arbuf.ar_fmag, ARFMAG, sizeof(arbuf.ar_fmag))) { fprintf(stderr, "ar: malformed archive (at %ld)\n", lseek(af, 0L, 1)); done(1); } cp = arbuf.ar_name + sizeof(arbuf.ar_name); while (*--cp==' ') ; *++cp = '\0'; strncpy(name, arbuf.ar_name, sizeof(arbuf.ar_name)); file = name; strncpy(larbuf.lar_name, name, sizeof(larbuf.lar_name)); sscanf(arbuf.ar_date, "%ld", &larbuf.lar_date); sscanf(arbuf.ar_uid, "%hd", &larbuf.lar_uid); sscanf(arbuf.ar_gid, "%hd", &larbuf.lar_gid); sscanf(arbuf.ar_mode, "%ho", &larbuf.lar_mode); sscanf(arbuf.ar_size, "%ld", &larbuf.lar_size); return(0);}/* rcmd_match() * * This function is just for use by rcmd(). This does the same job * as calling match() which calls trim() but it leaves the * filename in the original state so it can be used later for the open.*/rcmd_match(){ register i; register char *p1, *p2; for(i=0; i<namc; i++) { if(namv[i] == 0) continue; /* trim the name to just the filename and compare only * 15 characters if needed. But, we need to leave * the full filename before returning to rcmd which will * use the filename to do the open. */ /* Strip trailing slashes */ for(p1 = namv[i]; *p1; p1++) ; while(p1 > namv[i]){ if(*--p1 != '/') break; *p1 = 0; } /* Find last component of path; do not zap the path */ p2 = namv[i]; for(p1 = namv[i]; *p1; p1++) if(*p1 == '/') p2 = p1+1; /* p2 now points to just the filename of the file spec. * We only compare the characters that will fit in the * space for ar's filenames. Later on (if this matches) * rcmd() will call movefil() which calls trim() and it * will really truncate the filename when we don't need the * full spec any more. */ if(strncmp(p2, file, (sizeof(arbuf.ar_name) - 1)) == 0) { file = namv[i]; namv[i] = 0; return(1); } } return(0);}match(){ register i; for(i=0; i<namc; i++) { if(namv[i] == 0) continue; if(strcmp(trim(namv[i]), file) == 0) { file = namv[i]; namv[i] = 0; return(1); } } return(0);}bamatch(){ register f; switch(bastate) { case 1: if(strcmp(file, ponam) != 0) return; bastate = 2; if(flg['a'-'a']) return; case 2: bastate = 0; if(flg['l'-'a']) tf1name = mktemp(tmp1name); else tf1name = tempnam(tdir,tmp1name); close(creat(tf1name, 0600)); f = open(tf1name, 2); if(f < 0) { fprintf(stderr, "ar: cannot create second temp\n"); return; } tf1 = tf; tf = f; }}phserr(){ fprintf(stderr, "ar: phase error on %s\n", file);}mesg(c){ if(flg['v'-'a']) if(c != 'c' || flg['v'-'a'] > 1) printf("%c - %s\n", c, file);}char *trim(s)char *s;{ register char *p1, *p2; /* Strip trailing slashes */ for(p1 = s; *p1; p1++) ; while(p1 > s) { if(*--p1 != '/') break; *p1 = 0; } /* Find last component of path; do not zap the path */ p2 = s; for(p1 = s; *p1; p1++) if(*p1 == '/') p2 = p1+1; /* * Truncate name if too long, only if we are doing an 'add' * type operation. We only allow 15 cause rest of ar * isn't smart enough to deal with non-null terminated * names. Need an exit status convention... * Need yet another new archive format... */ if (truncate && strlen(p2) > sizeof(arbuf.ar_name) - 1) { fprintf(stderr, "ar: filename %s truncated to ", p2); *(p2 + sizeof(arbuf.ar_name) - 1) = '\0'; fprintf(stderr, "%s\n", p2); } return(p2);}#define IFMT 060000#define ISARG 01000#define LARGE 010000#define SUID 04000#define SGID 02000#define ROWN 0400#define WOWN 0200#define XOWN 0100#define RGRP 040#define WGRP 020#define XGRP 010#define ROTH 04#define WOTH 02#define XOTH 01#define STXT 01000longt(){ register char *cp; pmode(); printf("%5d/%-5d", larbuf.lar_uid, larbuf.lar_gid); printf(" %6ld", larbuf.lar_size); cp = ctime(&larbuf.lar_date); printf(" %-12.12s %-4.4s ", cp+4, cp+20);}int m1[] = { 1, ROWN, 'r', '-' };int m2[] = { 1, WOWN, 'w', '-' };int m3[] = { 2, SUID, 's', XOWN, 'x', '-' };int m4[] = { 1, RGRP, 'r', '-' };int m5[] = { 1, WGRP, 'w', '-' };int m6[] = { 2, SGID, 's', XGRP, 'x', '-' };int m7[] = { 1, ROTH, 'r', '-' };int m8[] = { 1, WOTH, 'w', '-' };int m9[] = { 2, STXT, 't', XOTH, 'x', '-' };int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9};pmode(){ register int **mp; for (mp = &m[0]; mp < &m[9];) select(*mp++);}select(pairp)int *pairp;{ register int n, *ap; ap = pairp; n = *ap++; while (--n>=0 && (larbuf.lar_mode&*ap++)==0) ap++; putchar(*ap);}wrerr(){ perror("ar write error"); done(1);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?