13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier 4*219b2ee8SDavid du Colombier #define DEFB (8*1024) 53e12c5d1SDavid du Colombier 63e12c5d1SDavid du Colombier void copy(char *from, char *to, int todir); 73e12c5d1SDavid du Colombier void copy1(int fdf, int fdt, char *from, char *to); 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier void 103e12c5d1SDavid du Colombier main(int argc, char *argv[]) 113e12c5d1SDavid du Colombier { 123e12c5d1SDavid du Colombier Dir dirb; 133e12c5d1SDavid du Colombier int todir, i; 143e12c5d1SDavid du Colombier 15*219b2ee8SDavid du Colombier if(argc<3){ 16*219b2ee8SDavid du Colombier fprint(2, "usage:\tcp fromfile tofile\n"); 17*219b2ee8SDavid du Colombier fprint(2, "\tcp fromfile ... todir\n"); 183e12c5d1SDavid du Colombier exits("usage"); 193e12c5d1SDavid du Colombier } 203e12c5d1SDavid du Colombier todir=0; 21*219b2ee8SDavid du Colombier if(dirstat(argv[argc-1], &dirb)==0 && (dirb.mode&CHDIR)) 223e12c5d1SDavid du Colombier todir=1; 23*219b2ee8SDavid du Colombier if(argc>3 && !todir){ 243e12c5d1SDavid du Colombier fprint(2, "cp: %s not a directory\n", argv[argc-1]); 253e12c5d1SDavid du Colombier exits("bad usage"); 263e12c5d1SDavid du Colombier } 27*219b2ee8SDavid du Colombier for(i=1; i<argc-1; i++) 283e12c5d1SDavid du Colombier copy(argv[i], argv[argc-1], todir); 293e12c5d1SDavid du Colombier exits(0); 303e12c5d1SDavid du Colombier } 313e12c5d1SDavid du Colombier 323e12c5d1SDavid du Colombier void 333e12c5d1SDavid du Colombier copy(char *from, char *to, int todir) 343e12c5d1SDavid du Colombier { 353e12c5d1SDavid du Colombier Dir dirb, dirt; 363e12c5d1SDavid du Colombier char name[256]; 373e12c5d1SDavid du Colombier int fdf, fdt; 383e12c5d1SDavid du Colombier 393e12c5d1SDavid du Colombier if(todir){ 403e12c5d1SDavid du Colombier char *s, *elem; 413e12c5d1SDavid du Colombier elem=s=from; 423e12c5d1SDavid du Colombier while(*s++) 433e12c5d1SDavid du Colombier if(s[-1]=='/') 443e12c5d1SDavid du Colombier elem=s; 453e12c5d1SDavid du Colombier sprint(name, "%s/%s", to, elem); 463e12c5d1SDavid du Colombier to=name; 473e12c5d1SDavid du Colombier } 483e12c5d1SDavid du Colombier if(dirstat(from, &dirb)!=0){ 49*219b2ee8SDavid du Colombier fprint(2,"cp: can't stat %s: %r\n", from); 503e12c5d1SDavid du Colombier return; 513e12c5d1SDavid du Colombier } 52*219b2ee8SDavid du Colombier if(dirb.mode&CHDIR){ 533e12c5d1SDavid du Colombier fprint(2, "cp: %s is a directory\n", from); 543e12c5d1SDavid du Colombier return; 553e12c5d1SDavid du Colombier } 563e12c5d1SDavid du Colombier dirb.mode &= 0777; 573e12c5d1SDavid du Colombier if(dirstat(to, &dirt)==0) 583e12c5d1SDavid du Colombier if(dirb.qid.path==dirt.qid.path && dirb.qid.vers==dirt.qid.vers) 593e12c5d1SDavid du Colombier if(dirb.dev==dirt.dev && dirb.type==dirt.type){ 60*219b2ee8SDavid du Colombier fprint(2, "cp: %s and %s are the same file\n", from, to); 613e12c5d1SDavid du Colombier return; 623e12c5d1SDavid du Colombier } 633e12c5d1SDavid du Colombier fdf=open(from, OREAD); 643e12c5d1SDavid du Colombier if(fdf<0){ 65*219b2ee8SDavid du Colombier fprint(2, "cp: can't open %s: %r\n", from); 663e12c5d1SDavid du Colombier return; 673e12c5d1SDavid du Colombier } 683e12c5d1SDavid du Colombier fdt=create(to, OWRITE, dirb.mode); 693e12c5d1SDavid du Colombier if(fdt<0){ 70*219b2ee8SDavid du Colombier fprint(2, "cp: can't create %s: %r\n", to); 713e12c5d1SDavid du Colombier close(fdf); 723e12c5d1SDavid du Colombier return; 733e12c5d1SDavid du Colombier } 743e12c5d1SDavid du Colombier copy1(fdf, fdt, from, to); 753e12c5d1SDavid du Colombier close(fdf); 763e12c5d1SDavid du Colombier close(fdt); 773e12c5d1SDavid du Colombier } 783e12c5d1SDavid du Colombier 793e12c5d1SDavid du Colombier void 803e12c5d1SDavid du Colombier copy1(int fdf, int fdt, char *from, char *to) 813e12c5d1SDavid du Colombier { 82*219b2ee8SDavid du Colombier char *buf; 83*219b2ee8SDavid du Colombier long n, n1, rcount; 843e12c5d1SDavid du Colombier 85*219b2ee8SDavid du Colombier buf = malloc(DEFB); 86*219b2ee8SDavid du Colombier /* clear any residual error */ 87*219b2ee8SDavid du Colombier memset(buf, 0, ERRLEN); 88*219b2ee8SDavid du Colombier errstr(buf); 893e12c5d1SDavid du Colombier for(rcount=0;; rcount++) { 90*219b2ee8SDavid du Colombier n = read(fdf, buf, DEFB); 913e12c5d1SDavid du Colombier if(n <= 0) 923e12c5d1SDavid du Colombier break; 933e12c5d1SDavid du Colombier n1 = write(fdt, buf, n); 943e12c5d1SDavid du Colombier if(n1 != n) { 95*219b2ee8SDavid du Colombier fprint(2, "cp: error writing %s: %r\n", to); 963e12c5d1SDavid du Colombier break; 973e12c5d1SDavid du Colombier } 983e12c5d1SDavid du Colombier } 99*219b2ee8SDavid du Colombier if(n < 0) 100*219b2ee8SDavid du Colombier fprint(2, "cp: error reading %s: %r\n", from); 101*219b2ee8SDavid du Colombier free(buf); 1023e12c5d1SDavid du Colombier } 103