/* Copyright (c) 1983 Regents of the University of California */
static char sccsid
[] = "@(#)cpio.c 4.2 (Berkeley) %G%";
/* cpio COMPILE: cc -O cpio.c -s -i -o cpio
cpio -- copy file collections
#define S_IFEXT 0120000 /* allocated by extents */
#define S_IF1EXT 0130000 /* one extent */
#define EQ(x,y) (strcmp(x,y)==0)
/* for VAX, Interdata, ... */
#define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];}
#define HDRSIZE ((sizeof Hdr)-256)
#define MERT 1 /* yes = 1 ; no = 0 */
struct stat Statb
, Xstatb
;
short Actual_size
[2]; /* MERT variable */
short Remove_mode
= 0007777;
union { long l
; short s
[2]; char c
[4]; } U
;
/* for VAX, Interdata, ... */
U
.s
[0] = v
[1], U
.s
[1] = v
[0];
U
.s
[0] = v
[0], U
.s
[1] = v
[1];
for(i
= 0; (i
+2) < argc
; ++i
)
if(access(argv
[2], 2) == -1) {
err("cannot write in <%s>\n", argv
[2]);
strcpy(Fullname
, argv
[2]);
if((Xstatb
.st_mode
&S_IFMT
) != S_IFDIR
)
Rtty
= fopen("/dev/tty", "r");
Wtty
= fopen("/dev/tty", "w");
if(Rtty
==NULL
|| Wtty
==NULL
) {
"Cannot rename (/dev/tty missing)\n");
err("Options must include o|i|p\n");
err("Swap flag is ignored with Cflag\n");
Wp
= Dbuf
= (short *)malloc(Bufsize
);
Cp
= Cbuf
= (char *)malloc(Bufsize
);
if(Option
== PASS
&& Rename
) {
err("Pass and Rename cannot be used together");
if( mklong(Hdr
.h_filesize
) == 0L) {
writehdr(Chdr
,CHARS
+Hdr
.h_namesize
);
bwrite(&Hdr
, HDRSIZE
+Hdr
.h_namesize
);
if( (MERT
) && (((Hdr
.h_mode
& Filetype
) == S_IF1EXT
)
|| ((Hdr
.h_mode
& Filetype
) == S_IFEXT
))) {
bwrite(&Hdr
, HDRSIZE
+Hdr
.h_namesize
);
if((Ifile
= open(Hdr
.h_name
, 0)) < 0) {
err("<%s> ?\n", Hdr
.h_name
);
writehdr(Chdr
,CHARS
+Hdr
.h_namesize
);
bwrite(&Hdr
, HDRSIZE
+Hdr
.h_namesize
);
if( (MERT
) && (((Hdr
.h_mode
& Filetype
) == S_IF1EXT
)
|| ((Hdr
.h_mode
& Filetype
) == S_IFEXT
))) {
bwrite(&Hdr
, HDRSIZE
+Hdr
.h_namesize
);
for(filesz
=mklong(Hdr
.h_filesize
); filesz
>0; filesz
-= 512){
ct
= filesz
>512? 512: filesz
;
if(read(Ifile
, Cflag
? BBuf
: (char *)Buf
, ct
) < 0) {
err("Cannot read %s\n", Hdr
.h_name
);
Cflag
? writehdr(BBuf
,ct
): bwrite(Buf
,ct
);
utime(Hdr
.h_name
, &Statb
.st_atime
);
strcpy(Hdr
.h_name
, "TRAILER!!!");
MKSHORT(Hdr
.h_filesize
, 0L);
Hdr
.h_namesize
= strlen("TRAILER!!!") + 1;
writehdr(Chdr
,CHARS
+Hdr
.h_namesize
);
bwrite(&Hdr
, HDRSIZE
+Hdr
.h_namesize
);
Cflag
? writehdr(Cbuf
, Bufsize
): bwrite(Dbuf
, Bufsize
);
Ofile
= ckname(Hdr
.h_name
)? openout(Hdr
.h_name
): 0;
for(filesz
=mklong(Hdr
.h_filesize
); filesz
>0; filesz
-= 512){
ct
= filesz
>512? 512: filesz
;
Cflag
? readhdr(BBuf
, ct
): bread(Buf
, ct
);
if(write(Ofile
, Cflag
? BBuf
: (char *)Buf
, ct
) < 0) {
err("Cannot write %s\n", Hdr
.h_name
);
set_time(Cd_name
, mklong(Hdr
.h_mtime
), mklong(Hdr
.h_mtime
));
fullp
= Fullname
+ strlen(Fullname
);
strcpy(fullp
, Hdr
.h_name
);
&& Dev
== Statb
.st_dev
) {
/* ??? && (Uid == Statb.st_uid || !Uid)) {*/
if(link(Hdr
.h_name
, Fullname
) < 0) { /* missing dir.? */
if(link(Hdr
.h_name
, Fullname
) < 0) {
"Cannot link <%s> & <%s>\n",
set_time(Hdr
.h_name
, mklong(Hdr
.h_mtime
), mklong(Hdr
.h_mtime
));
if(!(Ofile
= openout(Fullname
)))
if((Ifile
= open(Hdr
.h_name
, 0)) < 0) {
err("<%s> ?\n", Hdr
.h_name
);
for(; filesz
> 0; filesz
-= 512) {
ct
= filesz
>512? 512: filesz
;
if(read(Ifile
, Buf
, ct
) < 0) {
err("Cannot read %s\n", Hdr
.h_name
);
if(write(Ofile
, Buf
, ct
) < 0) {
err("Cannot write %s\n", Hdr
.h_name
);
utime(Hdr
.h_name
, &Statb
.st_atime
);
set_time(Fullname
, Statb
.st_atime
, mklong(Hdr
.h_mtime
));
err("%ld blocks\n", Blocks
* (Bufsize
>>9));
err("Usage: cpio -o[acvB] <name-list >collection\n%s\n%s\n",
" cpio -i[cdmrstuvB6] [pattern ...] <collection",
" cpio -p[adlmruv] directory <name-list");
register char *namep
= Name
;
if(*namep
== '.' && namep
[1] == '/')
strcpy(Hdr
.h_name
, namep
);
if(stat(namep
, &Statb
) < 0) {
err("< %s > ?\n", Hdr
.h_name
);
A_directory
= (Statb
.st_mode
& Filetype
) == S_IFDIR
;
A_special
= ((Statb
.st_mode
& Filetype
) == S_IFBLK
)
|| ((Statb
.st_mode
& Filetype
) == S_IFCHR
);
One_extent
= (Statb
.st_mode
& Filetype
) == S_IF1EXT
;
Multi_extent
= (Statb
.st_mode
& Filetype
) == S_IFEXT
;
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
;
Hdr
.h_ino
= Statb
.st_ino
;
Hdr
.h_mode
= Statb
.st_mode
;
MKSHORT(Hdr
.h_mtime
, Statb
.st_mtime
);
Hdr
.h_nlink
= Statb
.st_nlink
;
tlong
= Hdr
.h_mode
& S_IFREG
? Statb
.st_size
: 0L;
MKSHORT(Hdr
.h_filesize
, tlong
);
Hdr
.h_rdev
= Statb
.st_rdev
;
sprintf(Chdr
,"%.6o%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.6ho%.11lo%.6ho%.11lo%s",
MAGIC
,Statb
.st_dev
,Statb
.st_ino
,Statb
.st_mode
,Statb
.st_uid
,
Statb
.st_gid
,Statb
.st_nlink
,Statb
.st_rdev
& 00000177777,
Statb
.st_mtime
,(short)strlen(Hdr
.h_name
)+1,t
,Hdr
.h_name
);
sscanf(Chdr
,"%6o%6ho%6ho%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
,
MKSHORT(Hdr
.h_filesize
, Longfile
);
MKSHORT(Hdr
.h_mtime
, Longtime
);
if(Hdr
.h_magic
!= MAGIC
) {
err("Out of phase--get help\n");
bread(Hdr
.h_name
, Hdr
.h_namesize
);
readhdr(Hdr
.h_name
, Hdr
.h_namesize
);
swap(Hdr
.h_name
, Hdr
.h_namesize
);
if(EQ(Hdr
.h_name
, "TRAILER!!!"))
A_directory
= (Hdr
.h_mode
& Filetype
) == S_IFDIR
;
A_special
=((Hdr
.h_mode
& Filetype
) == S_IFBLK
)
|| ((Hdr
.h_mode
& Filetype
) == S_IFCHR
);
if( (MERT
) && (((Hdr
.h_mode
& Filetype
) == S_IF1EXT
)
|| ((Hdr
.h_mode
& Filetype
) == S_IFEXT
))) {
One_extent
= (Hdr
.h_mode
& Filetype
) == S_IF1EXT
;
Multi_extent
= (Hdr
.h_mode
& Filetype
) == S_IFEXT
;
Actual_size
[0] = Hdr
.h_filesize
[0];
Actual_size
[1] = Hdr
.h_filesize
[1];
if(Hdr
.h_magic
!= MAGIC
) {
err("Out of phase--get MERT help\n");
bread(Hdr
.h_name
, Hdr
.h_namesize
);
if(!nmatch(namep
, Pattern
)) {
if(Rename
&& !A_directory
) {
fprintf(Wtty
, "Rename <%s>\n", namep
);
namep
[strlen(namep
) - 1] = '\0';
if(!strncmp(namep
, "./", 2))
Cd_name
= namep
= cd(namep
);
|| stat(namep
, &Xstatb
) == 0)
chmod(namep
, Hdr
.h_mode
);
chown(namep
, Hdr
.h_uid
, Hdr
.h_gid
);
set_time(namep
, mklong(Hdr
.h_mtime
), mklong(Hdr
.h_mtime
));
if(mknod(namep
, Hdr
.h_mode
, Hdr
.h_rdev
) < 0) {
err("Cannot mknod <%s>\n", namep
);
if(stat(namep
, &Xstatb
) == 0) {
if(Uncond
&& !(Xstatb
.st_mode
& S_IWRITE
))
if(!Uncond
&& (mklong(Hdr
.h_mtime
) < Xstatb
.st_mtime
)) {
err("current <%s> newer\n", namep
);
&& Hdr
.h_ino
== Xstatb
.st_ino
&& Hdr
.h_dev
== Xstatb
.st_dev
) {
err("Attempt to pass file to self!\n");
if(One_extent
|| Multi_extent
) {
if((f
= falloc(namep
, Hdr
.h_mode
, Hdr
.h_filesize
[0].long_size
)) < 0) {
err("Cannot create <%s> (errno:%d)\n", namep
, errno
);
if(filespace
< Hdr
.h_filesize
[0].long_size
){
err("Cannot create contiguous file <%s> proper size\n", namep
);
err(" <%s> will be created as a regular file\n", namep
);
if(unlink(Fullname
) != 0)
err("<%s> not removed\n", namep
);
New_mode
= Hdr
.h_mode
& Remove_mode
;
New_mode
= New_mode
| S_IFREG
;
if((f
= creat(namep
, New_mode
)) < 0){
err("Cannot create <%s> (errno:%d)\n", namep
, errno
);
if(MERT
&& (One_extent
|| Multi_extent
))
if((f
= creat(namep
, Hdr
.h_mode
)) < 0) {
err("Cannot create <%s> (errno:%d)\n", namep
, errno
);
chown(namep
, Hdr
.h_uid
, Hdr
.h_gid
);
if(read(Input
, Dbuf
, Bufsize
)!=Bufsize
) {
Input
= chgreel(0, Input
);
if(read(Input
, Cbuf
, Bufsize
) != Bufsize
) {
Input
= chgreel(0, Input
);
if(write(Output
, Dbuf
, Bufsize
)<0) {
Output
= chgreel(1, Output
);
if(write(Output
,Cbuf
,Bufsize
)<0) {
Output
= chgreel(1, Output
);
register char *namep
, *np
;
for(i
= 0; i
< mlinks
; ++i
) {
if(mlinks
== LINKS
) break;
if(ml
[i
]->m_ino
==Hdr
.h_ino
&&
ml
[i
]->m_dev
==Hdr
.h_dev
) {
printf("%s linked to %s\n", ml
[i
]->m_name
,
Fullname
[Pathend
] = '\0';
strcat(Fullname
, ml
[i
]->m_name
);
if(link(mlp
, namep
) < 0) {
err("Cannot link <%s>&<%s>.\n",
set_time(namep
, mklong(Hdr
.h_mtime
), mklong(Hdr
.h_mtime
));
|| !(ml
[mlinks
] = (struct ml
*)malloc(strlen(np
) + 2 + sizeof(struct ml
)))) {
err("No memory for links\n");
ml
[mlinks
]->m_dev
= Hdr
.h_dev
;
ml
[mlinks
]->m_ino
= Hdr
.h_ino
;
strcpy(ml
[mlinks
]->m_name
, np
);
static short lastid
= -1;
static struct passwd
*pw
;
struct passwd
*getpwuid();
printf("%-7o", Hdr
.h_mode
& 0177777);
printf("%-6s", pw
->pw_name
);
if(pw
= getpwuid(Hdr
.h_uid
)) {
printf("%-6s", pw
->pw_name
);
printf("%-6d", Hdr
.h_uid
);
printf("%7ld ", mklong(Hdr
.h_filesize
));
U
.l
= mklong(Hdr
.h_mtime
);
strcpy(tbuf
, ctime(&U
.l
));
printf(" %s %s\n", &tbuf
[4], namep
);
if((**pat
== '!' && !gmatch(s
, *pat
+1))
register cc
, ok
, lc
, scc
;
return(gmatch(++s
, ++p
));
ok
|= (lc
<= scc
& scc
<= (cc
=p
[1]));
if(scc
) return(gmatch(++s
, ++p
));
if (gmatch(s
++,p
)) return(1);
while(wait(&status
) != pid
);
execl("/bin/mkdir", "mkdir", namep
, 0);
return ((status
>>8) & 0377)? 0: 1;
register union swp
{ short shortw
; char charv
[2]; } *buf
;
buf
->charv
[0] = buf
->charv
[1];
set_time(namep
, atime
, mtime
)
err("errno: %d, ", errno
);
err("Can't %s\n", x
? "write output": "read input");
if((statb
.st_mode
&S_IFMT
) != S_IFCHR
)
else if((statb
.st_mode
& (S_IFBLK
|S_IFREC
))==0)
if((statb
.st_mode
&S_IFMT
) != S_IFCHR
)
err("If you want to go on, type device/file name when ready\n");
devtty
= fopen("/dev/tty", "r");
str
[strlen(str
) - 1] = '\0';
if((f
= open(str
, x
? 1: 0)) < 0) {
for(np
= namep
; *np
; ++np
)
if(stat(namep
, &Xstatb
) == -1)
fprintf(stderr
, a
, b
, c
);
fgets(Fullname
, 256, dir
);
Pathend
= strlen(Fullname
);
Fullname
[Pathend
- 1] = '/';
char *p_save
= Name
, *n_save
= n
, *p_end
= 0;
static char dotdot
[]="../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../";
if(*n
== '/') /* don't try to chdir on full pathnames */
for(; *p
&& *n
== *p
; ++p
, ++n
) { /* whatever part of strings == */
p_save
= p
+1, n_save
= n
+1;
for(slashes
= 0; *p
; ++p
) { /* if prev is longer, chdir("..") */
slashes
= slashes
* 3 - 1;
p_end
= p
+1, n_save
= n
+1;
if(chdir(p_save
) == -1) {
err("Cannot chdir (no `d' option)\n");
} else if(chdir(p_save
) == -1)