📄 cpio.c
字号:
pwd(); while(gethdr()) { Ofile = ckname(Hdr.h_name)? openout(Hdr.h_name): 0; if(A_symlink) { namep = Hdr.h_name; if(!strncmp(namep,"./",2)) namep += 2; Cflag? readhdr(BBuf,(int)mklong(Hdr.h_filesize)): bread(Buf, (int)mklong(Hdr.h_filesize)); if(!Toc){ printd(stderr,"BBUF: %s\n namesize %d\n filesize %d\n", BBuf,Hdr.h_namesize,Hdr.h_filesize[1]); /* Clear out 'symstring' for it's entire length to ensure a clean slate. (from V24_QAR #533) */ strncpy(symstring, "", sizeof(symstring)); strncpy(symstring,Cflag? (char *)BBuf: (char *)Buf, (int)mklong(Hdr.h_filesize)); umask(oumask); if(symlink( symstring, Hdr.h_name) < 0) { perror("cpio"); fprintf(stderr,"Cannot create symlink %s\n", Hdr.h_name); umask(0); continue; } umask(0); if(Uid == 0) if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0) { fprintf(stderr,"Cannot chown <%s> (errno:%d)\n", namep, errno); } set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); } }else { for(filesz=mklong(Hdr.h_filesize); filesz>0; filesz-= CPIOBSZ){ ct = filesz>CPIOBSZ? CPIOBSZ: filesz; Cflag? readhdr(BBuf,ct): bread(Buf, ct); if(Ofile) { if(Swap) Cflag? swap(BBuf,ct): swap(Buf,ct); if(write(Ofile, Cflag? BBuf: (char *)Buf, ct) < 0) { fprintf(stderr,"Cannot write %s\n", Hdr.h_name); continue; } } } } if(Ofile) { close(Ofile); if(!A_symlink) if(!Pflag) if(chmod(Hdr.h_name, Hdr.h_mode) < 0) { fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Hdr.h_name, errno); } set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); } if(!Select) continue; if(Verbose) if(Toc) pentry(Hdr.h_name); else puts(Hdr.h_name); else if(Toc) puts(Hdr.h_name); } break; case PASS: /* move files around */ fullp = Fullname + strlen(Fullname); while(getname()) { if (A_directory && !Dir) fprintf(stderr,"Use `-d' option to copy <%s>\n",Hdr.h_name); if(!ckname(Hdr.h_name)) continue; i = 0; while(Hdr.h_name[i] == '/') i++; strcpy(fullp, &(Hdr.h_name[i])); if(A_symlink) { Symct=readlink(Hdr.h_name, Cflag? BBuf:(char *)Buf, Cflag? sizeof(BBuf): sizeof(Buf)); if(Symct < 0){ perror("cpio"); fprintf(stderr,"Cannot read %s\n", Hdr.h_name); continue; } Cptr = Cflag ? (char *)BBuf : (char *) Buf; Cptr[Symct]='\0'; umask(oumask); if(symlink(Cptr,Fullname) < 0) { perror("cpio"); fprintf(stderr,"Cannot create symlink %s-> %s\n", Fullname, BBuf); umask(0); continue; } umask(0); goto set; } if(Link && !A_directory && Dev == Statb.st_dev) { if(link(Hdr.h_name, Fullname) < 0) { /* missing dir.? */ unlink(Fullname); missdir(Fullname); if(link(Hdr.h_name, Fullname) < 0) { fprintf(stderr, "Cannot link <%s> & <%s>\n", Hdr.h_name, Fullname); continue; } } /* try creating (only twice) */ ans = 0; do { /* missing dir. ? */ if(link(Hdr.h_name, Fullname) < 0) { unlink(Fullname); ans += 1; }else { ans = 0; break; } }while(ans < 2 && missdir(Fullname) == 0); if(ans == 1) { fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", Fullname, errno); exit(0); }else if(ans == 2) { fprintf(stderr,"Cannot link <%s> & <%s>\n", Hdr.h_name, Fullname); exit(0); } if(!A_symlink) if(!Pflag) if(chmod(Hdr.h_name, Hdr.h_mode) < 0) { fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Hdr.h_name, errno); } set_time(Hdr.h_name, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); goto ckverbose; }#ifdef RT if (One_extent || Multi_extent) actsize(0);#endif if(!(Ofile = openout(Fullname))) continue; if((Ifile = open(Hdr.h_name, O_RDONLY)) < 0) { fprintf(stderr,"<%s> ?\n", Hdr.h_name); close(Ofile); continue; } filesz = Statb.st_size; for(; filesz > 0; filesz -= CPIOBSZ) { ct = filesz>CPIOBSZ? CPIOBSZ: filesz; if(read(Ifile, Buf, ct) < 0) { fprintf(stderr,"Cannot read %s\n", Hdr.h_name); break; } if(Ofile) if(write(Ofile, Buf, ct) < 0) { fprintf(stderr,"Cannot write %s\n", Hdr.h_name); break; }#ifndef u370 Blocks += ((ct + (BUFSIZE - 1)) / BUFSIZE);#else ++Blocks;#endif } close(Ifile);set: if( (Acc_time) && (!A_symlink) ) utimes(Hdr.h_name, &Statb.st_atime); if(Ofile) { close(Ofile); if(!A_symlink) if(!Pflag) if(chmod(Fullname, Hdr.h_mode) < 0) { fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", Fullname, errno); } set_time(Fullname, Statb.st_atime, mklong(Hdr.h_mtime));ckverbose: if(Verbose) puts(Fullname); } if(A_symlink) if(Verbose) puts(Fullname); } } /* print number of blocks actually copied */ if(Blocks) fprintf(stderr,"%ld blocks\n", Blocks * (Bufsize>>9)); /* Normal Exit */ exit(0);}usage(){ fprintf(stderr,"Usage: cpio -o[acvkBP] <name-list >collection\n%s\n%s\n", " cpio -i[bcdmrstuvfkBPS6] [pattern ...] <collection", " cpio -p[adlmuvkP] directory <name-list"); exit(2);}/* Set up header with filename and other file information */getname(){ register char *namep = Name; register ushort ftype; long tlong; for(;;) { if(gets(namep) == NULL) return 0; if(*namep == '.' && namep[1] == '/') namep += 2; strcpy(Hdr.h_name, namep); if(STAT(namep, &Statb) < 0) { fprintf(stderr,"< %s > ?\n", Hdr.h_name); continue; } ftype = Statb.st_mode & Filetype; if(Slink) A_symlink = (ftype == S_IFLNK); A_directory = (ftype == S_IFDIR); A_special = (ftype == S_IFBLK) || (ftype == S_IFCHR) || (ftype == S_IFIFO) || (ftype == S_IFSOCK);#ifdef RT A_special |= (ftype == S_IFREC); One_extent = (ftype == S_IF1EXT); Multi_extent = (ftype == S_IFEXT);#endif Hdr.h_magic = imagic; Hdr.h_namesize = strlen(Hdr.h_name) + 1; Hdr.h_uid = Statb.st_uid; Hdr.h_gid = Statb.st_gid; Hdr.h_dev = Statb.st_dev; /* * Maintain a list of devices seen by cpio. * NB: if "last_dev_seen == 0" then it's the first * device cpio has encountered on this invocation. */ if (last_dev_seen == 0) {#ifdef DEBUG if (devidx != 0) { fprintf(stderr, "cpio has problems with devidx\n"); }#endif devlist[devidx] = last_dev_seen = Hdr.h_dev; } if (Hdr.h_dev != last_dev_seen) { short i; for (i = devidx; i >= 0; i--) { if (Hdr.h_dev == devlist[i]) { devidx = i; break; } } /* * Wasn't found on search, and isn't the same as * "last" device, so it must be a new one. */ if (i < 0) { devlist[++devidx] = Hdr.h_dev; } last_dev_seen = devlist[devidx]; } /* * Fix for "inode too big" error. * There is no reason to use actual inode numbers of files * in the archive as this information cannot be used on * copy-in operations. So an artificial inode number is created * internally and used in the header in place of the "real" one. * A linked list of those inodes with multiple links is maintained * so the real inode can be "remembered" on subsequent accesses * (see routine match_ino()). */ Hdr.h_nlink = Statb.st_nlink; if (Hdr.h_nlink > 1) { match_ino(); } else { /* Set inode in header to our "internal" number */ Hdr.h_ino = next_ino(); } Hdr.h_mode = Statb.st_mode; MKSHORT(Hdr.h_mtime, Statb.st_mtime); tlong = (ftype == S_IFREG)? (long) Statb.st_size: 0L; if (A_symlink) tlong = (long) Statb.st_size;#ifdef RT if (One_extent || Multi_extent) tlong = Statb.st_size;#endif MKSHORT(Hdr.h_filesize, tlong); Hdr.h_rdev = Statb.st_rdev; if( Cflag ) bintochar(tlong); printd(stderr,"GETNAME\n\tname %s\n\tmagic %o \n\t namesize %d filesize %d\n", namep, Hdr.h_magic, Hdr.h_namesize,tlong); return 1; }}/* Convert Binary to ASCII for ASCII header write */bintochar(t) long t;{ sprintf(Chdr,"%.6o%.6ho%.6lo%.6ho%.6ho%.6ho%.6ho%.6ho%.11lo%.6ho%.11lo%s", imagic,Statb.st_dev,Statb.st_ino,Statb.st_mode, Statb.st_uid & 00000177777, Statb.st_gid & 00000177777, Statb.st_nlink,Statb.st_rdev & 00000177777, Statb.st_mtime,(short)strlen(Hdr.h_name)+1,t,Hdr.h_name);}/* Convert ASCII to binary for ASCII header read */chartobin(){ sscanf(Chdr,"%6ho%6ho%6lo%6ho%6ho%6ho%6ho%6ho%11lo%6ho%11lo", &Hdr.h_magic,&Hdr.h_dev,&Hdr.h_ino,&Hdr.h_mode,&Hdr.h_uid, &Hdr.h_gid,&Hdr.h_nlink,&Hdr.h_rdev,&Longtime,&Hdr.h_namesize, &Longfile); MKSHORT(Hdr.h_filesize, Longfile); MKSHORT(Hdr.h_mtime, Longtime);}/* Get File Header */gethdr(){ register ushort ftype; if (Cflag) { readhdr(Chdr,CHARS); chartobin(); } else { if (C_mode) { /* User specified compatability mode - use old header format */ bread(&O_Hdr, O_HDRSIZE); /* Place old header values into new header */ Hdr.h_magic = O_Hdr.h_magic; Hdr.h_dev = O_Hdr.h_dev; Hdr.h_ino = (ino_t)O_Hdr.h_ino; Hdr.h_mode = O_Hdr.h_mode; Hdr.h_uid = O_Hdr.h_uid; Hdr.h_gid = O_Hdr.h_gid; Hdr.h_nlink = O_Hdr.h_nlink; Hdr.h_rdev = O_Hdr.h_rdev; Hdr.h_namesize = O_Hdr.h_namesize; Hdr.h_mtime[0] = O_Hdr.h_mtime[0]; Hdr.h_mtime[1] = O_Hdr.h_mtime[1]; Hdr.h_filesize[0] = O_Hdr.h_filesize[0]; Hdr.h_filesize[1] = O_Hdr.h_filesize[1]; } else { /* Use normal, "new" header format */ bread(&Hdr, HDRSIZE); } } if(Hdr.h_magic != imagic) { fprintf(stderr,"Out of phase--get help\n"); exit(2); } if(Cflag) readhdr(Hdr.h_name, Hdr.h_namesize); else bread(Hdr.h_name, Hdr.h_namesize); printd(stderr,"GETHDR\n\tname %s\n\tmagic %o \n\t namesize %d filesize %d\n", Hdr.h_name, Hdr.h_magic, Hdr.h_namesize,mklong(Hdr.h_filesize)); if(EQ(Hdr.h_name, "TRAILER!!!")) return 0; ftype = Hdr.h_mode & Filetype; if(Slink) A_symlink = (ftype == S_IFLNK); A_directory = (ftype == S_IFDIR); A_special =(ftype == S_IFBLK) || (ftype == S_IFCHR) || (ftype == S_IFIFO) || (ftype == S_IFSOCK);#ifdef RT A_special |= (ftype == S_IFREC); One_extent = (ftype == S_IF1EXT); Multi_extent = (ftype == S_IFEXT); if (One_extent || Multi_extent) { Actual_size[0] = Hdr.h_filesize[0]; Actual_size[1] = Hdr.h_filesize[1]; if (Cflag) { readhdr(Chdr,CHARS); chartobin(); } else bread(&Hdr, HDRSIZE); if(Hdr.h_magic != imagic) { fprintf(stderr,"Out of phase--get RT help\n"); exit(2); } if(Cflag) readhdr(Hdr.h_name, Hdr.h_namesize); else bread(Hdr.h_name, Hdr.h_namesize); }#endif return 1;}/* Compare filename with pattern given on Command Line */ckname(namep)register char *namep;{ ++Select; if(fflag ^ !nmatch(namep, Pattern)) { Select = 0; return 0; } /* If Interactive Rename... */ if(Rename && !A_directory) { fprintf(Wtty, "Rename <%s>\n", namep); fflush(Wtty); fgets(namep, 128, Rtty); if(feof(Rtty)) exit(2); namep[strlen(namep) - 1] = '\0'; if(EQ(namep, "")) { printf("Skipped\n"); return 0; } } return !Toc;}/* Open files for writing, setup all neccessary information */openout(namep)register char *namep;{ register f; register char *np; int ans; if(!strncmp(namep, "./", 2)) namep += 2; np = namep; /* If a directory... */ if(A_directory) { if(!Dir || Rename || EQ(namep, ".") || EQ(namep, "..")) /* do not consider . or .. files */ return 0; if(STAT(namep, &Xstatb) == -1) { /* try creating (only twice) */ ans = 0; do { if(makdir(namep) != 0) { ans += 1; }else { ans = 0; break; } }while(ans < 2 && missdir(namep) == 0); if(ans == 1) { fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno); return(0); }else if(ans == 2) { fprintf(stderr,"Cannot create directory <%s> (errno:%d)\n", namep, errno); return(0); } }ret: if(!A_symlink) if(!Pflag) if(chmod(namep, Hdr.h_mode) < 0) { fprintf(stderr,"Cannot chmod <%s> (errno:%d)\n", namep, errno); } if(Uid == 0) if(chown(namep, Hdr.h_uid, Hdr.h_gid) < 0) { fprintf(stderr,"Cannot chown <%s> (errno:%d)\n", namep, errno); } set_time(namep, mklong(Hdr.h_mtime), mklong(Hdr.h_mtime)); return 0; } if(Hdr.h_nlink > 1) if(!postml(namep, np)) return 0; if(stat(namep, &Xstatb) == 0) { if(Uncond && !((!(Xstatb.st_mode & S_IWRITE) || A_special) && (Uid != 0))) { if(unlink(namep) < 0) { fprintf(stderr,"cannot unlink current <%s> (errno:%d)\n", namep, errno); } } if(!Uncond && (mklong(Hdr.h_mtime) <= Xstatb.st_mtime)) { /* There's a newer version of file on destination */ if(mklong(Hdr.h_mtime) < Xstatb.st_mtime) fprintf(stderr,"current <%s> newer\n", np); return 0; } } if(Option == PASS && Hdr.h_ino == Xstatb.st_ino && Hdr.h_dev == Xstatb.st_dev) { fprintf(stderr,"Attempt to pass file to self!\n"); exit(2); } if(A_symlink) return 0; if(A_special) { if (((Hdr.h_mode & Filetype) == S_IFSOCK) || ((Hdr.h_mode & Filetype) == S_IFIFO)) Hdr.h_rdev = 0; /* try creating (only twice) */ ans = 0; do { if(mknod(namep, Hdr.h_mode, Hdr.h_rdev) < 0) { ans += 1; }else { ans = 0; break; } }while(ans < 2 && missdir(np) == 0); if(ans == 1) { fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno); return(0); }else if(ans == 2) { fprintf(stderr,"Cannot mknod <%s> (errno:%d)\n", namep, errno); return(0); } goto ret; }#ifdef RT if(One_extent || Multi_extent) { /* try creating (only twice) */ ans = 0; do { if((f = falloc(namep, Hdr.h_mode, longword(Hdr.h_filesize[0]))) < 0) { ans += 1; }else { ans = 0; break; } }while(ans < 2 && missdir(np) == 0); if(ans == 1) { fprintf(stderr,"Cannot create directory for <%s> (errno:%d)\n", namep, errno); return(0); }else if(ans == 2) { fprintf(stderr,"Cannot create <%s> (errno:%d)\n", namep, errno); return(0); } if(filespace < longword(Hdr.h_filesize[0])){ fprintf(stderr,"Cannot create contiguous file <%s> proper size\n", namep); fprintf(stderr," <%s> will be created as a regular file\n", namep); if(unlink(Fullname) != 0) fprintf(stderr,"<%s> not removed\n", namep); Hdr.h_mode = (Hdr.h_mode & !S_IFMT) | S_IFREG; One_extent = Multi_extent = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -