#ifdef MSDOS /* { */ #include "grep_msd.h" #endif /* } */ char sccsID[] = "@(#) cp.c V2.0 Copyright Julian Stacey March 87.\n" ; #undef DEBUG /* UNIX - signal handling MISSING generally NOT NICE compared with real unix cp FUNCTION: copies one file to another file, or multiple files to a directory BUGS - self overwrite not checked - on unix we could major/minor device no + inode no, on msdos we must play with text strings .. too difficult to bother. - going from c to a: puts it in top directory, even if a is logged in as a sub directory FEATURES puts a new date stamp on file, whereas msdos leaves original date stamp (unix would put a new date stamp on). WIBNIS wont copy a single file to a directory -r for recursive could have mv functionality built in a la unix add file dating */ #include #include #include #include #include #ifdef unix /* { */ #include #endif /* } */ #define BUFSIZE 512 #define PMODE 0644 int ARGC ; char **ARGV ; char about = 0; /* 1 if we must jump about between source & target drives */ char out_drive[4], in_drive[4] ; extern char *strrchr(); extern int getcwd() ; #define CWD_LN 200 char in_dir[CWD_LN]; /* current working directory */ char out_dir[CWD_LN]; /* current working directory */ /* returns filename without path prefix */ char *namebaase(p) char *p ; { char *k; k = strrchr(p,'/'); if (k == (char *)0) return(p); else return(k+1); } main(argc,argv) int argc ; char **argv ; { struct stat input,output ; char *destin; /* destination directory */ char out_full[200] ; /* output full pathname */ int result = 0; /* JJ whats this for */ ARGV = argv ; #ifdef VSL /* { */ #include "../../include/vsl.h" #endif /* } */ ARGC = argc ; printf("%s\n",sccsID); if (argc < 3) { fprintf(stderr,"%s: insufficient parameters\n",*ARGV); exit(1); } /* get directory name */ while(--argc)argv++ ; destin = *argv ; /* In case destination directory is another drive (& not necessarily top directory in that drive */ if (isalpha(*destin) && *(destin +1) == ':') { about = 1; getcwd(in_dir,CWD_LN+2); #ifdef DEBUG printf("Source directory is %s\n",in_dir); #endif in_drive[0] = in_dir[0] ; in_drive[1] = in_dir[1] ; in_drive[2] = '\n' ; in_drive[3] = '\0' ; #ifdef DEBUG printf("Source drive is %s\n",in_drive); #endif out_drive[0] = *destin ; out_drive[1] = *(destin +1) ; out_drive[2] = '\n' ; out_drive[3] = '\0' ; #ifdef DEBUG printf("Target drive is %s\n",out_drive); #endif destin += 2 ; /* skip z: */ } #define STRADR & if (stat(destin,STRADR output)) { perror(*ARGV); exit(1); } if (!(output.st_mode & S_IFDIR) && (ARGC > 3) && !about) /* for some reason stat a: says not dir even when is, so ignore it by using `about` */ { printf("%s: Can not copy multiple files to non directory %s\n", *ARGV,destin); exit(1); } argc = ARGC - 1 ; argv = ARGV ; while (--argc) { argv++; result = 0; #ifdef DEBUG printf("Next source is %s\n",*argv); #endif if (stat(*argv,STRADR input)) { perror(*ARGV); exit(1); } if (input.st_mode & S_IFDIR) { fprintf(stderr, "%s: Skipping %s (directory).\n", *ARGV,*argv); result = 1; continue ; } (void) strcpy(out_full,destin); #ifdef DEBUG printf("base %s\n",namebaase(*argv)); #endif if ((output.st_mode & S_IFDIR) || about ) { if (*destin && destin[2]) (void) strcat(out_full,"/"); (void) strcat(out_full,namebaase(*argv)); } #ifdef DEBUG printf("a_to_b %s %s\n",*argv,out_full); #endif (void) a_to_b(*argv,out_full); if (chmod(out_full,(int)(input.st_mode))) { perror(*ARGV); exit(1); } } } a_to_b(name_a,name_b) char *name_a, *name_b; { int file1, file2, n; char buf[BUFSIZE]; if (about) (void)system(in_dir); (void)system("dir"); if ((file1 = open(name_a,O_RDONLY #ifdef MSDOS /* { */ | O_BINARY #endif /* } */ )) == -1) { fprintf(stderr,"%s: Failed to open %s\n",*ARGV,name_a); return(1); } if (about) /* change directory */ (void)system(out_dir); (void)system("dir"); if ((file2 = open(name_b, O_CREAT | O_TRUNC #ifdef MSDOS /* { */ | O_BINARY #endif /* } */ | O_WRONLY, S_IREAD | S_IWRITE) ) == -1) { fprintf(stderr,"%s: Failed to create %s\n",*ARGV,name_b); return(1); } while ( (n = read(file1,buf,BUFSIZE)) > 0) if (write(file2,buf,n) != n) { fprintf(stderr,"%s: Write error on %s\n",*ARGV,name_b); return(1); } if (close(file1)) { perror(*ARGV); exit(1); } if (close(file2)) { perror(*ARGV); exit(1); } return(0); }