Beispiel #1
0
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();
}
Beispiel #2
0
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;
    }

}
Beispiel #3
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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
}
Beispiel #8
0
/*
 * 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;
}
Beispiel #9
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();
}
Beispiel #10
0
/*================================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);
}
Beispiel #11
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);
}
Beispiel #12
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);
}
Beispiel #13
0
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);
}
Beispiel #15
0
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();
}
Beispiel #16
0
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;
}
Beispiel #17
0
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;
}
Beispiel #18
0
/*
 * 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;
}
Beispiel #19
0
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;
	}
}
Beispiel #20
0
/*
 * 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);
}
Beispiel #21
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
}
Beispiel #22
0
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;
}
Beispiel #23
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;
}
Beispiel #24
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);
}
Beispiel #25
0
int fifo_make (char const *fn, unsigned int mode)
{
  return mknod(fn, S_IFIFO | mode, 0) ;
}
Beispiel #26
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;
}
Beispiel #27
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, &times) < 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;
}
Beispiel #28
0
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, &times) < 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;
}
Beispiel #29
0
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);
}
Beispiel #30
0
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;
}