/* CP.C Written by Leor Zolman, 3/18/82 Modified for v1.50 9/82 CP either copies a file from any disk and user area to any other disk and user area, or copies a list of files from the current disk and user area to some other disk and/or user area. Usage: A>cp [user#/][d:] [user#/][d:][] or A>cp [user#/][d:] . or A>cp { or } Note that the filename portion of the last argument is optional when only one file is being copied, but not allowed when multiple files are being copied. If files are being copied and the destination filename is omitted, CP attempts to copy to the disk and/or user number specified, leaving the filename(s) the same. For example, to copy *.com into user area 7: cp *.com 7/ If the entire second argument is a single dot (.), then the destin- ation is the CURRENT disk and user area. For example, to copy foo.c from user are 4 into the current user area: cp 4/foo.c . Link with: clink cp wildexp (or) l2 cp wildexp */ #include main(argc,argv) char **argv; { int i,j,c,loop; int fd1,fd2; int bufsects; unsigned bufsize; unsigned corebuf; char cur_disk; /* currently logged-in disk */ char destname[30]; char *lastarg; wildexp(&argc,&argv); cur_disk = 'A' + bdos(25); lastarg = argv[argc - 1]; if (argc < 3 || (argc > 3 && !((c = lastarg[strlen(lastarg)-1]) == '/' || c == ':'))) { printf("Usages: cp [u/][d:]filename [u/][d:]newname \n"); printf(" cp [u/][d:]filename u/ \n"); printf(" cp [u/][d:]filename d: \n"); printf(" cp [u/][d:]filename . \n"); printf(" cp { or or }\n"); exit(); } corebuf = sbrk(256); for (bufsize = 256; sbrk(256) != ERROR; bufsize += 256) ; bufsects = bufsize / SECSIZ; for (loop = 1; loop < argc-1; loop++) { if ((fd1 = open(argv[loop],0)) == ERROR) { printf("Can't open %s\n",argv[loop]); continue; /* go on to next one anyway. */ } strcpy(destname,lastarg); /* create output filename */ if ( (c = destname[strlen(destname) - 1])=='/' || c == ':' || !strcmp(destname,".")) { if (!strcmp(destname,".")) *destname = '\0'; for (i = strlen(argv[loop]) - 1; i >= 0; i--) if (argv[loop][i] == '/' || argv[loop][i] == ':') break; strcat(destname,&argv[loop][i+1]); } if ((fd2 = creat(destname)) == ERROR) { printf("Can't create %s\n",destname); printf("Assuming out of directory space and aborting.\n"); exit(); } printf("\t copying %s to %s...\n",argv[loop],destname); while (1) { if (kbhit()) getchar(); if (!(i = read(fd1,corebuf,bufsects))) break; if (i == ERROR) { printf("We have big read error, folks, tell(fd1) = %d:\n", tell(fd1)); puts(errmsg(errno())); exit(); } if (kbhit()) getchar(); if (write(fd2,corebuf,i) != i) { printf("Write error. Disk full?\n"); exit(); } } if (close(fd2) == ERROR) { printf("Can't close the output file.\7\n");; } fabort(fd1); } } /* Return true if the string arg is a filename prefixed by "nn/", where "nn" is a user number: */ int hasuno(str) char *str; { char c; int sum; sum = 0; if (!isdigit(*str)) return FALSE; while (isdigit(c = *str++)) sum = sum * 10 + c - '0'; return (c == '/') ? (sum >= 0 && sum < 32) : FALSE; }