#include #include #include #include #include #include #include #include #include #include #include #include #include #include "../isys/imount.h" #include "../isys/isys.h" #include "commands.h" #include "idmap.h" #include "ls.h" #include "popt.h" #include "../isys/cpio.h" static int copyfd(int to, int from); static int copyfd(int to, int from) { char buf[1024]; int size; while ((size = read(from, buf, sizeof(buf))) > 0) { if (write(to, buf, size) != size) { fprintf(stderr, "error writing output: %s\n", strerror(errno)); return 1; } } if (size < 0) { fprintf(stderr, "error reading input: %s\n", strerror(errno)); return 1; } return 0; } static int catFile(char * filename) { int fd; int rc; fd = open(filename, O_RDONLY); if (fd < 0) { fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno)); return 1; } rc = copyfd(1, fd); close(fd); return rc; } int catCommand(int argc, char ** argv) { char ** argptr = argv + 1; int rc; if (!*argptr) { return copyfd(1, 0); } else { while (*argptr) { rc = catFile(*argptr); if (rc) return rc; argptr++; } } return 0; } int lsmodCommand(int argc, char ** argv) { puts("Module: #pages: Used by:"); catFile("/proc/modules"); return 0; } #define MOUNT_USAGE fprintf(stderr, "usage: mount -t \n" \ " (if /dev/ is left off the device name, a " \ "temporary node will be created)\n") int mountCommand(int argc, char ** argv) { char * dev, * dir; char * fs, * buf; if (argc < 2) { return catFile("/proc/mounts"); } else if (argc == 3) { if (strchr(argv[1], ':')) fs = "nfs"; else fs = "ext2"; dev = argv[1]; dir = argv[2]; } else if (argc != 5) { MOUNT_USAGE; return 1; } else { if (strcmp(argv[1], "-t")) { MOUNT_USAGE; return 1; } fs = argv[2]; dev = argv[3]; dir = argv[4]; } if (!strncmp(dev, "/dev/", 5) && access(dev, X_OK)) { dev += 5; buf = alloca(strlen(dev) + 10); sprintf(buf, "/tmp/%s", dev); devMakeInode(dev, buf); dev = buf; } if (doPwMount(dev, dir, fs, 0, 1, NULL, NULL)) return 1; return 0; } int umountCommand(int argc, char ** argv) { if (argc != 2) { fprintf(stderr, "umount expects a single argument\n"); return 1; } if (umount(argv[1])) { fprintf(stderr, "error unmounting %s: %s\n", argv[1], strerror(errno)); return 1; } return 0; } int mkdirCommand(int argc, char ** argv) { char ** argptr = argv + 1; if (argc < 2) { fprintf(stderr, "umount expects one or more arguments\n"); return 1; } while (*argptr) { if (mkdir(*argptr, 0755)) { fprintf(stderr, "error creating directory %s: %s\n", *argptr, strerror(errno)); return 1; } argptr++; } return 0; } int mknodCommand(int argc, char ** argv) { int major, minor; char * path; int mode = 0600; char *end; if (argc != 5 && argc != 2) { fprintf(stderr, "usage: mknod [b|c] or mknod \n"); return 1; } path = argv[1]; if (argc == 2) { end = path + strlen(path) - 1; while (end > path && *end != '/') end--; if (*end == '/') end++; if (devMakeInode(end, path)) { return 1; } return 0; } if (!strcmp(argv[2], "b")) mode |= S_IFBLK; else if (!strcmp(argv[2], "c")) mode |= S_IFCHR; else { fprintf(stderr, "unknown node type %s\n", argv[2]); return 1; } major = strtol(argv[3], &end, 0); if (*end) { fprintf(stderr, "bad major number %s\n", argv[3]); return 1; } minor = strtol(argv[4], &end, 0); if (*end) { fprintf(stderr, "bad minor number %s\n", argv[4]); return 1; } if (mknod(path, mode, makedev(major, minor))) { fprintf(stderr, "mknod failed: %s\n", strerror(errno)); return 1; } return 0; } int lnCommand(int argc, char ** argv) { char ** argptr = argv + 1; int force = 0, soft = 0; int rc; while (*argptr && **argptr == '-') { if (!strcmp(*argptr, "-f")) force = 1; else if (!strcmp(*argptr, "-s")) soft = 1; else if (!strcmp(*argptr, "-fs") || !strcmp(*argptr, "-sf")) force = soft = 1; else { fprintf(stderr, "ln: unknown argument %s\n", *argptr); return 1; } argptr++; } if (!*argptr || !(*argptr + 1) || *(argptr + 2)) { fprintf(stderr, "ln requires exactly two filenames\n"); return 1; } if (force) unlink(*(argptr + 1)); if (soft) rc = symlink(*argptr, *(argptr + 1)); else rc = link(*argptr, *(argptr + 1)); if (rc) { perror("error"); return 1; } return 0; } int rmCommand(int argc, char ** argv) { char ** argptr = argv + 1; if (argc < 2) { fprintf(stderr, "rm expects one or more arguments " "(no flags are supported"); return 1; } while (*argptr) { if (unlink(*argptr)) { fprintf(stderr, "unlink of %s failed: %s\n", *argptr, strerror(errno)); return 1; } argptr++; } return 0; } int chmodCommand(int argc, char ** argv) { char ** argptr = argv + 2; int mode; char * end; if (argc < 3) { fprintf(stderr, "usage: chmod \n"); return 1; } mode = strtol(argv[1], &end, 8); if (*end) { fprintf(stderr, "illegal mode %s\n", argv[1]); return 1; } while (*argptr) { if (chmod(*argptr, mode)) { fprintf(stderr, "error in chmod of %s to 0%o: %s\n", *argptr, mode, strerror(errno)); return 1; } argptr++; } return 0; } #define CPIOERR_CHECK_ERRNO 0x00008000 int uncpioCommand(int argc, char ** argv) { int rc; char * fail; CFD_t cfd; if (argc != 1) { fprintf(stderr, "uncpio reads from stdin"); return 1; } cfd.cpioPos = 0; cfd.cpioIoType = cpioIoTypeGzFd; cfd.cpioGzFd = gzdFdopen(fdDup(0), "r"); rc = cpioInstallArchive(&cfd, NULL, 0, NULL, NULL, &fail); if (rc) { fprintf(stderr, "cpio failed on %s: ", fail); if (rc & CPIOERR_CHECK_ERRNO) fprintf(stderr, "%s\n", strerror(errno)); else fprintf(stderr, "(internal)\n"); } return (rc != 0); } int dfCommand(int argc, char ** argv) { int fd; char * buf = alloca(2048); char * end; struct statfs fs; int i; int badjust; if ((fd = open("/proc/mounts", O_RDONLY)) < 0) { perror("failed to open /proc/mounts"); return 1; } i = read(fd, buf, 2048); buf[i] = '\0'; printf("%-30s %-10s %-10s %-10s\n", "Mount Point", "1k-blocks", "Used", "Available"); while (buf && *buf) { end = strchr(buf, ' '); if (!end) return 1; buf = end + 1; end = strchr(buf, ' '); if (!end) return 1; *end = '\0'; statfs(buf, &fs); badjust = fs.f_bsize / 1024; printf("%-30s %-10d %-10d %-10d\n", buf, fs.f_blocks * badjust, (fs.f_blocks - fs.f_bfree) * badjust, fs.f_bfree * badjust); buf = strchr(end + 1, '\n'); if (buf) buf++; } return 0; } int lsCommand(int argc, char ** argv) { poptContext optCon; int flags = 0; int rc; char path[1024]; struct poptOption ksOptions[] = { { NULL, 'l', 0, NULL, 'l' }, { NULL, 'C', 0, NULL, 'C' }, { NULL, 'd', 0, NULL, 'd' }, { NULL, 'g', 0, NULL, 'g' }, { NULL, 'n', 0, NULL, 'n' }, { NULL, 'p', 0, NULL, 'p' }, { NULL, 'a', 0, NULL, 'a' }, { NULL, 'L', 0, NULL, 'L' }, { NULL, 'f', 0, NULL, 'f' }, { NULL, 'r', 0, NULL, 'r' }, { NULL, 't', 0, NULL, 't' }, { NULL, 'S', 0, NULL, 'S' }, { NULL, 'R', 0, NULL, 'R' }, { NULL, '\0', 0, NULL, '\0' } }; optCon = poptGetContext(NULL, argc, argv, ksOptions, 0); if (isatty(1)) flags |= SENDDIR_MULTICOLUMN; while ((rc = poptGetNextOpt(optCon)) >= 0) { switch (rc) { case 'l': flags |= SENDDIR_LONG; flags &= ~SENDDIR_MULTICOLUMN; break; case 'C': flags |= SENDDIR_MULTICOLUMN; flags &= ~SENDDIR_LONG; break; case 'd': flags |= SENDDIR_SIMPLEDIRS; break; case 'g': /* ignored */ break; case 'n': flags |= SENDDIR_NUMIDS; break; case 'p': case 'F': flags |= SENDDIR_FILETYPE; break; case 'a': flags |= SENDDIR_ALL; break; case 'L': flags |= SENDDIR_FOLLOWLINKS; break; case 'f': flags |= SENDDIR_SORTNONE; break; case 'r': flags |= SENDDIR_SORTREVERSE; break; case 't': flags |= SENDDIR_SORTMTIME; break; case 'S': flags |= SENDDIR_SORTSIZE; break; case 'R': flags |= SENDDIR_RECURSE; break; } } getcwd(path, 1000); if (rc < -1) { fprintf(stderr, "argument error: %s %s", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); } else { idInit(); argv = poptGetArgs(optCon); if (argv) { while (*argv) { if (argv[0][0] == '/') listFiles("", *argv, flags); else listFiles(path, *argv, flags); argv++; } } else { listFiles(path, "", flags); } } return 0; } int gunzipCommand(int argc, char ** argv) { gzFile f; char buf[16384]; int i; f = gzdopen(0, "r"); while ((i = gzread(f, buf, sizeof(buf))) > 0) write(1, buf, i); gzclose(f); return 0; }