5748462 [rkeene@sledge /home/rkeene/devel/mooselinux-0.0.19/src]$ cat -n cp.c
  1 /*
  2     0280420002000: TODO: Add GNU options support.
  3     0280420002001: TODO: Fix support for the Preserve option (s[ug]id, access time)
  4 
  5 */
  6 
  7 #include <stdio.h>
  8 #include <unistd.h>
  9 #include <stdlib.h>
 10 #include <sys/types.h>
 11 #include <sys/stat.h>
 12 #include <fcntl.h>
 13 #include <string.h>
 14 #include "version.h"
 15 #include "cp.h"
 16 
 17 extern char *optarg;
 18 extern int optind, opterr, optopt;
 19 
 20 int cp_main (int argc, char **argv) {
 21     struct stat statinf;
 22     struct stat statinf2;
 23     char *destdir=NULL;
 24     char buff[4096];
 25     char read_buff[127];
 26     char option_force=0;
 27     char option_try_again=0;
 28     char option_interactive=0;
 29     char option_preserve=0;
 30     char option_recurse=0;
 31     char ch;
 32     int in_fd=-1, out_fd=-1;
 33     int i,x;
 34     int error_code=0;
 35 
 36     while ( (ch=getopt(argc,argv,"fipRr")) != -1) {
 37         switch (ch) {
 38             case 'f':
 39                 option_force=1;
 40                 break;
 41             case 'i':
 42                 option_interactive=1;
 43                 break;
 44             case 'p':
 45 
 46                 option_preserve=1;
 47                 break;
 48             case 'R':
 49             case 'r':
 50 /* TODO: Make recursive copying work. */
 51                 option_recurse=1;
 52                 break;
 53             default:
 54         }
 55     }
 56 
 57     if ((argc-optind)<2) {
 58         write(STDERR_FILENO, "cp: missing file argument\n", 26);
 59         return(-1);
 60     }
 61 
 62     statinf.st_mode=0;
 63     stat(argv[argc-1], &statinf);
 64     if (S_ISDIR(statinf.st_mode)) { 
 65         destdir=argv[argc-1];
 66     } else {
 67         if ((argc-optind)!=2) {
 68             write(STDERR_FILENO, "cp: when copying multiple files, last argument must be a directory\n", 67);
 69             return(-1);
 70         }
 71     }
 72 
 73     for (i=optind;i<argc-1;i++) {
 74         if (destdir==NULL) {
 75             strncpy(buff,argv[argc-1],sizeof(buff)-1);
 76         } else {
 77             sprintf(buff, "%s/%s", destdir, argv[i]);
 78         }
 79 
 80         if (option_interactive) {
 81             if (!access(buff,F_OK)) {
 82                 write(STDERR_FILENO, "cp: overwrite `", 15);
 83                 write(STDERR_FILENO, buff, strlen(buff));
 84                 write(STDERR_FILENO, "'? ", 3);
 85                 read(STDIN_FILENO, &read_buff, sizeof(read_buff));
 86                 if (read_buff[0]!='Y' && read_buff[0]!='y') goto loop;
 87             }
 88         }
 89 
 90         stat(argv[i], &statinf);
 91         stat(buff, &statinf2);
 92         if (statinf.st_ino==statinf2.st_ino) {
 93             write(STDERR_FILENO, "cp: `", 5);
 94             write(STDERR_FILENO, argv[i], strlen(argv[i]));
 95             write(STDERR_FILENO, "' and `", 7);
 96             write(STDERR_FILENO, buff, strlen(buff));
 97             write(STDERR_FILENO, "' are the same file\n", 20);
 98             error_code=-1;
 99             goto loop;
100         }
101 
102 top:
103         if ((out_fd=open(buff, O_WRONLY|O_CREAT|O_TRUNC, statinf.st_mode))<0) {
104             if (option_force && option_try_again==0) {
105                 option_try_again=1;
106                 unlink(buff);
107                 goto top;
108             }
109             option_try_again=0;
110             write(STDERR_FILENO, "cp: ", 4);
111             perror(buff);
112             error_code=-1;
113             goto loop;
114         }
115         if (option_preserve) {
116 #ifndef GO32
117             fchown(out_fd, statinf.st_uid, statinf.st_gid);
118 #endif
119         }
120         if ((in_fd=open(argv[i], O_RDONLY))<0) {
121             write(STDERR_FILENO, "cp: ", 4);
122             perror(argv[i]);
123             close(out_fd);
124             goto loop;
125         }
126         while (1) {
127             if ((x=read(in_fd, &buff, sizeof(buff)))<1) break;
128             write(out_fd, &buff, x);
129         }
130         close(in_fd);
131         close(out_fd);
132         out_fd=-1;
133 loop:
134     }
135 
136 
137     return(error_code);
138 }
5748463 [rkeene@sledge /home/rkeene/devel/mooselinux-0.0.19/src]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2000-06-21 13:24:03