diff options
Diffstat (limited to 'src/sash/cmds.c')
-rw-r--r-- | src/sash/cmds.c | 1562 |
1 files changed, 1562 insertions, 0 deletions
diff --git a/src/sash/cmds.c b/src/sash/cmds.c new file mode 100644 index 0000000..ae346b5 --- /dev/null +++ b/src/sash/cmds.c @@ -0,0 +1,1562 @@ +/* + * Copyright (c) 2014 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Most simple built-in commands are here. + */ + +#include "sash.h" + +#include <sys/types.h> +#include <sys/stat.h> +//#include <sys/mount.h> +#include <signal.h> +#include <pwd.h> +#include <grp.h> +#include <utime.h> +#include <errno.h> + +#if HAVE_LINUX_MOUNT +#include <linux/fs.h> +#endif + +/* Need to tell loop.h what the actual dev_t type is. */ +#undef dev_t +#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__)) +#define dev_t unsigned int +#else +#define dev_t unsigned short +#endif +//#include <linux/loop.h> +#undef dev_t +#define dev_t dev_t + + +int +do_echo(int argc, const char ** argv) +{ + BOOL first; + + first = TRUE; + + while (argc-- > 1) + { + if (!first) + fputc(' ', stdout); + + first = FALSE; + fputs(*(++argv), stdout); + } + + fputc('\n', stdout); + + return 0; +} + + +int +do_pwd(int argc, const char ** argv) +{ + char buf[PATH_LEN]; + + if (getcwd(buf, PATH_LEN) == NULL) + { + fprintf(stderr, "Cannot get current directory\n"); + + return 1; + } + + printf("%s\n", buf); + + return 0; +} + + +int +do_cd(int argc, const char ** argv) +{ + const char * path; + + if (argc > 1) + path = argv[1]; + else + { + path = getenv("HOME"); + + if (path == NULL) + { + fprintf(stderr, "No HOME environment variable\n"); + + return 1; + } + } + + if (chdir(path) < 0) + { + perror(path); + + return 1; + } + + return 0; +} + + +int +do_mkdir(int argc, const char ** argv) +{ + int r = 0; + + while (argc-- > 1) + { + if (mkdir(argv[1], 0777) < 0) + { + perror(argv[1]); + r = 1; + } + + argv++; + } + + return r; +} + + +int +do_mknod(int argc, const char ** argv) +{ + const char * cp; + int mode; + int major; + int minor; + + mode = 0666; + + if (strcmp(argv[2], "b") == 0) + mode |= S_IFBLK; + else if (strcmp(argv[2], "c") == 0) + mode |= S_IFCHR; + else + { + fprintf(stderr, "Bad device type\n"); + + return 1; + } + + major = 0; + cp = argv[3]; + + while (isDecimal(*cp)) + major = major * 10 + *cp++ - '0'; + + if (*cp || (major < 0) || (major > 255)) + { + fprintf(stderr, "Bad major number\n"); + + return 1; + } + + minor = 0; + cp = argv[4]; + + while (isDecimal(*cp)) + minor = minor * 10 + *cp++ - '0'; + + if (*cp || (minor < 0) || (minor > 255)) + { + fprintf(stderr, "Bad minor number\n"); + + return 1; + } + + if (mknod(argv[1], mode, major * 256 + minor) < 0) + { + perror(argv[1]); + + return 1; + } + + return 0; +} + + +#if HAVE_LINUX_PIVOT + +int +do_pivot_root(int argc, const char ** argv) +{ + if (pivot_root(argv[1], argv[2]) < 0) + { + perror("pivot_root"); + + return 1; + } + + return 0; +} + +#endif + + +#if HAVE_LINUX_CHROOT + +int +do_chroot(int argc, const char ** argv) +{ + if (chroot(argv[1]) < 0) + { + perror("chroot"); + + return 1; + } + + return 0; +} + +#endif + + +int +do_rmdir(int argc, const char ** argv) +{ + int r = 0; + + while (argc-- > 1) + { + if (rmdir(argv[1]) < 0) + { + perror(argv[1]); + r = 1; + } + + argv++; + } + + return r; +} + + +int +do_sync(int argc, const char ** argv) +{ + sync(); + + return 0; +} + + +int +do_rm(int argc, const char ** argv) +{ + int r = 0; + + while (argc-- > 1) + { + if (unlink(argv[1]) < 0) + { + perror(argv[1]); + r = 1; + } + + argv++; + } + + return r; +} + + +int +do_chmod(int argc, const char ** argv) +{ + const char * cp; + int mode; + int r; + + r = 0; + mode = 0; + cp = argv[1]; + + while (isOctal(*cp)) + mode = mode * 8 + (*cp++ - '0'); + + if (*cp) + { + fprintf(stderr, "Mode must be octal\n"); + + return 1; + } + + argc--; + argv++; + + while (argc-- > 1) + { + if (chmod(argv[1], mode) < 0) + { + perror(argv[1]); + r = 1; + } + + argv++; + } + + return r; +} + + +int +do_chown(int argc, const char ** argv) +{ + const char * cp; + int uid; + struct passwd * pwd; + struct stat statBuf; + int r; + + r = 0; + cp = argv[1]; + + if (isDecimal(*cp)) + { + uid = 0; + + while (isDecimal(*cp)) + uid = uid * 10 + (*cp++ - '0'); + + if (*cp) + { + fprintf(stderr, "Bad uid value\n"); + + return 1; + } + } + else + { + pwd = getpwnam(cp); + + if (pwd == NULL) + { + fprintf(stderr, "Unknown user name\n"); + + return 1; + } + + uid = pwd->pw_uid; + } + + argc--; + argv++; + + while (argc-- > 1) + { + argv++; + + if ((stat(*argv, &statBuf) < 0) || + (chown(*argv, uid, statBuf.st_gid) < 0)) + { + perror(*argv); + r = 1; + } + } + + return r; +} + + +int +do_chgrp(int argc, const char ** argv) +{ + const char * cp; + int gid; + struct group * grp; + struct stat statBuf; + int r; + + r = 0; + cp = argv[1]; + + if (isDecimal(*cp)) + { + gid = 0; + + while (isDecimal(*cp)) + gid = gid * 10 + (*cp++ - '0'); + + if (*cp) + { + fprintf(stderr, "Bad gid value\n"); + + return 1; + } + } + else + { + grp = getgrnam(cp); + + if (grp == NULL) + { + fprintf(stderr, "Unknown group name\n"); + + return 1; + } + + gid = grp->gr_gid; + } + + argc--; + argv++; + + while (argc-- > 1) + { + argv++; + + if ((stat(*argv, &statBuf) < 0) || + (chown(*argv, statBuf.st_uid, gid) < 0)) + { + perror(*argv); + r = 1; + } + } + + return r; +} + + +int +do_touch(int argc, const char ** argv) +{ + const char * name; + int fd; + struct utimbuf now; + int r; + + r = 0; + time(&now.actime); + now.modtime = now.actime; + + while (argc-- > 1) + { + name = *(++argv); + + fd = open(name, O_CREAT | O_WRONLY | O_EXCL, 0666); + + if (fd >= 0) + { + close(fd); + + continue; + } + + if (errno != EEXIST) + { + perror(name); + r = 1; + + continue; + } + + if (utime(name, &now) < 0) + { + perror(name); + r = 1; + } + } + + return r; +} + + +int +do_mv(int argc, const char ** argv) +{ + const char * srcName; + const char * destName; + const char * lastArg; + BOOL dirFlag; + int r; + + r = 0; + lastArg = argv[argc - 1]; + + dirFlag = isDirectory(lastArg); + + if ((argc > 3) && !dirFlag) + { + fprintf(stderr, "%s: not a directory\n", lastArg); + + return 1; + } + + while (!intFlag && (argc-- > 2)) + { + srcName = *(++argv); + + if (access(srcName, 0) < 0) + { + perror(srcName); + r = 1; + + continue; + } + + destName = lastArg; + + if (dirFlag) + destName = buildName(destName, srcName); + + if (rename(srcName, destName) >= 0) + continue; + + if (errno != EXDEV) + { + perror(destName); + r = 1; + + continue; + } + + if (!copyFile(srcName, destName, TRUE)) + { + r = 1; + + continue; + } + + if (unlink(srcName) < 0) + { + perror(srcName); + r = 1; + } + } + + return r; +} + + +int +do_ln(int argc, const char ** argv) +{ + const char * srcName; + const char * destName; + const char * lastArg; + BOOL dirFlag; + int r; + + r = 0; + + if (argv[1][0] == '-') + { + if (strcmp(argv[1], "-s")) + { + fprintf(stderr, "Unknown option\n"); + + return 1; + } + + if (argc != 4) + { + fprintf(stderr, "Wrong number of arguments for symbolic link\n"); + + return 1; + } + +#ifdef S_ISLNK + if (symlink(argv[2], argv[3]) < 0) + { + perror(argv[3]); + + return 1; + } + + return 0; +#else + fprintf(stderr, "Symbolic links are not allowed\n"); + + return 1; +#endif + } + + /* + * Here for normal hard links. + */ + lastArg = argv[argc - 1]; + dirFlag = isDirectory(lastArg); + + if ((argc > 3) && !dirFlag) + { + fprintf(stderr, "%s: not a directory\n", lastArg); + + return 1; + } + + while (argc-- > 2) + { + srcName = *(++argv); + + if (access(srcName, 0) < 0) + { + perror(srcName); + r = 1; + + continue; + } + + destName = lastArg; + + if (dirFlag) + destName = buildName(destName, srcName); + + if (link(srcName, destName) < 0) + { + perror(destName); + r = 1; + + continue; + } + } + + return r; +} + + +int +do_cp(int argc, const char ** argv) +{ + const char * srcName; + const char * destName; + const char * lastArg; + BOOL dirFlag; + int r; + + r = 0; + lastArg = argv[argc - 1]; + + dirFlag = isDirectory(lastArg); + + if ((argc > 3) && !dirFlag) + { + fprintf(stderr, "%s: not a directory\n", lastArg); + + return 1; + } + + while (!intFlag && (argc-- > 2)) + { + srcName = *(++argv); + destName = lastArg; + + if (dirFlag) + destName = buildName(destName, srcName); + + if (!copyFile(srcName, destName, FALSE)) + r = 1; + } + + return r; +} + + +int +do_mount(int argc, const char ** argv) +{ + const char * str; + const char * type; + int flags; + + argc--; + argv++; + + type = MOUNT_TYPE; + +#if HAVE_LINUX_MOUNT + flags = MS_MGC_VAL; +#else + flags = 0; +#endif + + while ((argc > 0) && (**argv == '-')) + { + argc--; + str = *argv++; + + while (*++str) switch (*str) + { + case 't': + if ((argc <= 0) || (**argv == '-')) + { + fprintf(stderr, "Missing file system type\n"); + + return 1; + } + + type = *argv++; + argc--; + break; + +#if HAVE_LINUX_MOUNT + case 'r': + flags |= MS_RDONLY; + break; + + case 'm': + flags |= MS_REMOUNT; + break; + + case 's': + flags |= MS_NOSUID; + break; + + case 'e': + flags |= MS_NOEXEC; + break; + +#elif HAVE_BSD_MOUNT + case 'r': + flags |= MNT_RDONLY; + break; + + case 's': + flags |= MNT_NOSUID; + break; + + case 'e': + flags |= MNT_NOEXEC; + break; +#endif + default: + fprintf(stderr, "Unknown option\n"); + + return 1; + } + } + + if (argc != 2) + { + fprintf(stderr, "Wrong number of arguments for mount\n"); + + return 1; + } + +#if HAVE_LINUX_MOUNT + + if (mount(argv[0], argv[1], type, flags, 0) < 0) + { + perror("mount failed"); + return 1; + } +#elif HAVE_BSD_MOUNT + { + struct ufs_args ufs; + struct adosfs_args adosfs; + struct iso_args iso; + struct mfs_args mfs; + struct msdosfs_args msdosfs; + void * args; + + if (!strcmp(type, "ffs") || !strcmp(type, "ufs")) + { + ufs.fspec = (char*) argv[0]; + args = &ufs; + } + else if (!strcmp(type, "adosfs")) + { + adosfs.fspec = (char*) argv[0]; + adosfs.uid = 0; + adosfs.gid = 0; + args = &adosfs; + } + else if (!strcmp(type, "cd9660")) + { + iso.fspec = (char*) argv[0]; + args = &iso; + } + else if (!strcmp(type, "mfs")) + { + mfs.fspec = (char*) argv[0]; + args = &mfs; + } + else if (!strcmp(type, "msdos")) + { + msdosfs.fspec = (char*) argv[0]; + msdosfs.uid = 0; + msdosfs.gid = 0; + args = &msdosfs; + } + else + { + fprintf(stderr, "Unknown filesystem type: %s", type); + fprintf(stderr, + "Supported: ffs ufs adosfs cd9660 mfs msdos\n"); + + return 1; + } + + if (mount(type, argv[1], flags, args) < 0) + { + perror(argv[0]); + + return 1; + } + } +#endif + return 0; +} + + +int +do_umount(int argc, const char ** argv) +{ +#if HAVE_LINUX_MOUNT + if (umount(argv[1]) < 0) + { + perror(argv[1]); + + return 1; + } +#elif HAVE_BSD_MOUNT + { + const char * str; + int flags = 0; + + for (argc--, argv++; + (argc > 0) && (**argv == '-');) + { + argc--; + str = *argv++; + + while (*++str) +{ + switch (*str) + { + case 'f': + flags = MNT_FORCE; + break; + } + } + } + + if (unmount(argv[0], flags) < 0) + { + perror(argv[0]); + + return 1; + } + } +#endif + return 0; +} + + +int +do_cmp(int argc, const char ** argv) +{ + int fd1; + int fd2; + int cc1; + int cc2; + long pos; + const char * bp1; + const char * bp2; + char buf1[BUF_SIZE]; + char buf2[BUF_SIZE]; + struct stat statBuf1; + struct stat statBuf2; + int r; + + r = 0; + + if (stat(argv[1], &statBuf1) < 0) + { + perror(argv[1]); + + return 1; + } + + if (stat(argv[2], &statBuf2) < 0) + { + perror(argv[2]); + + return 1; + } + + if ((statBuf1.st_dev == statBuf2.st_dev) && + (statBuf1.st_ino == statBuf2.st_ino)) + { + printf("Files are links to each other\n"); + + return 0; + } + + if (statBuf1.st_size != statBuf2.st_size) + { + printf("Files are different sizes\n"); + + return 1; + } + + fd1 = open(argv[1], O_RDONLY); + + if (fd1 < 0) + { + perror(argv[1]); + + return 1; + } + + fd2 = open(argv[2], O_RDONLY); + + if (fd2 < 0) + { + perror(argv[2]); + close(fd1); + + return 1; + } + + pos = 0; + + while (TRUE) + { + if (intFlag) + goto closefiles; + + cc1 = read(fd1, buf1, sizeof(buf1)); + + if (cc1 < 0) + { + perror(argv[1]); + r = 1; + goto closefiles; + } + + cc2 = read(fd2, buf2, sizeof(buf2)); + + if (cc2 < 0) + { + perror(argv[2]); + r = 1; + goto closefiles; + } + + if ((cc1 == 0) && (cc2 == 0)) + { + printf("Files are identical\n"); + r = 0; + goto closefiles; + } + + if (cc1 < cc2) + { + printf("First file is shorter than second\n"); + r = 1; + goto closefiles; + } + + if (cc1 > cc2) + { + printf("Second file is shorter than first\n"); + r = 1; + goto closefiles; + } + + if (memcmp(buf1, buf2, cc1) == 0) + { + pos += cc1; + + continue; + } + + bp1 = buf1; + bp2 = buf2; + + while (*bp1++ == *bp2++) + pos++; + + printf("Files differ at byte position %ld\n", pos); + r = 1; + + goto closefiles; + } + +closefiles: + close(fd1); + close(fd2); + + return r; +} + + +int +do_more(int argc, const char ** argv) +{ + FILE * fp; + const char * name; + int ch; + int line; + int col; + int pageLines; + int pageColumns; + char buf[80]; + + /* + * Get the width and height of the screen if it is set. + * If not, then default it. + */ + pageLines = 0; + pageColumns = 0; + + name = getenv("LINES"); + + if (name) + pageLines = atoi(name); + + name = getenv("COLS"); + + if (name) + pageColumns = atoi(name); + + if (pageLines <= 0) + pageLines = 24; + + if (pageColumns <= 0) + pageColumns = 80; + + /* + * OK, process each file. + */ + while (argc-- > 1) + { + name = *(++argv); + + fp = fopen(name, "r"); + + if (fp == NULL) + { + perror(name); + + return 1; + } + + printf("<< %s >>\n", name); + line = 1; + col = 0; + + while (fp && ((ch = fgetc(fp)) != EOF)) + { + switch (ch) + { + case '\r': + col = 0; + break; + + case '\n': + line++; + col = 0; + break; + + case '\t': + col = ((col + 1) | 0x07) + 1; + break; + + case '\b': + if (col > 0) + col--; + break; + + default: + col++; + } + + putchar(ch); + + if (col >= pageColumns) + { + col -= pageColumns; + line++; + } + + if (line < pageLines) + continue; + + if (col > 0) + putchar('\n'); + + printf("--More--"); + fflush(stdout); + + if (intFlag || (read(0, buf, sizeof(buf)) < 0)) + { + if (fp) + fclose(fp); + + return 0; + } + + ch = buf[0]; + + if (ch == ':') + ch = buf[1]; + + switch (ch) + { + case 'N': + case 'n': + fclose(fp); + fp = NULL; + break; + + case 'Q': + case 'q': + fclose(fp); + + return 0; + } + + col = 0; + line = 1; + } + + if (fp) + fclose(fp); + } + + return 0; +} + + +int +do_sum(int argc, const char ** argv) +{ + const char * name; + int fd; + int cc; + int ch; + int i; + unsigned long checksum; + char buf[BUF_SIZE]; + int r; + + argc--; + argv++; + r = 0; + + while (argc-- > 0) + { + name = *argv++; + + fd = open(name, O_RDONLY); + + if (fd < 0) + { + perror(name); + r = 1; + + continue; + } + + checksum = 0; + + while ((cc = read(fd, buf, sizeof(buf))) > 0) + { + for (i = 0; i < cc; i++) + { + ch = buf[i]; + + if ((checksum & 0x01) != 0) + checksum = (checksum >> 1) + 0x8000; + else + checksum = (checksum >> 1); + + checksum = (checksum + ch) & 0xffff; + } + } + + if (cc < 0) + { + perror(name); + r = 1; + + (void) close(fd); + + continue; + } + + (void) close(fd); + + printf("%05lu %s\n", checksum, name); + } + + return r; +} + + +int +do_exit(int argc, const char ** argv) +{ + int r = 0; + + if (getpid() == 1) + { + fprintf(stderr, "You are the INIT process!\n"); + + return 1; + } + + if (argc == 2) + { + r = atoi(argv[1]); + } + + exit(r); + + return 1; +} + + +int +do_setenv(int argc, const char ** argv) +{ + const char * name; + const char * value; + char * str; + + name = argv[1]; + value = argv[2]; + + /* + * The value given to putenv must remain around, so we must malloc it. + * Note: memory is not reclaimed if the same variable is redefined. + */ + str = malloc(strlen(name) + strlen(value) + 2); + + if (str == NULL) + { + fprintf(stderr, "Cannot allocate memory\n"); + + return 1; + } + + strcpy(str, name); + strcat(str, "="); + strcat(str, value); + + putenv(str); + + return 0; +} + + +int +do_printenv(int argc, const char ** argv) +{ + const char ** env; + extern char ** environ; + int len; + + env = (const char **) environ; + + if (argc == 1) + { + while (*env) + printf("%s\n", *env++); + + return 0; + } + + len = strlen(argv[1]); + + while (*env) + { + if ((strlen(*env) > len) && (env[0][len] == '=') && + (memcmp(argv[1], *env, len) == 0)) + { + printf("%s\n", &env[0][len+1]); + + return 0; + } + env++; + } + + return 0; +} + + +int +do_umask(int argc, const char ** argv) +{ + const char * cp; + int mask; + + if (argc <= 1) + { + mask = umask(0); + umask(mask); + printf("%03o\n", mask); + + return 0; + } + + mask = 0; + cp = argv[1]; + + while (isOctal(*cp)) + mask = mask * 8 + *cp++ - '0'; + + if (*cp || (mask & ~0777)) + { + fprintf(stderr, "Bad umask value\n"); + + return 1; + } + + umask(mask); + + return 0; +} + + +int +do_kill(int argc, const char ** argv) +{ + const char * cp; + int sig; + int pid; + int r; + + r = 0; + sig = SIGTERM; + + if (argv[1][0] == '-') + { + cp = &argv[1][1]; + + if (strcmp(cp, "HUP") == 0) + sig = SIGHUP; + else if (strcmp(cp, "INT") == 0) + sig = SIGINT; + else if (strcmp(cp, "QUIT") == 0) + sig = SIGQUIT; + else if (strcmp(cp, "KILL") == 0) + sig = SIGKILL; + else if (strcmp(cp, "STOP") == 0) + sig = SIGSTOP; + else if (strcmp(cp, "CONT") == 0) + sig = SIGCONT; + else if (strcmp(cp, "USR1") == 0) + sig = SIGUSR1; + else if (strcmp(cp, "USR2") == 0) + sig = SIGUSR2; + else if (strcmp(cp, "TERM") == 0) + sig = SIGTERM; + else + { + sig = 0; + + while (isDecimal(*cp)) + sig = sig * 10 + *cp++ - '0'; + + if (*cp) + { + fprintf(stderr, "Unknown signal\n"); + + return 1; + } + } + + argc--; + argv++; + } + + while (argc-- > 1) + { + cp = *(++argv); + pid = 0; + + while (isDecimal(*cp)) + pid = pid * 10 + *cp++ - '0'; + + if (*cp) + { + fprintf(stderr, "Non-numeric pid\n"); + + return 1; + } + + if (kill(pid, sig) < 0) + { + perror(*argv); + r = 1; + } + } + + return r; +} + + +int +do_where(int argc, const char ** argv) +{ + const char * program; + const char * dirName; + char * path; + char * endPath; + char * fullPath; + BOOL found; + int r; + + found = FALSE; + program = argv[1]; + + if (strchr(program, '/') != NULL) + { + fprintf(stderr, "Program name cannot include a path\n"); + + return 1; + } + + path = getenv("PATH"); + + fullPath = getChunk(strlen(path) + strlen(program) + 2); + path = chunkstrdup(path); + + if ((path == NULL) || (fullPath == NULL)) + { + fprintf(stderr, "Memory allocation failed\n"); + + return 1; + } + + /* + * Check out each path to see if the program exists and is + * executable in that path. + */ + for (; path; path = endPath) + { + /* + * Find the end of the next path and NULL terminate + * it if necessary. + */ + endPath = strchr(path, ':'); + + if (endPath) + *endPath++ = '\0'; + + /* + * Get the directory name, defaulting it to DOT if + * it is null. + */ + dirName = path; + + if (dirName == '\0') + dirName = "."; + + /* + * Construct the full path of the program. + */ + strcpy(fullPath, dirName); + strcat(fullPath, "/"); + strcat(fullPath, program); + + /* + * See if the program exists and is executable. + */ + if (access(fullPath, X_OK) < 0) + { + if (errno != ENOENT) + { + perror(fullPath); + r = 1; + } + + continue; + } + + printf("%s\n", fullPath); + found = TRUE; + } + + if (!found) + { + printf("Program \"%s\" not found in PATH\n", program); + r = 1; + } + + return r; +} + +#if HAVE_LINUX_LOSETUP + +int +do_losetup(int argc, const char ** argv) +{ + int loopfd; + int targfd; + struct loop_info loopInfo; + + if (!strcmp(argv[1], "-d")) + { + loopfd = open(argv[2], O_RDWR); + + if (loopfd < 0) + { + fprintf(stderr, "Error opening %s: %s\n", argv[2], + strerror(errno)); + + return 1; + } + + if (ioctl(loopfd, LOOP_CLR_FD, 0)) + { + fprintf(stderr, "Error unassociating device: %s\n", + strerror(errno)); + + return 1; + } + } + + loopfd = open(argv[1], O_RDWR); + + if (loopfd < 0) + { + fprintf(stderr, "Error opening %s: %s\n", argv[1], + strerror(errno)); + + return 1; + } + + targfd = open(argv[2], O_RDWR); + + if (targfd < 0) + { + fprintf(stderr, "Error opening %s: %s\n", argv[2], + strerror(errno)); + + return 1; + } + + if (ioctl(loopfd, LOOP_SET_FD, targfd)) + { + fprintf(stderr, "Error setting up loopback device: %s\n", + strerror(errno)); + + return 1; + } + + memset(&loopInfo, 0, sizeof(loopInfo)); + strcpy(loopInfo.lo_name, argv[2]); + + if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) + { + fprintf(stderr, "Error setting up loopback device: %s\n", + strerror(errno)); + + return 1; + } + + return 0; +} + +#endif + +/* END CODE */ |