| #include <stdio.h> | 
 | #include <string.h> | 
 | #include <errno.h> | 
 | #include <limits.h> | 
 | #include <sys/stat.h> | 
 | #include <sys/types.h> | 
 |  | 
 |  | 
 | int mv_main(int argc, char *argv[]) | 
 | { | 
 |     const char* dest; | 
 |     struct stat st; | 
 |     int i; | 
 |  | 
 |     if (argc < 3) { | 
 |         fprintf(stderr,"USAGE: %s <source...> <destination>\n", argv[0]); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     /* check if destination exists */ | 
 |     dest = argv[argc - 1]; | 
 |     if (stat(dest, &st)) { | 
 |         /* an error, unless the destination was missing */ | 
 |         if (errno != ENOENT) { | 
 |             fprintf(stderr, "failed on %s - %s\n", dest, strerror(errno)); | 
 |             return -1; | 
 |         } | 
 |         st.st_mode = 0; | 
 |     } | 
 |  | 
 |     for (i = 1; i < argc - 1; i++) { | 
 |         const char *source = argv[i]; | 
 |         char fullDest[PATH_MAX + 1 + PATH_MAX + 1]; | 
 |         /* assume we build "dest/source", and let rename() fail on pathsize */ | 
 |         if (strlen(dest) + 1 + strlen(source) + 1 > sizeof(fullDest)) { | 
 |             fprintf(stderr, "path too long\n"); | 
 |             return -1; | 
 |         } | 
 |         strcpy(fullDest, dest); | 
 |  | 
 |         /* if destination is a directory, concat the source file name */ | 
 |         if (S_ISDIR(st.st_mode)) { | 
 |             const char *fileName = strrchr(source, '/'); | 
 |             if (fullDest[strlen(fullDest)-1] != '/') { | 
 |                 strcat(fullDest, "/"); | 
 |             } | 
 |             strcat(fullDest, fileName ? fileName + 1 : source); | 
 |         } | 
 |  | 
 |         /* attempt to move it */ | 
 |         if (rename(source, fullDest)) { | 
 |             fprintf(stderr, "failed on '%s' - %s\n", source, strerror(errno)); | 
 |             return -1; | 
 |         } | 
 |     } | 
 |  | 
 |     return 0; | 
 | } | 
 |  |