/* cpio COMPILE: cc -O cpio.c -s -i -o cpio -lS
cpio -- copy file collections
#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)
struct stat Statb
, Xstatb
;
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];
register char *lastarg
, *fullp
;
if(argc
< 2 || argc
> 4) {
err("Usage: cpio -o[vB] <name-list >collection\n%s\n%s\n",
" cpio -i[drstuvB] [pattern] <collection",
" cpio -p[dlruv] [pattern] directory <name-list");
Pattern
= argc
== 2? "*": argv
[2];
if(access(lastarg
, 2) == -1) {
err("cannot write in <%s>\n", lastarg
);
strcpy(Fullname
, lastarg
);
if((Xstatb
.st_mode
&S_IFMT
) != S_IFDIR
)
Pattern
= argc
== 3? "*": argv
[2];
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");
Wp
= Dbuf
= malloc(Bufsize
);
if(Option
== PASS
&& Rename
) {
err("Pass and Rename cannot be used together");
if(mklong(Hdr
.h_filesize
) == 0L) {
bwrite(&Hdr
, HDRSIZE
+Hdr
.h_namesize
);
if((Ifile
= open(Hdr
.h_name
, 0)) < 0) {
err("<%s> ?\n", Hdr
.h_name
);
bwrite(&Hdr
, HDRSIZE
+Hdr
.h_namesize
);
for(filesz
=mklong(Hdr
.h_filesize
); filesz
>0; filesz
-= 512){
ct
= filesz
>512? 512: filesz
;
if(read(Ifile
, Buf
, ct
) < 0) {
err("Cannot read %s\n", Hdr
.h_name
);
strcpy(Hdr
.h_name
, "TRAILER!!!");
MKSHORT(Hdr
.h_filesize
, 0L);
Hdr
.h_namesize
= strlen("TRAILER!!!") + 1;
bwrite(&Hdr
, HDRSIZE
+Hdr
.h_namesize
);
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
;
if(write(Ofile
, 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
);
&& (Uid
== Statb
.st_uid
|| !Uid
)) {
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
);
set_time(Fullname
, Statb
.st_atime
, mklong(Hdr
.h_mtime
));
err("%D blocks\n", Blocks
* (Bufsize
>>9));
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
);
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
;
if(Hdr
.h_magic
!= MAGIC
) {
err("Out of phase--get help");
bread(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(!gmatch(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
&& (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((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(write(Output
, Dbuf
, 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
] = malloc(strlen(np
) + sizeof(struct ml
))) == 0) {
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("%7D ", mklong(Hdr
.h_filesize
));
U
.l
= mklong(Hdr
.h_mtime
);
strcpy(tbuf
, ctime(&U
.l
));
printf(" %s %s\n", &tbuf
[4], namep
);
return(gmatch(++s
, ++p
));
ok
|= (lc
<= scc
& scc
<= (cc
=p
[1]));
if(scc
) return(gmatch(++s
, ++p
));
if (gmatch(s
++,p
)) return(1);
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
)
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
, 128, dir
);
Pathend
= strlen(Fullname
);
Fullname
[Pathend
- 1] = '/';
char *p_save
= Name
, *n_save
= n
, *p_end
= 0;
static char dotdot
[]="../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../";
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) {
} else if(chdir(p_save
) == -1)