home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 1999 May / pcp151c.iso / misc / src / install / commands.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-07  |  8.1 KB  |  418 lines

  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <sys/mount.h>
  7. #include <sys/stat.h>
  8. #include <sys/swap.h>
  9. #include <sys/sysmacros.h>
  10. #include <unistd.h>
  11. #include <zlib.h>
  12.  
  13. #include "commands.h"
  14. #include "fs.h"
  15. #include "idmap.h"
  16. #include "ls.h"
  17. #include "mkswap.h"
  18. #include "popt.h"
  19.  
  20. /* librpm.a provides this */
  21. int cpioInstallArchive(gzFile stream, void * mappings,
  22.                int numMappings, void * cb, void * cbData,
  23.                char ** failedFile);
  24.  
  25. static int copyfd(int to, int from);
  26.  
  27. static int copyfd(int to, int from) {
  28.     char buf[1024];
  29.     int size;
  30.  
  31.     while ((size = read(from, buf, sizeof(buf))) > 0) {
  32.     if (write(to, buf, size) != size) {
  33.         fprintf(stderr, "error writing output: %s\n", strerror(errno));
  34.         return 1;
  35.     }
  36.     }
  37.  
  38.     if (size < 0) {
  39.     fprintf(stderr, "error reading input: %s\n", strerror(errno));
  40.     return 1;
  41.     }
  42.  
  43.     return 0;
  44. }
  45.  
  46. static int catFile(char * filename) {
  47.     int fd;
  48.     int rc;
  49.  
  50.     fd = open(filename, O_RDONLY);
  51.     if (fd < 0) {
  52.     fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
  53.     return 1;
  54.     }
  55.  
  56.     rc = copyfd(1, fd);
  57.     close(fd);
  58.  
  59.     return rc;
  60. }
  61.  
  62. int catCommand(int argc, char ** argv) {
  63.     char ** argptr = argv + 1;
  64.     int rc;
  65.  
  66.     if (!*argptr) {
  67.     return copyfd(1, 0);
  68.     } else {
  69.     while (*argptr) {
  70.         rc = catFile(*argptr);
  71.         if (rc) return rc;
  72.         argptr++;
  73.     }
  74.     }
  75.  
  76.     return 0;
  77. }
  78.  
  79. int lsmodCommand(int argc, char ** argv) {
  80.     puts("Module:        #pages:  Used by:");
  81.     catFile("/proc/modules");
  82.  
  83.     return 0;
  84. }
  85.  
  86. #define MOUNT_USAGE fprintf(stderr, "usage: mount -t <fs> <device> <dir>\n" \
  87.             "       (if /dev/ is left off the device name, a " \
  88.             "temporary node will be created)\n")
  89.  
  90. int mountCommand(int argc, char ** argv) {
  91.     char * dev, * dir;
  92.     char * fs;
  93.  
  94.     if (argc < 2) {
  95.     return catFile("/proc/mounts");
  96.     } else if (argc == 3) {
  97.     if (strchr(argv[1], ':'))
  98.         fs = "nfs";
  99.     else
  100.         fs = "ext2";
  101.     dev = argv[1];
  102.     dir = argv[2];
  103.     } else if (argc != 5) {
  104.     MOUNT_USAGE;
  105.     return 1;
  106.     } else {
  107.     if (strcmp(argv[1], "-t")) {
  108.         MOUNT_USAGE;
  109.         return 1;
  110.     }
  111.     
  112.     fs = argv[2];
  113.     dev = argv[3];
  114.     dir = argv[4];
  115.  
  116.     }
  117.  
  118.     if (!strncmp(dev, "/dev/", 5) && access(dev, X_OK)) 
  119.     dev += 5;
  120.  
  121.     if (doMount(dev, dir, fs, 0, 1))
  122.     return 1;
  123.  
  124.     return 0;
  125. }
  126.  
  127. int umountCommand(int argc, char ** argv) {
  128.     if (argc != 2) {
  129.     fprintf(stderr, "umount expects a single argument\n");
  130.     return 1;
  131.     }
  132.  
  133.     if (umount(argv[1])) {
  134.     fprintf(stderr, "error unmounting %s: %s\n", argv[1], strerror(errno));
  135.     return 1;
  136.     }
  137.  
  138.     return 0;
  139. }
  140.  
  141. int mkdirCommand(int argc, char ** argv) {
  142.     char ** argptr = argv + 1;
  143.  
  144.     if (argc < 2) {
  145.     fprintf(stderr, "umount expects one or more arguments\n");
  146.     return 1;
  147.     }
  148.  
  149.     while (*argptr) {
  150.     if (mkdir(*argptr, 0755)) {
  151.         fprintf(stderr, "error creating directory %s: %s\n", *argptr,
  152.             strerror(errno));
  153.         return 1;
  154.     }
  155.  
  156.     argptr++;
  157.     }
  158.  
  159.     return 0;
  160. }
  161.  
  162. int mknodCommand(int argc, char ** argv) {
  163.     int major, minor;
  164.     char * path;
  165.     int mode = 0600;
  166.     char *end;
  167.  
  168.     if (argc != 5 && argc != 2) {
  169.     fprintf(stderr, "usage: mknod <path> [b|c] <major> <minor> or mknod <path>\n");
  170.     return 1;
  171.     }
  172.  
  173.     path = argv[1];
  174.  
  175.     if (argc == 2) {
  176.     end = path + strlen(path) - 1;
  177.     while (end > path && *end != '/') end--;
  178.  
  179.     if (devMakeInode(end, path)) {
  180.         return 1;
  181.     }
  182.  
  183.     return 0;
  184.     }
  185.  
  186.     if (!strcmp(argv[2], "b")) 
  187.     mode |= S_IFBLK;
  188.     else if (!strcmp(argv[2], "c"))
  189.     mode |= S_IFCHR;
  190.     else {
  191.     fprintf(stderr, "unknown node type %s\n", argv[2]);
  192.     return 1;
  193.     } 
  194.  
  195.     major = strtol(argv[3], &end, 0);
  196.     if (*end) {
  197.     fprintf(stderr, "bad major number %s\n", argv[3]);
  198.     return 1;
  199.     }
  200.  
  201.     minor = strtol(argv[4], &end, 0);
  202.     if (*end) {
  203.     fprintf(stderr, "bad minor number %s\n", argv[4]);
  204.     return 1;
  205.     }
  206.  
  207.     if (mknod(path, mode, makedev(major, minor))) {
  208.     fprintf(stderr, "mknod failed: %s\n", strerror(errno));
  209.     return 1;
  210.     }
  211.  
  212.     return 0;
  213. }
  214.  
  215. int lnCommand(int argc, char ** argv) {
  216.     char ** argptr = argv + 1;
  217.     int force = 0, soft = 0;
  218.     int rc;
  219.  
  220.     while (*argptr && **argptr == '-') {
  221.     if (!strcmp(*argptr, "-f"))
  222.        force = 1;
  223.     else if (!strcmp(*argptr, "-s"))
  224.        soft = 1;
  225.     else if (!strcmp(*argptr, "-fs") || !strcmp(*argptr, "-sf"))
  226.        force = soft = 1;
  227.     else {
  228.        fprintf(stderr, "ln: unknown argument %s\n", *argptr);
  229.        return 1;
  230.     }
  231.  
  232.     argptr++;
  233.     }
  234.  
  235.     if (!*argptr || !(*argptr + 1) || *(argptr + 2)) {
  236.     fprintf(stderr, "ln requires exactly two filenames\n");
  237.     return 1;
  238.     }
  239.  
  240.     if (force) unlink(*(argptr + 1));
  241.     if (soft)
  242.     rc = symlink(*argptr, *(argptr + 1));
  243.     else
  244.     rc = link(*argptr, *(argptr + 1));
  245.  
  246.     if (rc) {
  247.     perror("error");
  248.     return 1;
  249.     }
  250.  
  251.     return 0;
  252. }
  253.  
  254. int rmCommand(int argc, char ** argv) {
  255.     char ** argptr = argv + 1;
  256.  
  257.     if (argc < 2) {
  258.     fprintf(stderr, "rm expects one or more arguments "
  259.         "(no flags are supported");
  260.     return 1;
  261.     }
  262.  
  263.     while (*argptr) {
  264.     if (unlink(*argptr)) {
  265.         fprintf(stderr, "unlink of %s failed: %s\n", *argptr, 
  266.             strerror(errno));
  267.         return 1;
  268.     }
  269.  
  270.     argptr++;
  271.     }
  272.  
  273.     return 0;
  274. }
  275.  
  276. int chmodCommand(int argc, char ** argv) {
  277.     char ** argptr = argv + 2;
  278.     int mode;
  279.     char * end;
  280.  
  281.     if (argc < 3) {
  282.     fprintf(stderr, "usage: chmod <mode> <one or files>\n");
  283.     return 1;
  284.     }
  285.  
  286.     mode = strtol(argv[1], &end, 8);
  287.     if (*end) {
  288.     fprintf(stderr, "illegal mode %s\n", argv[1]);
  289.     return 1;
  290.     }
  291.  
  292.     while (*argptr) {
  293.     if (chmod(*argptr, mode)) {
  294.         fprintf(stderr, "error in chmod of %s to 0%o: %s\n", *argptr,
  295.             mode, strerror(errno));
  296.         return 1;
  297.     }
  298.  
  299.     argptr++;
  300.     }
  301.  
  302.     return 0;
  303. }
  304.  
  305. int mkswapCommand(int argc, char ** argv) {
  306.     if (argc != 2) {
  307.     fprintf(stderr, "mkswap <device>");
  308.     return 1;
  309.     }
  310.  
  311.     if (!strncmp(argv[0], "/dev/", 5) && access(argv[0], X_OK)) 
  312.     argv[1] += 5;
  313.  
  314.     enableswap(argv[1], 0, 0);
  315.  
  316.     return 0;
  317. }
  318.  
  319. int swaponCommand(int argc, char ** argv) {
  320.     if (argc != 2) {
  321.     fprintf(stderr, "swapon <file>");
  322.     return 1;
  323.     }
  324.  
  325.     if (swapon(argv[1], 0)) {
  326.     perror("swapon:");
  327.     return 1;
  328.     }
  329.  
  330.     return 0;
  331. }
  332.  
  333. int uncpioCommand(int argc, char ** argv) {
  334.     int rc;
  335.     char * fail;
  336.  
  337.     if (argc != 1) {
  338.     fprintf(stderr, "uncpio reads from stdin");
  339.     return 1;
  340.     }
  341.  
  342.     rc = cpioInstallArchive(gzdopen(0, "r"), NULL, 0, NULL, NULL, &fail);
  343.     return (rc != 0);
  344. }
  345.  
  346. int lsCommand(int argc, char ** argv) {
  347.     poptContext optCon;
  348.     int flags = 0;
  349.     int rc;
  350.     char path[1024];
  351.     struct poptOption ksOptions[] = {
  352.     { NULL, 'l', 0, NULL, 'l' },
  353.     { NULL, 'C', 0, NULL, 'C' },
  354.     { NULL, 'd', 0, NULL, 'd' },
  355.     { NULL, 'g', 0, NULL, 'g' },
  356.     { NULL, 'n', 0, NULL, 'n' },
  357.     { NULL, 'p', 0, NULL, 'p' },
  358.     { NULL, 'a', 0, NULL, 'a' },
  359.     { NULL, 'L', 0, NULL, 'L' },
  360.     { NULL, 'f', 0, NULL, 'f' },
  361.     { NULL, 'r', 0, NULL, 'r' },
  362.     { NULL, 't', 0, NULL, 't' },
  363.     { NULL, 'S', 0, NULL, 'S' },
  364.     { NULL, 'R', 0, NULL, 'R' },
  365.     { NULL, '\0', 0, NULL, '\0' }
  366.     };
  367.  
  368.     optCon = poptGetContext(NULL, argc, argv, ksOptions, 0);
  369.     if (isatty(1)) flags |= SENDDIR_MULTICOLUMN;
  370.  
  371.     while ((rc = poptGetNextOpt(optCon)) >= 0) {
  372.     switch (rc) {
  373.       case 'l':
  374.         flags |= SENDDIR_LONG; flags &= ~SENDDIR_MULTICOLUMN;
  375.         break;
  376.       case 'C':
  377.         flags |= SENDDIR_MULTICOLUMN; flags &= ~SENDDIR_LONG;
  378.         break;
  379.       case 'd': flags |= SENDDIR_SIMPLEDIRS;     break;
  380.       case 'g': /* ignored */             break;
  381.       case 'n': flags |= SENDDIR_NUMIDS;         break;
  382.       case 'p': case 'F': flags |= SENDDIR_FILETYPE; break;
  383.       case 'a': flags |= SENDDIR_ALL;         break;
  384.       case 'L': flags |= SENDDIR_FOLLOWLINKS;     break;
  385.       case 'f': flags |= SENDDIR_SORTNONE;         break;
  386.       case 'r': flags |= SENDDIR_SORTREVERSE;     break;
  387.       case 't': flags |= SENDDIR_SORTMTIME;     break;
  388.       case 'S': flags |= SENDDIR_SORTSIZE;         break;
  389.       case 'R': flags |= SENDDIR_RECURSE;         break;
  390.     }
  391.     }
  392.  
  393.     getcwd(path, 1000);
  394.  
  395.     if (rc < -1) {
  396.     fprintf(stderr, "argument error: %s %s",
  397.            poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
  398.            poptStrerror(rc));
  399.     } else {
  400.     idInit();
  401.  
  402.     argv = poptGetArgs(optCon);
  403.     if (argv) {
  404.         while (*argv) {
  405.         if (argv[0][0] == '/')
  406.             listFiles("", *argv, flags);
  407.         else
  408.             listFiles(path, *argv, flags);
  409.         argv++;
  410.         }
  411.     } else {
  412.         listFiles(path, "", flags);
  413.     }
  414.     }
  415.  
  416.     return 0;
  417. }
  418.