int main(int argc, char **argv) { int lc; char *msg; struct stat buf; int fail; int cnt; char wbuf[17 * PIPE_SIZE_TEST]; struct sigaction sigptr; /* set up signal handler */ if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } /* global setup */ setup(); /* * The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset tst_count in case we are looping */ tst_count = 0; if (mknod(fifo, S_IFIFO | 0777, 0) < 0) { tst_resm(TBROK, "mknod() failed, errno: %d", errno); cleanup(); } if (stat(fifo, &buf) != 0) { tst_resm(TBROK, "stat() failed, errno: %d", errno); cleanup(); } if ((buf.st_mode & S_IFIFO) == 0) { tst_resm(TBROK, "Mode does not indicate fifo file"); cleanup(); } #if 0 sigset(SIGALRM, alarm_handler); #endif sigptr.sa_handler = (void (*)(int signal))alarm_handler; sigfillset(&sigptr.sa_mask); sigptr.sa_flags = 0; sigaddset(&sigptr.sa_mask, SIGALRM); if (sigaction(SIGALRM, &sigptr, NULL) == -1) { tst_resm(TBROK, "sigaction(): Failed"); cleanup(); } //block1: tst_resm(TINFO, "Enter block 1: test for EAGAIN in write()"); fail = 0; (void)memset((void *)wbuf, 'A', 17 * PIPE_SIZE_TEST); /* * open the read end of the pipe */ if (sigsetjmp(jmp, 1)) { tst_resm(TBROK, "Error reading fifo, read blocked"); fail = 1; } (void)alarm(10); /* set alarm for 10 seconds */ rfd = open(fifo, O_RDONLY | O_NONBLOCK); (void)alarm(0); if (rfd < 0) { tst_resm(TBROK, "open() for reading the pipe failed"); fail = 1; } /* * open the write end of the pipe */ if (sigsetjmp(jmp, 1)) { tst_resm(TBROK, "setjmp() failed"); cleanup(); } (void)alarm(10); /* set alarm for 10 seconds */ wfd = open(fifo, O_WRONLY | O_NONBLOCK); (void)alarm(0); if (wfd < 0) { tst_resm(TBROK, "open() for writing the pipe failed"); fail = 1; } /* * attempt to fill the pipe with some data */ if (sigsetjmp(jmp, 1)) { tst_resm(TBROK, "sigsetjmp() failed"); fail = 1; } (void)alarm(10); cnt = write(wfd, wbuf, 17 * PIPE_SIZE_TEST); (void)alarm(0); if (cnt == 17 * PIPE_SIZE_TEST) { tst_resm(TBROK, "Error reading fifo, nozero read"); fail = 1; } /* * Now that the fifo is full try and send some more */ if (sigsetjmp(jmp, 1)) { tst_resm(TBROK, "sigsetjmp() failed"); fail = 1; } (void)alarm(10); cnt = write(wfd, wbuf, 8 * PIPE_SIZE_TEST); (void)alarm(0); if (cnt != -1) { tst_resm(TBROK, "write() failed to fail when pipe " "is full"); fail = 1; } else { TEST_ERROR_LOG(errno); if (errno != EAGAIN) { tst_resm(TBROK, "write set bad errno, expected " "EAGAIN, got %d", errno); fail = 1; } tst_resm(TINFO, "read() succeded in setting errno to " "EAGAIN"); } if (fail) { tst_resm(TFAIL, "Block 1 FAILED"); } else { tst_resm(TPASS, "Block 1 PASSED"); } tst_resm(TINFO, "Exit block 1"); /* unlink fifo in case we are looping. */ unlink(fifo); } cleanup(); tst_exit(); }
int tbaseopen() { dev_t devt; struct stat st; int rc = 0; devt = makedev(TBASEMAJOR, 0); if (rc) { if (errno == ENOENT) { /* dev node does not exist. */ rc = mkdir("/dev/tbase", (S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)); } else { printf("ERROR: Problem with Base dev directory. Error code from stat() is %d\n\n", errno); } } else { if (!(st.st_mode & S_IFDIR)) { rc = unlink("/dev/tbase"); if (!rc) { rc = mkdir("/dev/tbase", (S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)); } } } /* * Check for the /dev/tbase node, and create if it does not * exist. */ rc = stat("/dev/tbase", &st); if (rc) { if (errno == ENOENT) { /* dev node does not exist */ rc = mknod("/dev/tbase", (S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), devt); } else { printf("ERROR:Problem with tbase device node directory. Error code form stat() is %d\n\n", errno); } } else { /* * /dev/tbase CHR device exists. Check to make sure it is for a * block device and that it has the right major and minor. */ if ((!(st.st_mode & S_IFCHR)) || (st.st_rdev != devt)) { /* Recreate the dev node. */ rc = unlink("/dev/tbase"); if (!rc) { rc = mknod("/dev/tbase", (S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), devt); } } } tbase_fd = open("/dev/tbase", O_RDWR); if (tbase_fd < 0) { printf("ERROR: Open of device %s failed %d errno = %d\n", "/dev/tbase",tbase_fd, errno); return errno; } else { printf("Device opened successfully \n"); return 0; } }
int main(int argc, char *argv[]) { _cleanup_udev_unref_ struct udev *udev = NULL; _cleanup_udev_event_unref_ struct udev_event *event = NULL; _cleanup_udev_device_unref_ struct udev_device *dev = NULL; _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL; char syspath[UTIL_PATH_SIZE]; const char *devpath; const char *action; sigset_t mask, sigmask_orig; int err; err = fake_filesystems(); if (err < 0) return EXIT_FAILURE; udev = udev_new(); if (udev == NULL) return EXIT_FAILURE; log_debug("version %s\n", VERSION); label_init("/dev"); sigprocmask(SIG_SETMASK, NULL, &sigmask_orig); action = argv[1]; if (action == NULL) { log_error("action missing\n"); goto out; } devpath = argv[2]; if (devpath == NULL) { log_error("devpath missing\n"); goto out; } rules = udev_rules_new(udev, 1); strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL); dev = udev_device_new_from_syspath(udev, syspath); if (dev == NULL) { log_debug("unknown device '%s'\n", devpath); goto out; } udev_device_set_action(dev, action); event = udev_event_new(dev); sigfillset(&mask); sigprocmask(SIG_SETMASK, &mask, &sigmask_orig); event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); if (event->fd_signal < 0) { fprintf(stderr, "error creating signalfd\n"); goto out; } /* do what devtmpfs usually provides us */ if (udev_device_get_devnode(dev) != NULL) { mode_t mode = 0600; if (streq(udev_device_get_subsystem(dev), "block")) mode |= S_IFBLK; else mode |= S_IFCHR; if (!streq(action, "remove")) { mkdir_parents_label(udev_device_get_devnode(dev), 0755); mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev)); } else { unlink(udev_device_get_devnode(dev)); util_delete_path(udev, udev_device_get_devnode(dev)); } } err = udev_event_execute_rules(event, rules, &sigmask_orig); if (err == 0) udev_event_execute_run(event, NULL); out: if (event != NULL && event->fd_signal >= 0) close(event->fd_signal); label_finish(); return err ? EXIT_FAILURE : EXIT_SUCCESS; }
int main(int argc, char *argv[]) { char **cmdv, **args; char *cmdlines[3]; int i; const char *errmsg; int ret = 0; int cmdc; int fd; struct timeval now; char *mount_argv[] = {"mount_part", "rootfs", "/root"}; pid_t pid; int nandboot = 0; gettimeofday(&now, NULL); srand48(now.tv_usec ^ (now.tv_sec << 24)); /* Default parameters for anything init-like we execute */ init_argc = argc; init_argv = alloca((argc+1)*sizeof(char *)); memcpy(init_argv, argv, (argc+1)*sizeof(char *)); /* * omit /dev/console when generating initramfs, * so we create it dynamically */ if (access("/dev/console", O_RDWR)) { mknod("/dev/console", S_IFCHR|0644, makedev(5, 1)); } if ((fd = open("/dev/console", O_RDWR)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) { close(fd); } } mnt_procfs = mount_sys_fs("/proc/cmdline", "/proc", "proc") >= 0; if (!mnt_procfs) { ret = 1; goto bail; } mnt_sysfs = mount_sys_fs("/sys/bus", "/sys", "sysfs") >= 0; if (!mnt_sysfs) { ret = 1; goto bail; } /* Construct the effective kernel command line. The effective kernel command line consists of /arch.cmd, if it exists, /proc/cmdline, plus any arguments after an -- argument on the proper command line, in that order. */ ret = readfile("/arch.cmd", &cmdlines[0]); if (ret < 0) cmdlines[0] = ""; ret = readfile("/proc/cmdline", &cmdlines[1]); if (ret < 0) { fprintf(stderr, "%s: cannot read /proc/cmdline\n", progname); ret = 1; goto bail; } cmdlines[2] = NULL; /* Find an -- argument, and if so append to the command line */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--")) { i++; break; } } args = &argv[i]; /* Points either to first argument past -- or to the final NULL */ /* Count the number of arguments */ cmdc = split_cmdline(INT_MAX, NULL, argv[0], cmdlines, args); /* Actually generate the cmdline array */ cmdv = (char **)alloca((cmdc+1)*sizeof(char *)); if (split_cmdline(cmdc, cmdv, argv[0], cmdlines, args) != cmdc) { ret = 1; goto bail; } /* Debugging... */ dump_args(cmdc, cmdv); { const char * root_device_name = get_arg(cmdc, cmdv, "root="); if (strncmp(root_device_name, "/dev/mtdblock", strlen("/dev/mtdblock")) == 0) { nandboot = 1; printf("kinit: NAND mode, check online upgrade flag\n"); do_rootfs_OU(); } else { nandboot = 0; printf("kinit: None-NAND mode, ignore online upgrade flag\n"); } } /* Resume from suspend-to-disk, if appropriate */ /* If successful, does not return */ do_resume(cmdc, cmdv); /* Initialize networking, if applicable */ do_ipconfig(cmdc, cmdv); check_path("/root"); if (nandboot) { int index = 0; while (1) { char name[128]; snprintf(name, sizeof(name), "/sys/block/mtdblock%d", index); if (access(name, F_OK) == 0) { snprintf(name, sizeof(name), "/dev/mtdblock%d", index); create_dev(name, name_to_dev_t(name)); index++; } else { break; } } if((pid=fork())<0) fprintf(stderr, "fork error.\n"); else if(pid == 0) { if((ret = execve("/bin/mount_part", mount_argv, NULL)) <0) perror("excute mount_part error\n"); } if(waitpid(pid, NULL, 0) < 0) fprintf(stderr, "wait mount_part error.\n"); } else { do_mounts(cmdc, cmdv); } if (mnt_procfs) { umount2("/proc", 0); mnt_procfs = 0; } if (mnt_sysfs) { umount2("/sys", 0); mnt_sysfs = 0; } make_devices(); init_path = find_init("/root", get_arg(cmdc, cmdv, "init=")); if (!init_path) { fprintf(stderr, "%s: init not found!\n", progname); ret = 2; goto bail; } DEBUG(("kinit: init_path = %s, init=%s\n", init_path, get_arg(cmdc, cmdv, "init="))); init_argv[0] = strrchr(init_path, '/') + 1; errmsg = run_init("/root", "/dev/console", init_path, init_argv); /* If run_init returned, something went bad */ fprintf(stderr, "%s: %s: %s\n", progname, errmsg, strerror(errno)); ret = 2; goto bail; bail: if (mnt_procfs) umount2("/proc", 0); if (mnt_sysfs) umount2("/sys", 0); /* * If we get here, something bad probably happened, and the kernel * will most likely panic. Drain console output so the user can * figure out what happened. */ tcdrain(2); tcdrain(1); return ret; }
static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, FsCred *credp) { char *path; int err = -1; int serrno = 0; V9fsString fullname; char *buffer; v9fs_string_init(&fullname); v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name); path = fullname.data; /* Determine the security model */ if (fs_ctx->export_flags & V9FS_SM_MAPPED) { buffer = rpath(fs_ctx, path); err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0); if (err == -1) { g_free(buffer); goto out; } err = local_set_xattr(buffer, credp); if (err == -1) { serrno = errno; goto err_end; } } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { buffer = rpath(fs_ctx, path); err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0); if (err == -1) { g_free(buffer); goto out; } err = local_set_mapped_file_attr(fs_ctx, path, credp); if (err == -1) { serrno = errno; goto err_end; } } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || (fs_ctx->export_flags & V9FS_SM_NONE)) { buffer = rpath(fs_ctx, path); err = mknod(buffer, credp->fc_mode, credp->fc_rdev); if (err == -1) { g_free(buffer); goto out; } err = local_post_create_passthrough(fs_ctx, path, credp); if (err == -1) { serrno = errno; goto err_end; } } goto out; err_end: remove(buffer); errno = serrno; g_free(buffer); out: v9fs_string_free(&fullname); return err; }
int main(int ac, char **av) { int lc; int fflag; /* functionality flag variable */ const char *msg; msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; /* * Attempt to create a filesystem node with group id (sgid) * bit set on a directory with group id (sgid) bit set * such that, the node created by mknod(2) should have * group id (sgid) bit set and node's gid should be equal * to that of effective gid of the process. */ TEST(mknod(node_name, MODE_SGID, 0)); /* Check return code from mknod(2) */ if (TEST_RETURN == -1) { tst_resm(TFAIL, "mknod(%s, %#o, 0) failed, errno=%d : " "%s", node_name, MODE_SGID, TEST_ERRNO, strerror(TEST_ERRNO)); continue; } /* Set the functionality flag */ fflag = 1; /* Check for node's creation */ if (stat(node_name, &buf) < 0) { tst_resm(TFAIL, "stat() of %s failed, errno:%d", node_name, TEST_ERRNO); /* unset functionality flag */ fflag = 0; } /* Verify mode permissions of node */ if (!(buf.st_mode & S_ISGID)) { tst_resm(TFAIL, "%s: Incorrect modes, setgid bit not " "set", node_name); /* unset flag as functionality fails */ fflag = 0; } /* Verify group ID */ if (buf.st_gid != group2_gid) { tst_resm(TFAIL, "%s: Incorrect group", node_name); /* unset flag as functionality fails */ fflag = 0; } if (fflag) { tst_resm(TPASS, "Functionality of mknod(%s, " "%#o, 0) successful", node_name, MODE_SGID); } /* Remove the node for the next go `round */ if (unlink(node_name) == -1) { tst_resm(TWARN, "unlink(%s) failed, errno:%d %s", node_name, errno, strerror(errno)); } } /* Change the directory back to temporary directory */ chdir(".."); /* * Invoke cleanup() to delete the test directories created * in the setup() and exit main(). */ cleanup(); tst_exit(); }
void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) { file_header_t *file_header = archive_handle->file_header; int dst_fd; int res; #if ENABLE_FEATURE_TAR_SELINUX char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; #ifdef __BIONIC__ matchpathcon_init(NULL); #endif if (!sctx) sctx = archive_handle->tar__sctx[PAX_GLOBAL]; if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */ setfscreatecon(sctx); free(archive_handle->tar__sctx[PAX_NEXT_FILE]); archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL; } #endif if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { char *slash = strrchr(file_header->name, '/'); if (slash) { *slash = '\0'; bb_make_directory(file_header->name, -1, FILEUTILS_RECUR); *slash = '/'; } } if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { /* Remove the entry if it exists */ if (!S_ISDIR(file_header->mode)) { /* Is it hardlink? * We encode hard links as regular files of size 0 with a symlink */ if (S_ISREG(file_header->mode) && file_header->link_target && file_header->size == 0 ) { /* Ugly special case: * tar cf t.tar hardlink1 hardlink2 hardlink1 * results in this tarball structure: * hardlink1 * hardlink2 -> hardlink1 * hardlink1 -> hardlink1 <== !!! */ if (strcmp(file_header->link_target, file_header->name) == 0) goto ret; } /* Proceed with deleting */ if (unlink(file_header->name) == -1 && errno != ENOENT ) { bb_perror_msg_and_die("can't remove old file %s", file_header->name); } } } else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { /* Remove the existing entry if its older than the extracted entry */ struct stat existing_sb; if (lstat(file_header->name, &existing_sb) == -1) { if (errno != ENOENT) { bb_perror_msg_and_die("can't stat old file"); } } else if ((time_t) existing_sb.st_mtime >= (time_t) file_header->mtime) { if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) && !S_ISDIR(file_header->mode) ) { bb_error_msg("%s not created: newer or " "same age file exists", file_header->name); } data_skip(archive_handle); goto ret; } else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) { bb_perror_msg_and_die("can't remove old file %s", file_header->name); } } /* Handle hard links separately * We encode hard links as regular files of size 0 with a symlink */ if (S_ISREG(file_header->mode) && file_header->link_target && file_header->size == 0 ) { /* hard link */ res = link(file_header->link_target, file_header->name); if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { bb_perror_msg("can't create %slink " "from %s to %s", "hard", file_header->name, file_header->link_target); } /* Hardlinks have no separate mode/ownership, skip chown/chmod */ goto ret; } /* Create the filesystem entry */ switch (file_header->mode & S_IFMT) { case S_IFREG: { /* Regular file */ char *dst_name; int flags = O_WRONLY | O_CREAT | O_EXCL; if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) flags = O_WRONLY | O_CREAT | O_TRUNC; dst_name = file_header->name; #ifdef ARCHIVE_REPLACE_VIA_RENAME if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) /* rpm-style temp file name */ dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); #endif dst_fd = xopen3(dst_name, flags, file_header->mode ); bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); close(dst_fd); #ifdef ARCHIVE_REPLACE_VIA_RENAME if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { xrename(dst_name, file_header->name); free(dst_name); } #endif break; } case S_IFDIR: res = mkdir(file_header->name, file_header->mode); if ((res == -1) && (errno != EISDIR) /* btw, Linux doesn't return this */ && (errno != EEXIST) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { bb_perror_msg("can't make dir %s", file_header->name); } break; case S_IFLNK: /* Symlink */ //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) res = symlink(file_header->link_target, file_header->name); if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { bb_perror_msg("can't create %slink " "from %s to %s", "sym", file_header->name, file_header->link_target); } break; case S_IFSOCK: case S_IFBLK: case S_IFCHR: case S_IFIFO: res = mknod(file_header->name, file_header->mode, file_header->device); if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { bb_perror_msg("can't create node %s", file_header->name); } break; default: bb_error_msg_and_die("unrecognized file type"); } if (!S_ISLNK(file_header->mode)) { if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_OWNER)) { uid_t uid = file_header->uid; gid_t gid = file_header->gid; #if ENABLE_FEATURE_TAR_UNAME_GNAME if (!(archive_handle->ah_flags & ARCHIVE_NUMERIC_OWNER)) { if (file_header->tar__uname) { //TODO: cache last name/id pair? struct passwd *pwd = getpwnam(file_header->tar__uname); if (pwd) uid = pwd->pw_uid; } if (file_header->tar__gname) { struct group *grp = getgrnam(file_header->tar__gname); if (grp) gid = grp->gr_gid; } } #endif /* GNU tar 1.15.1 uses chown, not lchown */ chown(file_header->name, uid, gid); } /* uclibc has no lchmod, glibc is even stranger - * it has lchmod which seems to do nothing! * so we use chmod... */ if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) { chmod(file_header->name, file_header->mode); } if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) { struct timeval t[2]; t[1].tv_sec = t[0].tv_sec = file_header->mtime; t[1].tv_usec = t[0].tv_usec = 0; utimes(file_header->name, t); } } ret: ; #if ENABLE_FEATURE_TAR_SELINUX if (sctx) { /* reset the context after creating an entry */ setfscreatecon(NULL); } #endif }
/* * test_rwflag(int i, int cnt) * Validate the mount system call for rwflags. */ int test_rwflag(int i, int cnt) { int ret, fd, pid, status; char nobody_uid[] = "nobody"; time_t atime; struct passwd *ltpuser; struct stat file_stat; switch (i) { case 0: /* Validate MS_RDONLY flag of mount call */ snprintf(file, PATH_MAX, "%stmp", path_name); fd = open(file, O_CREAT | O_RDWR, S_IRWXU); if (fd == -1) { if (errno == EROFS) { return 0; } else { tst_resm(TWARN | TERRNO, "open didn't fail with EROFS"); return 1; } } close(fd); return 1; case 1: /* Validate MS_NODEV flag of mount call */ snprintf(file, PATH_MAX, "%smynod_%d_%d", path_name, getpid(), cnt); if (mknod(file, S_IFBLK | 0777, 0) == 0) { fd = open(file, O_RDWR, S_IRWXU); if (fd == -1) { if (errno == EACCES) { return 0; } else { tst_resm(TWARN | TERRNO, "open didn't fail with EACCES"); return 1; } } close(fd); } else { tst_resm(TWARN | TERRNO, "mknod(2) failed to create %s", file); return 1; } return 1; case 2: /* Validate MS_NOEXEC flag of mount call */ snprintf(file, PATH_MAX, "%stmp1", path_name); fd = open(file, O_CREAT | O_RDWR, S_IRWXU); if (fd == -1) { tst_resm(TWARN | TERRNO, "opening %s failed", file); } else { close(fd); ret = execlp(file, basename(file), NULL); if ((ret == -1) && (errno == EACCES)) return 0; } return 1; case 3: /* * Validate MS_SYNCHRONOUS flag of mount call. * Copy some data into data buffer. */ strcpy(write_buffer, "abcdefghijklmnopqrstuvwxyz"); /* Creat a temporary file under above directory */ snprintf(file, PATH_MAX, "%s%s", path_name, TEMP_FILE); fildes = open(file, O_RDWR | O_CREAT, FILE_MODE); if (fildes == -1) { tst_resm(TWARN | TERRNO, "open(%s, O_RDWR|O_CREAT, %#o) failed", file, FILE_MODE); return 1; } /* Write the buffer data into file */ if (write(fildes, write_buffer, strlen(write_buffer)) != strlen(write_buffer)) { tst_resm(TWARN | TERRNO, "writing to %s failed", file); close(fildes); return 1; } /* Set the file ptr to b'nning of file */ if (lseek(fildes, 0, SEEK_SET) < 0) { tst_resm(TWARN, "lseek() failed on %s, error=" " %d", file, errno); close(fildes); return 1; } /* Read the contents of file */ if (read(fildes, read_buffer, sizeof(read_buffer)) > 0) { if (strcmp(read_buffer, write_buffer)) { tst_resm(TWARN, "Data read from %s and written " "mismatch", file); close(fildes); return 1; } else { close(fildes); return 0; } } else { tst_resm(TWARN | TERRNO, "read() Fails on %s", file); close(fildes); return 1; } case 4: /* Validate MS_REMOUNT flag of mount call */ TEST(mount(device, mntpoint, fstype, MS_REMOUNT, NULL)); if (TEST_RETURN != 0) { tst_resm(TWARN | TTERRNO, "mount(2) failed to remount"); return 1; } else { snprintf(file, PATH_MAX, "%stmp2", path_name); fd = open(file, O_CREAT | O_RDWR, S_IRWXU); if (fd == -1) { tst_resm(TWARN, "open(%s) on readonly " "filesystem passed", file); return 1; } else { close(fd); return 0; } } case 5: /* Validate MS_NOSUID flag of mount call */ snprintf(file, PATH_MAX, "%ssetuid_test", path_name); SAFE_FILE_PRINTF(cleanup, file, "TEST FILE"); if (stat(file, &file_stat) < 0) tst_brkm(TBROK, cleanup, "stat for setuid_test failed"); if (file_stat.st_mode != SUID_MODE && chmod(file, SUID_MODE) < 0) tst_brkm(TBROK, cleanup, "setuid for setuid_test failed"); pid = fork(); switch (pid) { case -1: tst_resm(TBROK | TERRNO, "fork failed"); return 1; case 0: ltpuser = getpwnam(nobody_uid); if (setreuid(ltpuser->pw_uid, ltpuser->pw_uid) == -1) tst_resm(TWARN | TERRNO, "seteuid() failed to change euid to %d", ltpuser->pw_uid); execlp(file, basename(file), NULL); exit(1); default: waitpid(pid, &status, 0); if (WIFEXITED(status)) { /* reset the setup_uid */ if (status) return 0; else return 1; } } case 6: /* Validate MS_NOATIME flag of mount call */ snprintf(file, PATH_MAX, "%satime", path_name); fd = open(file, O_CREAT | O_RDWR, S_IRWXU); if (fd == -1) { tst_resm(TWARN | TERRNO, "opening %s failed", file); return 1; } if (write(fd, "TEST_MS_NOATIME", 15) != 15) { tst_resm(TWARN | TERRNO, "write %s failed", file); return 1; } if (fstat(fd, &file_stat) == -1) { tst_resm(TWARN | TERRNO, "stat %s failed #1", file); return 1; } atime = file_stat.st_atime; sleep(1); if (read(fd, NULL, 20) == -1) { tst_resm(TWARN | TERRNO, "read %s failed", file); return 1; } if (fstat(fd, &file_stat) == -1) { tst_resm(TWARN | TERRNO, "stat %s failed #2", file); return 1; } close(fd); if (file_stat.st_atime != atime) { tst_resm(TWARN, "access time is updated"); return 1; } return 0; } return 0; }
int main(int ac, char **av) { int lc; /* loop counter */ int fflag; /* functionality flag variable */ char *msg; /* message returned from parse_opts */ /* Parse standard options given to run the test. */ msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { Tst_count = 0; /* * Call mknod() to creat a node on a directory without * set group-ID (sgid) bit set. */ TEST(mknod(node_name, MODE_RWX, 0)); /* Check return code from mknod(2) */ if (TEST_RETURN == -1) { tst_resm(TFAIL, "mknod(%s, %#o, 0) failed, errno=%d : %s", node_name, MODE_RWX, TEST_ERRNO, strerror(TEST_ERRNO)); continue; } /* * Perform functional verification if test executed * without (-f) option. */ if (STD_FUNCTIONAL_TEST) { /* Set the functionality flag */ fflag = 1; /* Check for node's creation */ if (stat(node_name, &buf) < 0) { tst_resm(TFAIL, "stat() of %s failed, errno:%d", node_name, TEST_ERRNO); /* unset flag as functionality fails */ fflag = 0; } /* Verify mode permissions of node */ if (buf.st_mode & S_ISGID) { tst_resm(TFAIL, "%s: Incorrect modes, setgid " "bit set", node_name); /* unset flag as functionality fails */ fflag = 0; } /* Verify group ID */ if (buf.st_gid != mygid) { tst_resm(TFAIL, "%s: Incorrect group", node_name); /* unset flag as functionality fails */ fflag = 0; } if (fflag) { tst_resm(TPASS, "Functionality of mknod(%s, " "%#o, 0) successful", node_name, MODE_RWX); } } else { tst_resm(TPASS, "call succeeded"); } /* Remove the node for the next go `round */ if (unlink(node_name) == -1) { tst_resm(TWARN, "unlink(%s) failed, errno:%d %s", node_name, errno, strerror(errno)); } } /* Change the directory back to temporary directory */ chdir(".."); /* * Invoke cleanup() to delete the test directories created * in the setup() and exit main(). */ cleanup(); tst_exit(); }
/*================================control_sh() ============================= */ void *control_sh(void *arg) { int a,i; char c; char command[BUFSIZ]; char command_arg[BUFSIZ]; char fifo_file[PATH_MAX +1]; FILE *fp; char readbuf[BUFSIZ]; sprintf(fifo_file, "%s.%d",OSD_FIFO_PATH, getuid()); settings.displaying = 1; /* we open the osd*/ settings.myosd = xosd_create (2); initialize_osd(&settings); load_basic_plugins(); /* create the fifo file*/ unlink(fifo_file); umask(0); mknod(fifo_file, S_IFIFO|0600, 0); /*open and read the fifo*/ while (settings.displaying) { fp = fopen(fifo_file, "r"); /*Read the bufer and check that it's not a comment*/ while(fgets(readbuf, BUFSIZ, fp)) { if (readbuf[c]=='#') continue; /*ignore spaces*/ for (i=0; i<BUFSIZ&&((c=readbuf[i])==' '||c=='\t'); i++); /*get the command*/ for (a=0; (c=readbuf[i])!='\n'&&c!='('; a++,i++) command[a] = readbuf[i]; command[a] = '\0'; /*get the command's arguments*/ i ++; for(a=0; (c=readbuf[i])!='\0'&&c!='\n'&&c!=')';a++,i++) { if (c=='\\') { i++; command_arg[a] = readbuf[i]; } else { command_arg[a]=c; } } command_arg[a] = '\0'; /*execute the command from the fifo and close it*/ display_stuff(command, command_arg); } fclose(fp); } unlink(fifo_file); sprintf(fifo_file, "%s.pid", fifo_file); unlink(fifo_file); xosd_destroy(settings.myosd); exit(0); }
int node_creat(ARCHD *arcn) { int res; int ign = 0; int oerrno; int pass = 0; mode_t file_mode; struct stat sb; char target[MAXPATHLEN]; char *nm = arcn->name; int len; /* * create node based on type, if that fails try to unlink the node and * try again. finally check the path and try again. As noted in the * file and link creation routines, this method seems to exhibit the * best performance in general use workloads. */ file_mode = arcn->sb.st_mode & FILEBITS; for (;;) { switch(arcn->type) { case PAX_DIR: /* * If -h (or -L) was given in tar-mode, follow the * potential symlink chain before trying to create the * directory. */ if (strcmp(NM_TAR, argv0) == 0 && Lflag) { while (lstat(nm, &sb) == 0 && S_ISLNK(sb.st_mode)) { len = readlink(nm, target, sizeof target - 1); if (len == -1) { syswarn(0, errno, "cannot follow symlink %s in chain for %s", nm, arcn->name); res = -1; goto badlink; } target[len] = '\0'; nm = target; } } res = mkdir(nm, file_mode); badlink: if (ign) res = 0; break; case PAX_CHR: file_mode |= S_IFCHR; res = mknod(nm, file_mode, arcn->sb.st_rdev); break; case PAX_BLK: file_mode |= S_IFBLK; res = mknod(nm, file_mode, arcn->sb.st_rdev); break; case PAX_FIF: res = mkfifo(nm, file_mode); break; case PAX_SCK: /* * Skip sockets, operation has no meaning under BSD */ paxwarn(0, "%s skipped. Sockets cannot be copied or extracted", nm); return(-1); case PAX_SLK: res = symlink(arcn->ln_name, nm); break; case PAX_CTG: case PAX_HLK: case PAX_HRG: case PAX_REG: default: /* * we should never get here */ paxwarn(0, "%s has an unknown file type, skipping", nm); return(-1); } /* * if we were able to create the node break out of the loop, * otherwise try to unlink the node and try again. if that * fails check the full path and try a final time. */ if (res == 0) break; /* * we failed to make the node */ oerrno = errno; if ((ign = unlnk_exist(nm, arcn->type)) < 0) return(-1); if (++pass <= 1) continue; if (nodirs || chk_path(nm,arcn->sb.st_uid,arcn->sb.st_gid) < 0) { syswarn(1, oerrno, "Could not create: %s", nm); return(-1); } } /* * we were able to create the node. set uid/gid, modes and times */ if (pids) res = ((arcn->type == PAX_SLK) ? set_lids(nm, arcn->sb.st_uid, arcn->sb.st_gid) : set_ids(nm, arcn->sb.st_uid, arcn->sb.st_gid)); else res = 0; /* * symlinks are done now. */ if (arcn->type == PAX_SLK) return(0); /* * IMPORTANT SECURITY NOTE: * if not preserving mode or we cannot set uid/gid, then PROHIBIT any * set uid/gid bits */ if (!pmode || res) arcn->sb.st_mode &= ~(SETBITS); if (pmode) set_pmode(nm, arcn->sb.st_mode); if (arcn->type == PAX_DIR && strcmp(NM_CPIO, argv0) != 0) { /* * Dirs must be processed again at end of extract to set times * and modes to agree with those stored in the archive. However * to allow extract to continue, we may have to also set owner * rights. This allows nodes in the archive that are children * of this directory to be extracted without failure. Both time * and modes will be fixed after the entire archive is read and * before pax exits. */ if (access(nm, R_OK | W_OK | X_OK) < 0) { if (lstat(nm, &sb) < 0) { syswarn(0, errno,"Could not access %s (stat)", arcn->name); set_pmode(nm,file_mode | S_IRWXU); } else { /* * We have to add rights to the dir, so we make * sure to restore the mode. The mode must be * restored AS CREATED and not as stored if * pmode is not set. */ set_pmode(nm, ((sb.st_mode & FILEBITS) | S_IRWXU)); if (!pmode) arcn->sb.st_mode = sb.st_mode; } /* * we have to force the mode to what was set here, * since we changed it from the default as created. */ add_dir(nm, strlen(nm), &(arcn->sb), 1); } else if (pmode || patime || pmtime) add_dir(nm, strlen(nm), &(arcn->sb), 0); } if (patime || pmtime) set_ftime(nm, arcn->sb.st_mtime, arcn->sb.st_atime, 0); return(0); }
int loop_bind(FILE *image_fp, char **loop_dev, int autoclear) { struct loop_info64 lo64 = {0}; int i; message(DEBUG, "Called loop_bind(image_fp, **{loop_dev)\n"); if ( autoclear > 0 ) { lo64.lo_flags = LO_FLAGS_AUTOCLEAR; } lo64.lo_offset = image_offset(image_fp); for( i=0; i < MAX_LOOP_DEVS; i++ ) { char *test_loopdev = strjoin("/dev/loop", int2str(i)); FILE *loop_fp; if ( is_blk(test_loopdev) < 0 ) { message(VERBOSE, "Creating loop device: %s\n", test_loopdev); if ( mknod(test_loopdev, S_IFBLK | 0644, makedev(7, i)) < 0 ) { message(ERROR, "Could not create %s: %s\n", test_loopdev, strerror(errno)); ABORT(255); } } if ( ( loop_fp = fopen(test_loopdev, "r+") ) == NULL ) { // Flawfinder: ignore (not user modifyable) message(VERBOSE, "Could not open loop device %s: %s\n", test_loopdev, strerror(errno)); continue; } message(VERBOSE2, "Attempting to associate image pointer to loop device\n"); if ( ioctl(fileno(loop_fp), LOOP_SET_FD, fileno(image_fp)) < 0 ) { if ( errno == 16 ) { message(VERBOSE3, "Loop device is in use: %s\n", test_loopdev); fclose(loop_fp); continue; } else { message(WARNING, "Could not associate image to loop %s: %s\n", test_loopdev, strerror(errno)); fclose(loop_fp); continue; } } message(VERBOSE, "Found valid loop device: %s\n", test_loopdev); message(VERBOSE2, "Setting loop device flags\n"); if ( ioctl(fileno(loop_fp), LOOP_SET_STATUS64, &lo64) < 0 ) { fprintf(stderr, "ERROR: Failed to set loop flags on loop device: %s\n", strerror(errno)); (void)ioctl(fileno(loop_fp), LOOP_CLR_FD, 0); (void)loop_free(*loop_dev); ABORT(255); } *loop_dev = strdup(test_loopdev); message(VERBOSE, "Using loop device: %s\n", *loop_dev); message(DEBUG, "Returning loop_bind(image_fp) = 0\n"); return(0); } message(ERROR, "No valid loop devices available\n"); ABORT(255); return(-1); }
void start_sysinit(void) { char buf[PATH_MAX]; struct stat tmp_stat; time_t tm = 0; mknod("/dev/mmc", S_IFBLK | 0660, makedev(126, 0)); mknod("/dev/mmc0", S_IFBLK | 0660, makedev(126, 1)); mknod("/dev/mmc1", S_IFBLK | 0660, makedev(126, 2)); mknod("/dev/mmc2", S_IFBLK | 0660, makedev(126, 3)); mknod("/dev/mmc3", S_IFBLK | 0660, makedev(126, 4)); eval("/bin/tar", "-xzf", "/dev/mtdblock/3", "-C", "/"); FILE *in = fopen("/tmp/nvram/nvram.db", "rb"); if (in != NULL) { fclose(in); eval("/usr/sbin/convertnvram"); eval("/sbin/mtd", "erase", "nvram"); nvram_commit(); } if (!nvram_match("disable_watchdog", "1")) eval("watchdog"); /* * Setup console */ cprintf("sysinit() klogctl\n"); klogctl(8, NULL, atoi(nvram_safe_get("console_loglevel"))); cprintf("sysinit() get router\n"); #ifdef HAVE_RTG32 insmod("slhc"); insmod("ppp_generic"); insmod("ppp_async"); insmod("ppp_synctty"); insmod("ppp_mppe_mppc "); insmod("pppox"); insmod("pppoe"); #endif /* * network drivers */ #ifdef HAVE_HOTPLUG2 insmod("ar231x"); #else insmod("ar2313"); #endif detect_wireless_devices(); eval("ifconfig", "eth0", "up"); // wan system("swconfig dev eth0 set reset 1"); system("swconfig dev eth0 set enable_vlan 1"); #ifdef HAVE_RTG32 system("swconfig dev eth0 vlan 1 set ports \"0t 1 2 3 4\""); system("swconfig dev eth0 vlan 2 set ports \"0t 5\""); #else system("swconfig dev eth0 vlan 1 set ports \"0t 2 3 4 5\""); system("swconfig dev eth0 vlan 2 set ports \"0t 1\""); #endif system("swconfig dev eth0 set apply"); eval("vconfig", "set_name_type", "VLAN_PLUS_VID_NO_PAD"); eval("vconfig", "add", "eth0", "1"); eval("vconfig", "add", "eth0", "2"); struct ifreq ifr; int s; if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) { char eabuf[32]; strncpy(ifr.ifr_name, "eth0", IFNAMSIZ); ioctl(s, SIOCGIFHWADDR, &ifr); char macaddr[32]; strcpy(macaddr, ether_etoa((unsigned char *)ifr.ifr_hwaddr.sa_data, eabuf)); nvram_set("et0macaddr", macaddr); MAC_ADD(macaddr); ether_atoe(macaddr, (unsigned char *)ifr.ifr_hwaddr.sa_data); strncpy(ifr.ifr_name, "vlan2", IFNAMSIZ); ioctl(s, SIOCSIFHWADDR, &ifr); close(s); } eval("gpio", "enable", "1"); #ifdef HAVE_RTG32 writeproc("/proc/sys/dev/wifi0/ledpin", "7"); writeproc("/proc/sys/dev/wifi0/softled", "1"); #else writeproc("/proc/sys/dev/wifi0/ledpin", "0"); writeproc("/proc/sys/dev/wifi0/softled", "1"); #endif /* * Set a sane date */ stime(&tm); nvram_set("wl0_ifname", "ath0"); return; }
static int local_mknod (vfs *me, char *path, int mode, int dev) { return mknod (path, mode, dev); }
int main(int ac, char **av) { int lc; char *msg; char *node_name; /* ptr. for node name created */ char *test_desc; /* test specific error message */ int ind; /* counter to test different test conditions */ msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } /* * Invoke setup function to call individual test setup functions * for the test which run as root/super-user. */ setup(); /* set the expected errnos... */ TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; for (ind = 0; Test_cases[ind].desc != NULL; ind++) { node_name = Test_cases[ind].pathname; test_desc = Test_cases[ind].desc; #if !defined(UCLINUX) if (node_name == High_address_node) { node_name = get_high_address(); } #endif /* * Call mknod(2) to test different test conditions. * verify that it fails with -1 return value and * sets appropriate errno. */ TEST(mknod(node_name, MODE_RWX, 0)); /* Check return code from mknod(2) */ if (TEST_RETURN != -1) { tst_resm(TFAIL, "mknod() returned %ld, expected " "-1, errno:%d", TEST_RETURN, Test_cases[ind].exp_errno); continue; } TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == Test_cases[ind].exp_errno) { tst_resm(TPASS, "mknod() fails, %s, errno:%d", test_desc, TEST_ERRNO); } else { tst_resm(TFAIL, "mknod() fails, %s, errno:%d, " "expected errno:%d", test_desc, TEST_ERRNO, Test_cases[ind].exp_errno); } } } /* * Invoke cleanup() to delete the test directories created * in the setup(). */ cleanup(); tst_exit(); }
static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, struct cr_img *img) { int gfd, ghost_flags, ret; char path[PATH_MAX]; ret = rst_get_mnt_root(gf->remap.rmnt_id, path, sizeof(path)); if (ret < 0) { pr_err("The %d mount is not found for ghost\n", gf->remap.rmnt_id); goto err; } snprintf(path + ret, sizeof(path) - ret, "/%s", gf->remap.rpath); ret = -1; if (S_ISFIFO(gfe->mode)) { if (mknod(path, gfe->mode, 0)) { pr_perror("Can't create node for ghost file"); goto err; } ghost_flags = O_RDWR; /* To not block */ } else if (S_ISCHR(gfe->mode) || S_ISBLK(gfe->mode)) { if (!gfe->has_rdev) { pr_err("No rdev for ghost device\n"); goto err; } if (mknod(path, gfe->mode, gfe->rdev)) { pr_perror("Can't create node for ghost dev"); goto err; } ghost_flags = O_WRONLY; } else if (S_ISDIR(gfe->mode)) { if (mkdir(path, gfe->mode)) { pr_perror("Can't make ghost dir"); goto err; } ghost_flags = O_DIRECTORY; } else ghost_flags = O_WRONLY | O_CREAT | O_EXCL; gfd = open(path, ghost_flags, gfe->mode); if (gfd < 0) { pr_perror("Can't open ghost file %s", path); goto err; } if (fchown(gfd, gfe->uid, gfe->gid) < 0) { pr_perror("Can't reset user/group on ghost %s", path); goto err_c; } if (S_ISREG(gfe->mode)) { if (copy_file(img_raw_fd(img), gfd, 0) < 0) goto err_c; } ret = 0; err_c: close(gfd); err: return ret; }
static int copy_single_file(const char *from, const char *to) { FILE *from_stream, *to_stream; struct stat st; char buf[4096]; size_t len; if (check_the_same(from, to)) { fprintf(stderr, "%s: '%s' is the same as '%s'\n", __func__, from, to); return RecursiveOp_Callback_Error; } if (lstat(from, &st)) { perror("lstat"); return RecursiveOp_Callback_Error; } if (S_ISLNK(st.st_mode)) { /* symbolic links should be copied in special way */ char *link_buffer; int need_free; ssize_t link_len; /* get large enough buffer to read link content */ if (st.st_size < sizeof(buf)) { link_buffer = buf; need_free = 0; } else { link_buffer = MEM_callocN(st.st_size + 2, "copy_single_file link_buffer"); need_free = 1; } link_len = readlink(from, link_buffer, st.st_size + 1); if (link_len < 0) { perror("readlink"); if (need_free) MEM_freeN(link_buffer); return RecursiveOp_Callback_Error; } link_buffer[link_len] = 0; if (symlink(link_buffer, to)) { perror("symlink"); if (need_free) MEM_freeN(link_buffer); return RecursiveOp_Callback_Error; } if (need_free) MEM_freeN(link_buffer); return RecursiveOp_Callback_OK; } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { /* copy special type of file */ if (mknod(to, st.st_mode, st.st_rdev)) { perror("mknod"); return RecursiveOp_Callback_Error; } if (set_permissions(to, &st)) return RecursiveOp_Callback_Error; return RecursiveOp_Callback_OK; } else if (!S_ISREG(st.st_mode)) { fprintf(stderr, "Copying of this kind of files isn't supported yet\n"); return RecursiveOp_Callback_Error; } from_stream = fopen(from, "rb"); if (!from_stream) { perror("fopen"); return RecursiveOp_Callback_Error; } to_stream = fopen(to, "wb"); if (!to_stream) { perror("fopen"); fclose(from_stream); return RecursiveOp_Callback_Error; } while ((len = fread(buf, 1, sizeof(buf), from_stream)) > 0) { fwrite(buf, 1, len, to_stream); } fclose(to_stream); fclose(from_stream); if (set_permissions(to, &st)) return RecursiveOp_Callback_Error; return RecursiveOp_Callback_OK; }
/* * Create the file, or the directory * * fname is the original filename * ofile is the output filename (may be in a different directory) * * Returns: CF_SKIP if file should be skipped * CF_ERROR on error * CF_EXTRACT file created and data to restore * CF_CREATED file created no data to restore * * Note, we create the file here, except for special files, * we do not set the attributes because we want to first * write the file, then when the writing is done, set the * attributes. * So, we return with the file descriptor open for normal * files. * */ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) { mode_t new_mode, parent_mode; int flags; uid_t uid; gid_t gid; int pnl; bool exists = false; struct stat mstatp; bfd->reparse_point = false; if (is_win32_stream(attr->data_stream)) { set_win32_backup(bfd); } else { set_portable_backup(bfd); } new_mode = attr->statp.st_mode; Dmsg3(200, "type=%d newmode=%x file=%s\n", attr->type, new_mode, attr->ofname); parent_mode = S_IWUSR | S_IXUSR | new_mode; gid = attr->statp.st_gid; uid = attr->statp.st_uid; #ifdef HAVE_WIN32 if (!bfd->use_backup_api) { // eliminate invalid windows filename characters from foreign filenames char *ch = (char *)attr->ofname; if (ch[0] != 0 && ch[1] != 0) { ch += 2; while (*ch) { switch (*ch) { case ':': case '<': case '>': case '*': case '?': case '|': *ch = '_'; break; } ch++; } } } #endif Dmsg2(400, "Replace=%c %d\n", (char)replace, replace); if (lstat(attr->ofname, &mstatp) == 0) { exists = true; switch (replace) { case REPLACE_IFNEWER: if (attr->statp.st_mtime <= mstatp.st_mtime) { Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname); return CF_SKIP; } break; case REPLACE_IFOLDER: if (attr->statp.st_mtime >= mstatp.st_mtime) { Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname); return CF_SKIP; } break; case REPLACE_NEVER: Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname); return CF_SKIP; case REPLACE_ALWAYS: break; } } switch (attr->type) { case FT_RAW: /* raw device to be written */ case FT_FIFO: /* FIFO to be written to */ case FT_LNKSAVED: /* Hard linked, file already saved */ case FT_LNK: case FT_SPEC: /* fifo, ... to be backed up */ case FT_REGE: /* empty file */ case FT_REG: /* regular file */ /* * Note, we do not delete FT_RAW because these are device files * or FIFOs that should already exist. If we blow it away, * we may blow away a FIFO that is being used to read the * restore data, or we may blow away a partition definition. */ if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) { /* Get rid of old copy */ Dmsg1(400, "unlink %s\n", attr->ofname); if (unlink(attr->ofname) == -1) { berrno be; Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"), attr->ofname, be.bstrerror()); /* Continue despite error */ } } /* * Here we do some preliminary work for all the above * types to create the path to the file if it does * not already exist. Below, we will split to * do the file type specific work */ pnl = separate_path_and_file(jcr, attr->fname, attr->ofname); if (pnl < 0) { return CF_ERROR; } /* * If path length is <= 0 we are making a file in the root * directory. Assume that the directory already exists. */ if (pnl > 0) { char savechr; savechr = attr->ofname[pnl]; attr->ofname[pnl] = 0; /* terminate path */ if (!path_already_seen(jcr, attr->ofname, pnl)) { Dmsg1(400, "Make path %s\n", attr->ofname); /* * If we need to make the directory, ensure that it is with * execute bit set (i.e. parent_mode), and preserve what already * exists. Normally, this should do nothing. */ if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) { Dmsg1(10, "Could not make path. %s\n", attr->ofname); attr->ofname[pnl] = savechr; /* restore full name */ return CF_ERROR; } } attr->ofname[pnl] = savechr; /* restore full name */ } /* Now we do the specific work for each file type */ switch(attr->type) { case FT_REGE: case FT_REG: Dmsg1(100, "Create=%s\n", attr->ofname); flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /* O_NOFOLLOW; */ if (IS_CTG(attr->statp.st_mode)) { flags |= O_CTG; /* set contiguous bit if needed */ } if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); bclose(bfd); } if ((bopen(bfd, attr->ofname, flags, S_IRUSR | S_IWUSR)) < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(100,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; #ifndef HAVE_WIN32 // none of these exists on MS Windows case FT_RAW: /* Bacula raw device e.g. /dev/sda1 */ case FT_FIFO: /* Bacula fifo to save data */ case FT_SPEC: if (S_ISFIFO(attr->statp.st_mode)) { Dmsg1(400, "Restore fifo: %s\n", attr->ofname); if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) { berrno be; Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } } else if (S_ISSOCK(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname); #ifdef S_IFDOOR // Solaris high speed RPC mechanism } else if (S_ISDOOR(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of door file: %s\n", attr->ofname); #endif #ifdef S_IFPORT // Solaris event port for handling AIO } else if (S_ISPORT(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname); #endif } else { Dmsg1(400, "Restore node: %s\n", attr->ofname); if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) { berrno be; Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } } /* * Here we are going to attempt to restore to a FIFO, which * means that the FIFO must already exist, AND there must * be some process already attempting to read from the * FIFO, so we open it write-only. */ if (attr->type == FT_RAW || attr->type == FT_FIFO) { btimer_t *tid; Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname); flags = O_WRONLY | O_BINARY; /* Timeout open() in 60 seconds */ if (attr->type == FT_FIFO) { Dmsg0(400, "Set FIFO timer\n"); tid = start_thread_timer(jcr, pthread_self(), 60); } else { tid = NULL; } if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); } Dmsg2(400, "open %s flags=0x%x\n", attr->ofname, flags); if ((bopen(bfd, attr->ofname, flags, 0)) < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(400, "Could not open %s: ERR=%s\n", attr->ofname, be.bstrerror()); stop_thread_timer(tid); return CF_ERROR; } stop_thread_timer(tid); return CF_EXTRACT; } Dmsg1(400, "FT_SPEC %s\n", attr->ofname); return CF_CREATED; case FT_LNK: Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname); if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) { berrno be; Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } return CF_CREATED; case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname); if (link(attr->olname, attr->ofname) != 0) { berrno be; #ifdef HAVE_CHFLAGS struct stat s; /* * If using BSD user flags, maybe has a file flag * preventing this. So attempt to disable, retry link, * and reset flags. * Note that BSD securelevel may prevent disabling flag. */ if (stat(attr->olname, &s) == 0 && s.st_flags != 0) { if (chflags(attr->olname, 0) == 0) { if (link(attr->olname, attr->ofname) != 0) { /* restore original file flags even when linking failed */ if (chflags(attr->olname, s.st_flags) < 0) { Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } #endif /* HAVE_CHFLAGS */ Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); Dmsg3(200, "Could not hard link %s -> %s: ERR=%s\n", attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; #ifdef HAVE_CHFLAGS } /* finally restore original file flags */ if (chflags(attr->olname, s.st_flags) < 0) { Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } } else { Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } } else { Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } #endif /* HAVE_CHFLAGS */ } return CF_CREATED; #endif } /* End inner switch */ case FT_REPARSE: bfd->reparse_point = true; /* Fall through wanted */ case FT_DIRBEGIN: case FT_DIREND: Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname); if (!makepath(attr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) { return CF_ERROR; } /* * If we are using the Win32 Backup API, we open the * directory so that the security info will be read * and saved. */ if (!is_portable_backup(bfd)) { if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); } if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) { berrno be; be.set_errno(bfd->berrno); #ifdef HAVE_WIN32 /* Check for trying to create a drive, if so, skip */ if (attr->ofname[1] == ':' && IsPathSeparator(attr->ofname[2]) && attr->ofname[3] == '\0') { return CF_SKIP; } #endif Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; } else { return CF_CREATED; } case FT_DELETED: Qmsg2(jcr, M_INFO, 0, _("Original file %s have been deleted: type=%d\n"), attr->fname, attr->type); break; /* The following should not occur */ case FT_NOACCESS: case FT_NOFOLLOW: case FT_NOSTAT: case FT_DIRNOCHG: case FT_NOCHG: case FT_ISARCH: case FT_NORECURSE: case FT_NOFSCHG: case FT_NOOPEN: Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type); break; default: Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname); break; } return CF_ERROR; }
void process_chunk(void) { yaffs_ObjectHeader oh; yaffs_PackedTags2 *pt; object *obj, *eq_obj; int out_file, remain, s; oh = *(yaffs_ObjectHeader *)chunk_data; pt = (yaffs_PackedTags2 *)spare_data; if (pt->t.byteCount == 0xffffffff) /* empty object */ return; else if (pt->t.byteCount != 0xffff) { /* not a new object */ prt_err(0, 0, "Warning: Invalid header at chunk #%d, skipping...", chunk_no); if (++warn_count >= MAX_WARN) prt_err(1, 0, "Giving up"); return; } obj = add_object(&oh, pt); /* listing */ if (opt_verbose) prt_node(obj->path_name, &oh); else if (opt_list) printf("%s\n", obj->path_name); if (opt_list) { if (oh.type == YAFFS_OBJECT_TYPE_FILE) { remain = oh.fileSize; /* skip over data chunks */ while(remain > 0) { if (!read_chunk()) prt_err(1, 0, "Broken image file"); remain -= pt->t.byteCount; } } return; } switch(oh.type) { case YAFFS_OBJECT_TYPE_FILE: remain = oh.fileSize; out_file = creat(obj->path_name, oh.yst_mode & STD_PERMS); if (out_file < 0) prt_err(1, errno, "Can't create file %s", obj->path_name); while(remain > 0) { if (!read_chunk()) prt_err(1, 0, "Broken image file"); s = (remain < pt->t.byteCount) ? remain : pt->t.byteCount; if (xwrite(out_file, chunk_data, s) < 0) prt_err(1, errno, "Can't write to %s", obj->path_name); remain -= s; } close(out_file); lchown(obj->path_name, oh.yst_uid, oh.yst_gid); if ((oh.yst_mode & EXTRA_PERMS) != 0 && chmod(obj->path_name, oh.yst_mode) < 0) prt_err(0, errno, "Warning: Can't chmod %s", obj->path_name); break; case YAFFS_OBJECT_TYPE_SYMLINK: if (symlink(oh.alias, obj->path_name) < 0) prt_err(1, errno, "Can't create symlink %s", obj->path_name); lchown(obj->path_name, oh.yst_uid, oh.yst_gid); break; case YAFFS_OBJECT_TYPE_DIRECTORY: if (pt->t.objectId != YAFFS_OBJECTID_ROOT && mkdir(obj->path_name, oh.yst_mode & STD_PERMS) < 0) prt_err(1, errno, "Can't create directory %s", obj->path_name); lchown(obj->path_name, oh.yst_uid, oh.yst_gid); if ((pt->t.objectId == YAFFS_OBJECTID_ROOT || (oh.yst_mode & EXTRA_PERMS) != 0) && chmod(obj->path_name, oh.yst_mode) < 0) prt_err(0, errno, "Warning: Can't chmod %s", obj->path_name); break; case YAFFS_OBJECT_TYPE_HARDLINK: eq_obj = get_object(oh.equivalentObjectId); if (eq_obj == NULL) prt_err(1, 0, "Invalid equivalentObjectId %u in object %u (%s)", oh.equivalentObjectId, pt->t.objectId, oh.name); if (link(eq_obj->path_name, obj->path_name) < 0) prt_err(1, errno, "Can't create hardlink %s", obj->path_name); break; case YAFFS_OBJECT_TYPE_SPECIAL: if (mknod(obj->path_name, oh.yst_mode, oh.yst_rdev) < 0) { if (errno == EPERM || errno == EINVAL) prt_err(0, errno, "Warning: Can't create device %s", obj->path_name); else prt_err(1, errno, "Can't create device %s", obj->path_name); } lchown(obj->path_name, oh.yst_uid, oh.yst_gid); break; case YAFFS_OBJECT_TYPE_UNKNOWN: break; } /* set file date and time */ switch(oh.type) { case YAFFS_OBJECT_TYPE_FILE: case YAFFS_OBJECT_TYPE_SPECIAL: #ifdef HAS_LUTIMES case YAFFS_OBJECT_TYPE_SYMLINK: #endif set_utime(obj->path_name, oh.yst_atime, oh.yst_mtime); break; case YAFFS_OBJECT_TYPE_DIRECTORY: default: break; } }
/* * DESCRIPTION: * Create a file if it does not already exist. This function will also * create any missing directories. If the file already exists * this function will return success. * PARAMS: * ctx_t * IN - context object * upath_t IN - fully qualified file name * mode_t IN - permissions to set for file * RETURNS: * success - 0 * error - -1 */ int create_file( ctx_t *ctx, /* ARGSUSED */ char *full_path) { struct stat64 buf; char dupfile[MAXPATHLEN+1]; char *path; mode_t mode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; Trace(TR_MISC, "creating file %s", full_path); if (ISNULL(full_path)) { Trace(TR_ERR, "creating file failed: %d %s", samerrno, samerrmsg); return (-1); } if (stat64(full_path, &buf) != 0) { if (ENOENT == errno) { /* file doesn't exist. */ strlcpy(dupfile, full_path, sizeof (dupfile)); path = dirname(dupfile); if (create_dir(NULL, path) != 0) { Trace(TR_ERR, "creating file %s failed: %s", full_path, samerrmsg); return (-1); } /* create the file */ if (mknod(full_path, mode, NULL) != 0) { samerrno = SE_CREATE_FILE_FAILED; snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(SE_CREATE_FILE_FAILED), full_path, ""); strlcat(samerrmsg, strerror(errno), MAX_MSG_LEN); Trace(TR_ERR, "creating file %s failed: %s", full_path, samerrmsg); return (-1); } } else { samerrno = SE_CREATE_FILE_FAILED; snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(SE_CREATE_FILE_FAILED), full_path, ""); strlcat(samerrmsg, strerror(errno), MAX_MSG_LEN); Trace(TR_ERR, "creating file %s failed: %s", full_path, samerrmsg); return (-1); } } else { /* check that it is not a directory */ if (S_ISDIR(buf.st_mode)) { snprintf(samerrmsg, MAX_MSG_LEN, GetCustMsg(SE_CREATE_FILE_FAILED), full_path, ""); strlcat(samerrmsg, strerror(EISDIR), MAX_MSG_LEN); Trace(TR_ERR, "creating file %s failed: %s", full_path, samerrmsg); return (-1); } } return (0); }
/*! test the file system features */ static int test_fs_features(int *f) { #define TESTFILE1 ".__discofs_test_1__" #define TESTFILE2 ".__discofs_test_2__" char *p, *p2; struct stat st, st2; struct timespec times[2]; VERBOSE("testing remote fs features\n"); /* create test file */ p = remote_path(TESTFILE1); p2 = remote_path(TESTFILE2); if (mknod(p, S_IFREG | S_IRUSR | S_IWUSR, 0)) { perror("failed to create feature test file"); return -1; } #if HAVE_UTIMENSAT && HAVE_CLOCK_GETTIME /* test if timestamps support nanosecond presicion */ /* set atime of file to 0, 1337 */ times[0].tv_sec = 0; times[0].tv_nsec = 1337; utimensat(-1, p, times, AT_SYMLINK_NOFOLLOW); /* get stat */ if (stat(p, &st)) { perror("failed to stat feature test file"); return -1; } /* check if nanoseconds were actually being set */ if (st.st_mtim.tv_nsec == times[0].tv_nsec) *f |= FEAT_NS; #endif #if HAVE_SETXATTR /* test if extended attributes are supported */ if (lsetxattr(p, "user.discofs_test", "1", 1, 0) == 0 || errno != ENOTSUP) *f |= FEAT_XATTR; #endif /* test if hard links are supported */ if (link(p, p2) == 0) { lstat(p, &st); lstat(p2, &st2); if (st.st_ino == st2.st_ino) *f |= FEAT_HARDLINKS; unlink(p2); } else perror("creating hardlink:\n"); /* remove test files */ unlink(p); unlink(p2); free(p); free(p2); return 0; #undef TESTFILE1 #undef TESTFILE2 }
int main(void) { // variable declaration int fd; pid_t pidRED, pidGRN, pidBLU, pidRead; // Create the named pipe mknod(PIPE_NAME, S_IFIFO | 0666, 0); // Opens the named pipe for both reading and writing fd = open(PIPE_NAME, O_RDWR | O_NDELAY ); // Child process that writes 'RED' to the pipe pidRED = fork(); if (pidRED == 0) { printf("Pid %d (red) started\n", getpid()); writeColours(fd, "RED"); // Write to the pipe exit(1); // ends the child process } // Child process that writes 'GRN' to the pipe pidGRN = fork(); if (pidGRN == 0) { printf("Pid %d (green) started\n", getpid()); writeColours(fd, "GRN"); // Writes to the pipe exit(1); // ends the child process } // Child process that writes 'BLU' to the pipe pidBLU = fork(); if (pidBLU == 0) { printf("Pid %d (blue) started\n", getpid()); writeColours(fd, "BLU"); // Writes to the pipe exit(1); // ends the child process } // Child process that reads the data from the pipe // and tallies up the totals pidRead = fork(); if (pidRead == 0) { // Variables to keep track of totals written by each process int nbrOfRed = 0, nbrOfGreen = 0, nbrOfBlue = 0; // Variable to hold the data read in from the pipe char data[4]; // Calculate the system time 5 seconds from now time_t endTime = time(0) + 5; // Runs loop for 5 seconds while(time(0) < endTime) { // Reads in the data from the pipe read(fd, &data, 4); // Determines which process wrote to the pipe // Increments the variable that's tallying the total if (!strcmp(data, "RED")) { nbrOfRed++; } else if (!strcmp(data, "GRN")) { nbrOfGreen++; } else if (!strcmp(data, "BLU")) { nbrOfBlue++; } // Determine how many seconds the process has left to run double oldDiff = difftime(endTime, time(0)); double newDiff; // The difference in how many seconds the process has left // Will change every 1 second // This is used as a measure to know when to print // Out the progress of the race while( newDiff != oldDiff && oldDiff != 0) { printProgress(nbrOfRed, nbrOfGreen, nbrOfBlue); newDiff = difftime(endTime, time(0)); break; } } // Close the pipe close(fd); // Print the final messages for each process printf("\n"); // line break printFinalMessage("red", nbrOfRed); printFinalMessage("green", nbrOfGreen); printFinalMessage("blue", nbrOfBlue); } return 0; }
static int test_fn(int argc, char **argv) { FILE *f; int fd, tmpfs_fd; unsigned fs_cnt, fs_cnt_last = 0; struct ns_exec_args args; mode_t old_mask; pid_t pid = -1; if (!getenv("ZDTM_REEXEC")) { setenv("ZDTM_REEXEC", "1", 0); return execv(argv[0], argv); } else test_init(argc, argv); close(0); /* /dev/null */ again: fs_cnt = 0; f = fopen("/proc/self/mountinfo", "r"); if (!f) { fail("Can't open mountinfo"); return -1; } if (mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL)) { err("Can't remount / with MS_PRIVATE"); return -1; } while (fgets(buf, sizeof(buf), f) != NULL) { char *mp = buf, *end; mp = strchr(mp, ' ') + 1; mp = strchr(mp, ' ') + 1; mp = strchr(mp, ' ') + 1; mp = strchr(mp, ' ') + 1; end = strchr(mp, ' '); *end = '\0'; if (!strcmp(mp, "/")) continue; if (!strcmp(mp, "/proc")) continue; if (umount(mp)) test_msg("umount(`%s') failed: %m\n", mp); fs_cnt++; } fclose(f); if (fs_cnt == 0) goto done; if (fs_cnt != fs_cnt_last) { fs_cnt_last = fs_cnt; goto again; } fail("Can't umount all the filesystems"); return -1; done: rmdir(MPTS_ROOT); if (mkdir(MPTS_ROOT, 0600) < 0) { fail("Can't make zdtm_sys"); return 1; } if (mount("none", MPTS_ROOT, "sysfs", 0, "") < 0) { fail("Can't mount sysfs"); return 1; } if (mount("none", MPTS_ROOT"/dev", "tmpfs", 0, "") < 0) { fail("Can't mount tmpfs"); return 1; } tmpfs_fd = open(MPTS_ROOT"/dev/test", O_WRONLY | O_CREAT); if (write(tmpfs_fd, "hello", 5) <= 0) { err("write() failed"); return 1; } /* Check that over-mounted files are restored on tmpfs */ mkdir(MPTS_ROOT"/dev/overmount", 0600); fd = open(MPTS_ROOT"/dev/overmount/test.over", O_WRONLY | O_CREAT); if (fd == -1) { err("Unable to open "MPTS_ROOT"/dev/overmount\n"); return -1; } close(fd); if (mount("none", MPTS_ROOT"/dev/overmount", "tmpfs", 0, "") < 0) { err("Can't mount "MPTS_ROOT"/dev/overmount\n"); return 1; } mkdir(MPTS_ROOT"/dev/non-root", 0600); if (mount(MPTS_ROOT"/dev/non-root", MPTS_ROOT"/module", NULL, MS_BIND, NULL) < 0) { err("Can't bind-mount %s -> %s", MPTS_ROOT"/dev/tdir", MPTS_ROOT"/module"); } mkdir(MPTS_ROOT"/dev/non-root/test", 0600); mkdir(MPTS_ROOT"/dev/share-1", 0600); if (mount("none", MPTS_ROOT"/dev/share-1/", "tmpfs", 0, "") < 0) { fail("Can't mount tmpfs"); return 1; } if (mount("none", MPTS_ROOT"/dev/share-1/", NULL, MS_SHARED, NULL) < 0) { fail("Can't mount tmpfs"); return 1; } //#define CR_NEXT #ifdef CR_NEXT mkdir(MPTS_ROOT"/dev/share-1/alone", 0600); if (mount("none", MPTS_ROOT"/dev/share-1/alone", "tmpfs", 0, "") < 0) { fail("Can't mount tmpfs"); return 1; } #endif mkdir(MPTS_ROOT"/dev/share-2", 0600); if (mount(MPTS_ROOT"/dev/share-1", MPTS_ROOT"/dev/share-2", NULL, MS_BIND, NULL) < 0) { fail("Can't bind mount a tmpfs directory"); return 1; } mkdir(MPTS_ROOT"/dev/share-3", 0600); if (mount(MPTS_ROOT"/dev/share-1", MPTS_ROOT"/dev/share-3", NULL, MS_BIND, NULL) < 0) { fail("Can't bind mount a tmpfs directory"); return 1; } mkdir(MPTS_ROOT"/dev/slave", 0600); if (mount(MPTS_ROOT"/dev/share-1", MPTS_ROOT"/dev/slave", NULL, MS_BIND, NULL) < 0) { fail("Can't bind mount a tmpfs directory"); return 1; } if (mount("none", MPTS_ROOT"/dev/slave", NULL, MS_SLAVE, NULL) < 0) { fail("Can't mount tmpfs"); return 1; } mkdir(MPTS_ROOT"/dev/slave2", 0600); if (mount(MPTS_ROOT"/dev/share-3", MPTS_ROOT"/dev/slave2", NULL, MS_BIND, NULL) < 0) { fail("Can't bind mount a tmpfs directory"); return 1; } if (mount("none", MPTS_ROOT"/dev/slave2", NULL, MS_SLAVE, NULL) < 0) { fail("Can't mount tmpfs"); return 1; } mkdir(MPTS_ROOT"/dev/share-1/test.mnt.share", 0600); if (mount("none", MPTS_ROOT"/dev/share-1/test.mnt.share", "tmpfs", 0, "size=1G") < 0) { fail("Can't mount tmpfs"); return 1; } mkdir(MPTS_ROOT"/dev/share-1/test.mnt.share/test.share", 0600); if (umount(MPTS_ROOT"/dev/slave2/test.mnt.share")) { err("Can't umount "MPTS_ROOT"/dev/slave2/test.mnt.share: %m"); return 1; } mkdir(MPTS_ROOT"/dev/slave/test.mnt.slave", 0600); if (mount("none", MPTS_ROOT"/dev/slave/test.mnt.slave", "tmpfs", 0, "") < 0) { fail("Can't mount tmpfs"); return 1; } mkdir(MPTS_ROOT"/dev/slave/test.mnt.slave/test.slave", 0600); fd = open(MPTS_ROOT"/dev/bmfile", O_CREAT | O_WRONLY); if (fd < 0) { err("Can't create " MPTS_ROOT "/dev/share-1/bmfile"); return 1; } close(fd); fd = open(MPTS_ROOT"/dev/bmfile-mount", O_CREAT | O_WRONLY); if (fd < 0) { err("Can't create " MPTS_ROOT "/dev/share-1/bmfile"); return 1; } close(fd); if (mount(MPTS_ROOT"/dev/bmfile", MPTS_ROOT"/dev/bmfile-mount", NULL, MS_BIND, NULL) < 0) { fail("Can't mount tmpfs"); return 1; } if (mount("none", MPTS_ROOT"/kernel", "proc", 0, "") < 0) { fail("Can't mount proc"); return 1; } if (mount("none", MPTS_ROOT"/kernel/sys/fs/binfmt_misc", "binfmt_misc", 0, "") < 0) { fail("Can't mount binfmt_misc"); return 1; } unlink("/dev/null"); /* * Clear umask first, create readable & writeable /dev/null, * and change it back. This is done to ensure that file mode * creation mask will not impede it to create file that grants * read and write permission to all users. */ old_mask = umask(0); mknod("/dev/null", 0777 | S_IFCHR, makedev(1, 3)); umask(old_mask); fd = open(MPTS_ROOT"/kernel/meminfo", O_RDONLY); if (fd == -1) return 1; if (getenv("ZDTM_NOSUBNS") == NULL) { pid = clone(ns_child, args.stack_ptr, CLONE_NEWNS | SIGCHLD, &args); if (pid < 0) { err("Unable to fork child"); return 1; } } test_daemon(); test_waitsig(); /* this checks both -- sys and proc presence */ if (access(MPTS_ROOT"/kernel/meminfo", F_OK)) { fail("No proc after restore"); return 1; } if (umount(MPTS_ROOT"/dev/overmount") == -1) { err("Can't umount "MPTS_ROOT"/dev/overmount\n"); return -1; } if (access(MPTS_ROOT"/dev/overmount/test.over", F_OK)) { fail(MPTS_ROOT"/dev/overmount/test.over"); return -1; } { struct stat st1, st2; if (stat(MPTS_ROOT"/dev/share-1/test.mnt.share/test.share", &st1)) { err("Can't stat /dev/share-1/test.share/test.share"); return 1; } if (stat(MPTS_ROOT"/dev/share-2/test.mnt.share/test.share", &st2)) { err("Can't stat /dev/share-2/test.mnt.share/test.share"); return 1; } if (st1.st_ino != st2.st_ino) { fail("/dev/share-1 and /dev/share-1 is not shared"); return 1; } if (stat(MPTS_ROOT"/dev/slave/test.mnt.share/test.share", &st2)) { err("Can't stat /dev/slave/test.mnt.share/test.share"); return 1; } if (st1.st_ino != st2.st_ino) { fail("/dev/slave is not slave of /dev/share-1"); return 1; } if (stat(MPTS_ROOT"/dev/share-1/test.mnt.slave/test.slave", &st1) != -1 || errno != ENOENT) { err("/dev/share-1/test.mnt.slave/test.slave exists"); return 1; } if (stat(MPTS_ROOT"/dev/slave/test.mnt.slave/test.slave", &st2)) { err("Can't stat /dev/slave/test.mnt.slave/test.slave"); return 1; } if (stat(MPTS_ROOT"/dev/non-root/test", &st1)) { err("Can't stat /dev/non-root/test"); return 1; } } if (pid > 0) { kill(pid, SIGTERM); int status = 1; wait(&status); if (status) return 1; } pass(); return 0; }
// mknod in /dev based on a path like "/sys/block/hda/hda1" static void make_device(char *path) { char *device_name, *s, *temp; int major, minor, type, len, fd; int mode = 0660; uid_t uid = 0; gid_t gid = 0; // Try to read major/minor string temp = strrchr(path, '/'); fd = open(path, O_RDONLY); *temp=0; temp = toybuf; len = read(fd, temp, 64); close(fd); if (len<1) return; temp[len] = 0; // Determine device name, type, major and minor device_name = strrchr(path, '/') + 1; type = path[5]=='c' ? S_IFCHR : S_IFBLK; major = minor = 0; sscanf(temp, "%u:%u", &major, &minor); // If we have a config file, look up permissions for this device if (CFG_MDEV_CONF) { char *conf, *pos, *end; // mmap the config file if (-1!=(fd = open("/etc/mdev.conf", O_RDONLY))) { len = fdlength(fd); conf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); if (conf) { int line = 0; // Loop through lines in mmaped file for (pos = conf; pos-conf<len;) { int field; char *end2; line++; // find end of this line for(end = pos; end-conf<len && *end!='\n'; end++); // Three fields: regex, uid:gid, mode for (field = 3; field; field--) { // Skip whitespace while (pos<end && isspace(*pos)) pos++; if (pos==end || *pos=='#') break; for (end2 = pos; end2<end && !isspace(*end2) && *end2!='#'; end2++); switch(field) { // Regex to match this device case 3: { char *regex = strndup(pos, end2-pos); regex_t match; regmatch_t off; int result; // Is this it? xregcomp(&match, regex, REG_EXTENDED); result=regexec(&match, device_name, 1, &off, 0); regfree(&match); free(regex); // If not this device, skip rest of line if (result || off.rm_so || off.rm_eo!=strlen(device_name)) goto end_line; break; } // uid:gid case 2: { char *s2; // Find : for(s = pos; s<end2 && *s!=':'; s++); if (s==end2) goto end_line; // Parse UID uid = strtoul(pos,&s2,10); if (s!=s2) { struct passwd *pass; char *str = strndup(pos, s-pos); pass = getpwnam(str); free(str); if (!pass) goto end_line; uid = pass->pw_uid; } s++; // parse GID gid = strtoul(s,&s2,10); if (end2!=s2) { struct group *grp; char *str = strndup(s, end2-s); grp = getgrnam(str); free(str); if (!grp) goto end_line; gid = grp->gr_gid; } break; } // mode case 1: { mode = strtoul(pos, &pos, 8); if (pos!=end2) goto end_line; goto found_device; } } pos=end2; } end_line: // Did everything parse happily? if (field && field!=3) error_exit("Bad line %d", line); // Next line pos = ++end; } found_device: munmap(conf, len); } close(fd); } } sprintf(temp, "/dev/%s", device_name); if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST) perror_exit("mknod %s failed", temp); if (CFG_MDEV_CONF) mode=chown(temp, uid, gid); }
int fifo_make (char const *fn, unsigned int mode) { return mknod(fn, S_IFIFO | mode, 0) ; }
static int create_item(Item *i) { int r, e; mode_t u; struct stat st; assert(i); switch (i->type) { case IGNORE_PATH: case REMOVE_PATH: case RECURSIVE_REMOVE_PATH: return 0; case CREATE_FILE: case TRUNCATE_FILE: case WRITE_FILE: { int fd, flags; flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND : i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0; u = umask(0); label_context_set(i->path, S_IFREG); fd = open(i->path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode); e = errno; label_context_clear(); umask(u); errno = e; if (fd < 0) { if (i->type == WRITE_FILE && errno == ENOENT) break; log_error("Failed to create file %s: %m", i->path); return -errno; } if (i->argument) { ssize_t n; size_t l; struct iovec iovec[2]; static const char new_line = '\n'; l = strlen(i->argument); zero(iovec); iovec[0].iov_base = i->argument; iovec[0].iov_len = l; iovec[1].iov_base = (void*) &new_line; iovec[1].iov_len = 1; n = writev(fd, iovec, 2); /* It's OK if we don't write the trailing * newline, hence we check for l, instead of * l+1 here. Files in /sys often refuse * writing of the trailing newline. */ if (n < 0 || (size_t) n < l) { log_error("Failed to write file %s: %s", i->path, n < 0 ? strerror(-n) : "Short write"); close_nointr_nofail(fd); return n < 0 ? n : -EIO; } } close_nointr_nofail(fd); if (stat(i->path, &st) < 0) { log_error("stat(%s) failed: %m", i->path); return -errno; } if (!S_ISREG(st.st_mode)) { log_error("%s is not a file.", i->path); return -EEXIST; } r = item_set_perms(i, i->path); if (r < 0) return r; break; } case TRUNCATE_DIRECTORY: case CREATE_DIRECTORY: u = umask(0); mkdir_parents_label(i->path, 0755); r = mkdir(i->path, i->mode); umask(u); if (r < 0 && errno != EEXIST) { log_error("Failed to create directory %s: %m", i->path); return -errno; } if (stat(i->path, &st) < 0) { log_error("stat(%s) failed: %m", i->path); return -errno; } if (!S_ISDIR(st.st_mode)) { log_error("%s is not a directory.", i->path); return -EEXIST; } r = item_set_perms(i, i->path); if (r < 0) return r; break; case CREATE_FIFO: u = umask(0); r = mkfifo(i->path, i->mode); umask(u); if (r < 0 && errno != EEXIST) { log_error("Failed to create fifo %s: %m", i->path); return -errno; } if (stat(i->path, &st) < 0) { log_error("stat(%s) failed: %m", i->path); return -errno; } if (!S_ISFIFO(st.st_mode)) { log_error("%s is not a fifo.", i->path); return -EEXIST; } r = item_set_perms(i, i->path); if (r < 0) return r; break; case CREATE_SYMLINK: { char *x; label_context_set(i->path, S_IFLNK); r = symlink(i->argument, i->path); e = errno; label_context_clear(); errno = e; if (r < 0 && errno != EEXIST) { log_error("symlink(%s, %s) failed: %m", i->argument, i->path); return -errno; } r = readlink_malloc(i->path, &x); if (r < 0) { log_error("readlink(%s) failed: %s", i->path, strerror(-r)); return -errno; } if (!streq(i->argument, x)) { free(x); log_error("%s is not the right symlinks.", i->path); return -EEXIST; } free(x); break; } case CREATE_BLOCK_DEVICE: case CREATE_CHAR_DEVICE: { mode_t file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR); u = umask(0); label_context_set(i->path, file_type); r = mknod(i->path, i->mode | file_type, i->major_minor); e = errno; label_context_clear(); umask(u); errno = e; if (r < 0 && errno != EEXIST) { log_error("Failed to create device node %s: %m", i->path); return -errno; } if (stat(i->path, &st) < 0) { log_error("stat(%s) failed: %m", i->path); return -errno; } if ((st.st_mode & S_IFMT) != file_type) { log_error("%s is not a device node.", i->path); return -EEXIST; } r = item_set_perms(i, i->path); if (r < 0) return r; break; } case RELABEL_PATH: r = glob_item(i, item_set_perms); if (r < 0) return 0; break; case RECURSIVE_RELABEL_PATH: r = glob_item(i, recursive_relabel); if (r < 0) return r; } log_debug("%s created successfully.", i->path); return 0; }
int copy_file(const char *source, const char *dest, int flags) { struct stat source_stat; struct stat dest_stat; int dest_exists = 0; int status = 0; if ((!(flags & FILEUTILS_DEREFERENCE) && lstat(source, &source_stat) < 0) || ((flags & FILEUTILS_DEREFERENCE) && stat(source, &source_stat) < 0)) { bb_perror_msg("%s", source); return -1; } if (lstat(dest, &dest_stat) < 0) { if (errno != ENOENT) { bb_perror_msg("unable to stat `%s'", dest); return -1; } } else { if (source_stat.st_dev == dest_stat.st_dev && source_stat.st_ino == dest_stat.st_ino) { bb_error_msg("`%s' and `%s' are the same file", source, dest); return -1; } dest_exists = 1; } if (S_ISDIR(source_stat.st_mode)) { DIR *dp; struct dirent *d; mode_t saved_umask = 0; if (!(flags & FILEUTILS_RECUR)) { bb_error_msg("%s: omitting directory", source); return -1; } /* Create DEST. */ if (dest_exists) { if (!S_ISDIR(dest_stat.st_mode)) { bb_error_msg("`%s' is not a directory", dest); return -1; } } else { mode_t mode; saved_umask = umask(0); mode = source_stat.st_mode; if (!(flags & FILEUTILS_PRESERVE_STATUS)) mode = source_stat.st_mode & ~saved_umask; mode |= S_IRWXU; if (mkdir(dest, mode) < 0) { umask(saved_umask); bb_perror_msg("cannot create directory `%s'", dest); return -1; } umask(saved_umask); } /* Recursively copy files in SOURCE. */ if ((dp = bb_opendir(source)) == NULL) { status = -1; goto preserve_status; } while ((d = readdir(dp)) != NULL) { char *new_source, *new_dest; new_source = concat_subpath_file(source, d->d_name); if(new_source == NULL) continue; new_dest = concat_path_file(dest, d->d_name); if (copy_file(new_source, new_dest, flags) < 0) status = -1; free(new_source); free(new_dest); } /* closedir have only EBADF error, but "dp" not changes */ closedir(dp); if (!dest_exists && chmod(dest, source_stat.st_mode & ~saved_umask) < 0) { bb_perror_msg("unable to change permissions of `%s'", dest); status = -1; } } else if (S_ISREG(source_stat.st_mode) || (S_ISLNK(source_stat.st_mode) && (flags & FILEUTILS_DEREFERENCE))) { int src_fd; int dst_fd; if (ENABLE_FEATURE_PRESERVE_HARDLINKS) { char *link_name; if (!(flags & FILEUTILS_DEREFERENCE) && is_in_ino_dev_hashtable(&source_stat, &link_name)) { if (link(link_name, dest) < 0) { bb_perror_msg("unable to link `%s'", dest); return -1; } return 0; } add_to_ino_dev_hashtable(&source_stat, dest); } src_fd = open(source, O_RDONLY); if (src_fd == -1) { bb_perror_msg("unable to open `%s'", source); return(-1); } if (dest_exists) { if (flags & FILEUTILS_INTERACTIVE) { fprintf(stderr, "%s: overwrite `%s'? ", bb_applet_name, dest); if (!bb_ask_confirmation()) { close (src_fd); return 0; } } dst_fd = open(dest, O_WRONLY|O_TRUNC); if (dst_fd == -1) { if (!(flags & FILEUTILS_FORCE)) { bb_perror_msg("unable to open `%s'", dest); close(src_fd); return -1; } if (unlink(dest) < 0) { bb_perror_msg("unable to remove `%s'", dest); close(src_fd); return -1; } goto dest_removed; } } else { dest_removed: dst_fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode); if (dst_fd == -1) { bb_perror_msg("unable to open `%s'", dest); close(src_fd); return(-1); } } if (bb_copyfd_eof(src_fd, dst_fd) == -1) status = -1; if (close(dst_fd) < 0) { bb_perror_msg("unable to close `%s'", dest); status = -1; } if (close(src_fd) < 0) { bb_perror_msg("unable to close `%s'", source); status = -1; } } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) || S_ISLNK(source_stat.st_mode)) { if (dest_exists) { if((flags & FILEUTILS_FORCE) == 0) { fprintf(stderr, "`%s' exists\n", dest); return -1; } if(unlink(dest) < 0) { bb_perror_msg("unable to remove `%s'", dest); return -1; } } if (S_ISFIFO(source_stat.st_mode)) { if (mkfifo(dest, source_stat.st_mode) < 0) { bb_perror_msg("cannot create fifo `%s'", dest); return -1; } } else if (S_ISLNK(source_stat.st_mode)) { char *lpath; lpath = xreadlink(source); if (symlink(lpath, dest) < 0) { bb_perror_msg("cannot create symlink `%s'", dest); return -1; } free(lpath); if (flags & FILEUTILS_PRESERVE_STATUS) if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0) bb_perror_msg("unable to preserve ownership of `%s'", dest); return 0; } else { if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { bb_perror_msg("unable to create `%s'", dest); return -1; } } } else { bb_error_msg("internal error: unrecognized file type"); return -1; } preserve_status: if (flags & FILEUTILS_PRESERVE_STATUS) { struct utimbuf times; char *msg="unable to preserve %s of `%s'"; times.actime = source_stat.st_atime; times.modtime = source_stat.st_mtime; if (utime(dest, ×) < 0) bb_perror_msg(msg, "times", dest); if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { source_stat.st_mode &= ~(S_ISUID | S_ISGID); bb_perror_msg(msg, "ownership", dest); } if (chmod(dest, source_stat.st_mode) < 0) bb_perror_msg(msg, "permissions", dest); } return status; }
int copy_file(const char *source, const char *dest, int flags) { struct stat source_stat; struct stat dest_stat; int dest_exists = 1; int status = 0; if (((flags & FILEUTILS_PRESERVE_SYMLINKS) && lstat(source, &source_stat) < 0) || (!(flags & FILEUTILS_PRESERVE_SYMLINKS) && stat(source, &source_stat) < 0)) { perror_msg("%s", source); return -1; } if (stat(dest, &dest_stat) < 0) { if (errno != ENOENT) { perror_msg("unable to stat `%s'", dest); return -1; } dest_exists = 0; } if (dest_exists && source_stat.st_rdev == dest_stat.st_rdev && source_stat.st_ino == dest_stat.st_ino) { error_msg("`%s' and `%s' are the same file", source, dest); return -1; } if (S_ISDIR(source_stat.st_mode)) { DIR *dp; struct dirent *d; mode_t saved_umask = 0; if (!(flags & FILEUTILS_RECUR)) { error_msg("%s: omitting directory", source); return -1; } /* Create DEST. */ if (dest_exists) { if (!S_ISDIR(dest_stat.st_mode)) { error_msg("`%s' is not a directory", dest); return -1; } } else { mode_t mode; saved_umask = umask(0); mode = source_stat.st_mode; if (!(flags & FILEUTILS_PRESERVE_STATUS)) mode = source_stat.st_mode & ~saved_umask; mode |= S_IRWXU; if (mkdir(dest, mode) < 0) { umask(saved_umask); perror_msg("cannot create directory `%s'", dest); return -1; } umask(saved_umask); } /* Recursively copy files in SOURCE. */ if ((dp = opendir(source)) == NULL) { perror_msg("unable to open directory `%s'", source); status = -1; goto end; } while ((d = readdir(dp)) != NULL) { char *new_source, *new_dest; if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) continue; new_source = concat_path_file(source, d->d_name); new_dest = concat_path_file(dest, d->d_name); if (copy_file(new_source, new_dest, flags) < 0) status = -1; free(new_source); free(new_dest); } /* ??? What if an error occurs in readdir? */ if (closedir(dp) < 0) { perror_msg("unable to close directory `%s'", source); status = -1; } if (!dest_exists && chmod(dest, source_stat.st_mode & ~saved_umask) < 0) { perror_msg("unable to change permissions of `%s'", dest); status = -1; } } else if (S_ISREG(source_stat.st_mode)) { FILE *sfp, *dfp; if (dest_exists) { if ((dfp = fopen(dest, "w")) == NULL) { if (!(flags & FILEUTILS_FORCE)) { perror_msg("unable to open `%s'", dest); return -1; } if (unlink(dest) < 0) { perror_msg("unable to remove `%s'", dest); return -1; } dest_exists = 0; } } if (!dest_exists) { int fd; if ((fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode)) < 0 || (dfp = fdopen(fd, "w")) == NULL) { if (fd >= 0) close(fd); perror_msg("unable to open `%s'", dest); return -1; } } if ((sfp = fopen(source, "r")) == NULL) { fclose(dfp); perror_msg("unable to open `%s'", source); status = -1; goto end; } if (copy_file_chunk(sfp, dfp, -1) < 0) status = -1; if (fclose(dfp) < 0) { perror_msg("unable to close `%s'", dest); status = -1; } if (fclose(sfp) < 0) { perror_msg("unable to close `%s'", source); status = -1; } } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || S_ISSOCK(source_stat.st_mode)) { if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { perror_msg("unable to create `%s'", dest); return -1; } } else if (S_ISFIFO(source_stat.st_mode)) { if (mkfifo(dest, source_stat.st_mode) < 0) { perror_msg("cannot create fifo `%s'", dest); return -1; } } else if (S_ISLNK(source_stat.st_mode)) { char *lpath = xreadlink(source); if (symlink(lpath, dest) < 0) { perror_msg("cannot create symlink `%s'", dest); return -1; } free(lpath); #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) if (flags & FILEUTILS_PRESERVE_STATUS) if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0) perror_msg("unable to preserve ownership of `%s'", dest); #endif return 0; } else { error_msg("internal error: unrecognized file type"); return -1; } end: if (flags & FILEUTILS_PRESERVE_STATUS) { struct utimbuf times; times.actime = source_stat.st_atime; times.modtime = source_stat.st_mtime; if (utime(dest, ×) < 0) perror_msg("unable to preserve times of `%s'", dest); if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { source_stat.st_mode &= ~(S_ISUID | S_ISGID); perror_msg("unable to preserve ownership of `%s'", dest); } if (chmod(dest, source_stat.st_mode) < 0) perror_msg("unable to preserve permissions of `%s'", dest); } return status; }
int main(int argc, char *argv[]) { daddr_t diskbn; daddr_t number; struct stat stbuf, devstat; struct dirent *dp; DIR *dirp; char name[2 * MAXPATHLEN]; char *name_dir_end; if (argc < 3) usage(); if (chdir(argv[1]) < 0 || stat(".", &stbuf) < 0) err(2, "%s", argv[1]); strcpy(name, _PATH_DEV); if ((dirp = opendir(name)) == NULL) err(3, "%s", name); name_dir_end = name + strlen(name); while ((dp = readdir(dirp)) != NULL) { strcpy(name_dir_end, dp->d_name); if (lstat(name, &devstat) < 0) err(4, "%s", name); if (stbuf.st_dev == devstat.st_rdev && (devstat.st_mode & IFMT) == IFCHR) break; } closedir(dirp); if (dp == NULL) { printf("Cannot find dev 0%lo corresponding to %s\n", (u_long)stbuf.st_rdev, argv[1]); exit(5); } if (ufs_disk_fillout(&disk, name) == -1) { if (disk.d_error != NULL) errx(6, "%s: %s", name, disk.d_error); else err(7, "%s", name); } for (argc -= 2, argv += 2; argc > 0; argc--, argv++) { number = strtol(*argv, NULL, 0); if (errno == EINVAL || errno == ERANGE) err(8, "%s", *argv); if (chkuse(number, 1)) continue; /* * Print a warning if converting the block number to a dev_t * will truncate it. badsect was not very useful in versions * of BSD before 4.4 because dev_t was 16 bits and another * bit was lost by bogus sign extensions. */ diskbn = dbtofsb(fs, number); if ((dev_t)diskbn != diskbn) { printf("sector %ld cannot be represented as a dev_t\n", (long)number); errs++; } else if (mknod(*argv, IFMT|0600, (dev_t)diskbn) < 0) { warn("%s", *argv); errs++; } } ufs_disk_close(&disk); printf("Don't forget to run ``fsck %s''\n", name); exit(errs); }
static int test_fn(int argc, char **argv) { FILE *f; int fd, tmpfs_fd; unsigned fs_cnt, fs_cnt_last = 0; again: fs_cnt = 0; f = fopen("/proc/self/mountinfo", "r"); if (!f) { fail("Can't open mountinfo"); return -1; } while (fgets(buf, sizeof(buf), f) != NULL) { char *mp = buf, *end; mp = strchr(mp, ' ') + 1; mp = strchr(mp, ' ') + 1; mp = strchr(mp, ' ') + 1; mp = strchr(mp, ' ') + 1; end = strchr(mp, ' '); *end = '\0'; if (!strcmp(mp, "/")) continue; if (!strcmp(mp, "/proc")) continue; umount(mp); fs_cnt++; } fclose(f); if (fs_cnt == 0) goto done; if (fs_cnt != fs_cnt_last) { fs_cnt_last = fs_cnt; goto again; } fail("Can't umount all the filesystems"); return -1; done: rmdir(MPTS_ROOT); if (mkdir(MPTS_ROOT, 0600) < 0) { fail("Can't make zdtm_sys"); return 1; } if (mount("none", MPTS_ROOT, "sysfs", 0, "") < 0) { fail("Can't mount sysfs"); return 1; } if (mount("none", MPTS_ROOT"/dev", "tmpfs", 0, "") < 0) { fail("Can't mount tmpfs"); return 1; } tmpfs_fd = open(MPTS_ROOT"/dev/test", O_WRONLY | O_CREAT); if (write(tmpfs_fd, "hello", 5) <= 0) { err("write() failed"); return 1; } if (mount("none", MPTS_ROOT"/kernel", "proc", 0, "") < 0) { fail("Can't mount proc"); return 1; } if (mount("none", MPTS_ROOT"/kernel/sys/fs/binfmt_misc", "binfmt_misc", 0, "") < 0) { fail("Can't mount proc"); return 1; } mknod("/dev/null", 0777 | S_IFCHR, makedev(1, 3)); setup_outfile(); fd = open(MPTS_ROOT"/kernel/meminfo", O_RDONLY); if (fd == -1) return 1; test_daemon(); test_waitsig(); /* this checks both -- sys and proc presence */ if (access(MPTS_ROOT"/kernel/meminfo", F_OK)) { fail("No proc after restore"); return 1; } pass(); return 0; }