Exemple #1
0
static int write_ar_header(archive_handle_t *handle)
{
    char *fn;
    char fn_h[17]; /* 15 + "/" + NUL */
    struct stat st;
    int fd;

    fn = llist_pop(&handle->accept);
    if (!fn)
        return -1;

    xstat(fn, &st);

    handle->file_header->mtime = st.st_mtime;
    handle->file_header->uid = st.st_uid;
    handle->file_header->gid = st.st_gid;
    handle->file_header->mode = st.st_mode;
    handle->file_header->size = st.st_size;
    handle->file_header->name = fn_h;
//TODO: if ENABLE_FEATURE_AR_LONG_FILENAMES...
    sprintf(fn_h, "%.15s/", bb_basename(fn));

    output_ar_header(handle);

    fd = xopen(fn, O_RDONLY);
    bb_copyfd_exact_size(fd, handle->src_fd, st.st_size);
    close(fd);
    handle->offset += st.st_size;

    return 0;
}
Exemple #2
0
static int swap_enable_disable(char *device)
{
	int status;
	struct stat st;

	resolve_mount_spec(&device);
	xstat(device, &st);

#if ENABLE_DESKTOP
	/* test for holes */
	if (S_ISREG(st.st_mode))
		if (st.st_blocks * (off_t)512 < st.st_size)
			bb_error_msg("warning: swap file has holes");
#endif

	if (applet_name[5] == 'n')
		status = swapon(device, g_flags);
	else
		status = swapoff(device);

	if (status != 0) {
		bb_simple_perror_msg(device);
		return 1;
	}

	return 0;
}
Exemple #3
0
int	can_access(char *str, int i, int j)
{
  struct stat	sb;

  if (j == 1)
    if (access(str, F_OK) == -1)
      i = 3;
  if (i == 0)
    if (access(str, F_OK) == -1)
      {
	my_putstr(str, 2);
	my_putstr(NO_FILE_DIR, 2);
	return (1);
      }
  if (i == 1)
    {
      xstat(str, &sb);
      if ((sb.st_mode & S_IFMT) == S_IFDIR)
	{
	  my_putstr(str, 2);
	  my_putstr(" : Is a directory.\n", 2);
	  return (1);
	}
    }
  return (0);
}
Exemple #4
0
int is_dir(const char *pathname)
{
	struct stat buf;

	xstat(pathname, &buf);
	if (S_ISDIR(buf.st_mode))
		return 1;
	else
		return 0;
}
int main(void) {
  atexit(cleanup);

  system("rm -fr DIR");

  mkdirs("DIR/a/b");

  struct stat buf;
  xstat("DIR/a/b", &buf);
  assert(S_ISDIR(buf.st_mode));

  exit(EXIT_SUCCESS);
}
Exemple #6
0
/*
 * Read lines from a file stream (normally STDIN)
 * Returns the number of regular files to be watched or -1 if max_files is
 * exceeded
 */
int
process_input(FILE *file, WatchFile *files[], int max_files) {
	char buf[PATH_MAX];
	char *p, *path;
	int n_files = 0;
	struct stat sb;
	int i, matches;

	while (fgets(buf, sizeof(buf), file) != NULL) {
		buf[PATH_MAX-1] = '\0';
		if ((p = strchr(buf, '\n')) != NULL)
			*p = '\0';
		if (buf[0] == '\0')
			continue;

		if (xstat(buf, &sb) == -1) {
			xwarnx("unable to stat '%s'", buf);
			continue;
		}
		if (S_ISREG(sb.st_mode) != 0) {
			files[n_files] = malloc(sizeof(WatchFile));
			strlcpy(files[n_files]->fn, buf, MEMBER_SIZE(WatchFile, fn));
			files[n_files]->is_dir = 0;
			files[n_files]->file_count = 0;
			files[n_files]->mode = sb.st_mode;
			n_files++;
		}
		/* also watch the directory if it's not already in the list */
		if (dirwatch_opt == 1) {
			if (S_ISDIR(sb.st_mode) != 0)
				path = &buf[0];
			else
				if ((path = dirname(buf)) == 0)
					err(1, "dirname '%s' failed", buf);
			for (matches=0, i=0; i<n_files; i++)
				if (strcmp(files[i]->fn, path) == 0) matches++;
			if (matches == 0) {
				files[n_files] = malloc(sizeof(WatchFile));
				strlcpy(files[n_files]->fn, path,
				    MEMBER_SIZE(WatchFile, fn));
				files[n_files]->is_dir = 1;
				files[n_files]->file_count = xlist_dir(path);
				files[n_files]->mode = sb.st_mode;
				n_files++;
			}
		}
		if (n_files+1 > max_files)
			return -1;
	}
	return n_files;
}
Exemple #7
0
static int swap_enable_disable(const char *device)
{
	int status;
	struct stat st;

	xstat(device, &st);

	/* test for holes */
	if (S_ISREG(st.st_mode))
		if (st.st_blocks * 512 < st.st_size)
			bb_error_msg_and_die("swap file has holes");

	if (bb_applet_name[5] == 'n')
		status = swapon(device, 0);
	else
		status = swapoff(device);

	if (status != 0) {
		bb_perror_msg("%s", device);
		return 1;
	}

	return 0;
}
Exemple #8
0
int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned opt;
	char *signame;
	char *startas;
	char *chuid;
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
//	char *retry_arg = NULL;
//	int retries = -1;
	char *opt_N;
#endif

	INIT_G();

	opt = GETOPT32(argv, "^"
		"KSbqtma:n:s:u:c:x:p:"
		IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:")
			/* -K or -S is required; they are mutually exclusive */
			/* -p is required if -m is given */
			/* -xpun (at least one) is required if -K is given */
			/* -xa (at least one) is required if -S is given */
			/* -q turns off -v */
			"\0"
			"K:S:K--S:S--K:m?p:K?xpun:S?xa"
			IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"),
		LONGOPTS
		&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile
		IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
		/* We accept and ignore -R <param> / --retry <param> */
		IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL)
	);

	if (opt & OPT_s) {
		signal_nr = get_signum(signame);
		if (signal_nr < 0) bb_show_usage();
	}

	if (!(opt & OPT_a))
		startas = execname;
	if (!execname) /* in case -a is given and -x is not */
		execname = startas;
	if (execname) {
		G.execname_sizeof = strlen(execname) + 1;
		G.execname_cmpbuf = xmalloc(G.execname_sizeof + 1);
	}

//	IF_FEATURE_START_STOP_DAEMON_FANCY(
//		if (retry_arg)
//			retries = xatoi_positive(retry_arg);
//	)
	//argc -= optind;
	argv += optind;

	if (userspec) {
		user_id = bb_strtou(userspec, NULL, 10);
		if (errno)
			user_id = xuname2uid(userspec);
	}
	/* Both start and stop need to know current processes */
	do_procinit();

	if (opt & CTX_STOP) {
		int i = do_stop();
		return (opt & OPT_OKNODO) ? 0 : (i <= 0);
	}

	if (G.found_procs) {
		if (!QUIET)
			printf("%s is already running\n%u\n", execname, (unsigned)G.found_procs->pid);
		return !(opt & OPT_OKNODO);
	}

#ifdef OLDER_VERSION_OF_X
	if (execname)
		xstat(execname, &G.execstat);
#endif

	*--argv = startas;
	if (opt & OPT_BACKGROUND) {
#if BB_MMU
		bb_daemonize(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS + DAEMON_DOUBLE_FORK);
		/* DAEMON_DEVNULL_STDIO is superfluous -
		 * it's always done by bb_daemonize() */
#else
		/* Daemons usually call bb_daemonize_or_rexec(), but SSD can do
		 * without: SSD is not itself a daemon, it _execs_ a daemon.
		 * The usual NOMMU problem of "child can't run indefinitely,
		 * it must exec" does not bite us: we exec anyway.
		 */
		pid_t pid = xvfork();
		if (pid != 0) {
			/* parent */
			/* why _exit? the child may have changed the stack,
			 * so "return 0" may do bad things */
			_exit(EXIT_SUCCESS);
		}
		/* Child */
		setsid(); /* detach from controlling tty */
		/* Redirect stdio to /dev/null, close extra FDs */
		bb_daemon_helper(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS);
#endif
	}
	if (opt & OPT_MAKEPID) {
		/* User wants _us_ to make the pidfile */
		write_pidfile(pidfile);
	}
	if (opt & OPT_c) {
		struct bb_uidgid_t ugid;
		parse_chown_usergroup_or_die(&ugid, chuid);
		if (ugid.uid != (uid_t) -1L) {
			struct passwd *pw = xgetpwuid(ugid.uid);
			if (ugid.gid != (gid_t) -1L)
				pw->pw_gid = ugid.gid;
			/* initgroups, setgid, setuid: */
			change_identity(pw);
		} else if (ugid.gid != (gid_t) -1L) {
			xsetgid(ugid.gid);
			setgroups(1, &ugid.gid);
		}
	}
#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
	if (opt & OPT_NICELEVEL) {
		/* Set process priority */
		int prio = getpriority(PRIO_PROCESS, 0) + xatoi_range(opt_N, INT_MIN/2, INT_MAX/2);
		if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
			bb_perror_msg_and_die("setpriority(%d)", prio);
		}
	}
#endif
	execvp(startas, argv);
	bb_perror_msg_and_die("can't execute '%s'", startas);
}
Exemple #9
0
int fuser_main(int argc UNUSED_PARAM, char **argv)
{
	// changed for ofgwrite
	applet_name = argv[0];
	char **pp;

	INIT_G();

	/* Handle -SIGNAL. Oh my... */
	pp = argv;
	while (*++pp) {
		int sig;
		char *arg = *pp;

		if (arg[0] != '-')
			continue;
		if (arg[1] == '-' && arg[2] == '\0') /* "--" */
			break;
		if ((arg[1] == '4' || arg[1] == '6') && arg[2] == '\0')
			continue; /* it's "-4" or "-6" */
		sig = get_signum(&arg[1]);
		if (sig < 0)
			continue;
		/* "-SIGNAL" option found. Remove it and bail out */
		G.killsig = sig;
		do {
			pp[0] = arg = pp[1];
			pp++;
		} while (arg);
		break;
	}

	opt_complementary = "-1"; /* at least one param */
	getopt32(argv, OPTION_STRING);
	argv += optind;

	pp = argv;
	while (*pp) {
		/* parse net arg */
		unsigned port;
		char path[sizeof("/proc/net/TCP6")];

		strcpy(path, "/proc/net/");
		if (sscanf(*pp, "%u/%4s", &port, path + sizeof("/proc/net/")-1) == 2
		 && access(path, R_OK) == 0
		) {
			/* PORT/PROTO */
			scan_proc_net_or_maps(path, port);
		} else {
			/* FILE */
			struct stat statbuf;
			xstat(*pp, &statbuf);
			add_inode(&statbuf);
		}
		pp++;
	}

	if (scan_recursive("/proc")) {
		if (!(option_mask32 & OPT_SILENT))
			bb_putchar('\n');
		return G.kill_failed;
	}

	return EXIT_FAILURE;
}
Exemple #10
0
/*
 * Wait for events to and execute a command. Four major concerns are in play:
 *   leading_edge: Global reference to the first file to have changed
 *   reopen_only : Unlink or rename events which require us to spin while
 *                 waiting for the file to reappear. These must always be
 *                 processed
 *   collate_only: Changes that indicate that more events are likely to occur.
 *                 Watch for more events using a short timeout
 *   do_exec     : Delay execution until all events have been processed. Allow
 *                 the user to edit files while the utility is running without
 *                 any visible side-effects
 *   dir_modified: The number of files changed for a directory under watch
 */
void
watch_loop(int kq, char *argv[]) {
	struct kevent evSet;
	struct kevent evList[32];
	int nev;
	WatchFile *file;
	int i;
	struct timespec evTimeout = { 0, 1000000 };
	int reopen_only = 0;
	int collate_only = 0;
	int do_exec = 0;
	int dir_modified = 0;
	int leading_edge_set = 0;
	struct stat sb;

	leading_edge = files[0]; /* default */
	if (postpone_opt == 0)
		run_utility(argv);

main:
	if ((reopen_only == 1) || (collate_only == 1))
		nev = xkevent(kq, NULL, 0, evList, 32, &evTimeout);
	else {
		nev = xkevent(kq, NULL, 0, evList, 32, NULL);
		dir_modified = 0;
	}
	/* escape for test runner */
	if ((nev == -2) && (collate_only == 0))
		return;

	for (i=0; i<nev; i++) {
		if (evList[i].filter != EVFILT_VNODE)
			continue;
		file = (WatchFile *)evList[i].udata;
		if (file->is_dir == 1)
			dir_modified += compare_dir_contents(file);
		else if (leading_edge_set == 0)
			if ((reopen_only == 0) && (collate_only == 0)) {
				leading_edge = file;
				leading_edge_set = 1;
			}
	}

	collate_only = 0;
	for (i=0; i<nev; i++) {
		file = (WatchFile *)evList[i].udata;
		if (evList[i].fflags & NOTE_DELETE ||
		    evList[i].fflags & NOTE_RENAME) {
			EV_SET(&evSet, file->fd, EVFILT_VNODE, EV_DELETE,
			    NOTE_ALL, 0, file);
			if (xkevent(kq, &evSet, 1, NULL, 0, NULL) == -1)
				err(1, "failed to remove VNODE event");
			if ((file->fd != -1) && (close(file->fd) == -1))
				err(1, "unable to close file");
			watch_file(kq, file);
			collate_only = 1;
		}
	}
	if (reopen_only == 1) {
		reopen_only = 0;
		goto main;
	}

	for (i=0; i<nev && reopen_only == 0; i++) {
		file = (WatchFile *)evList[i].udata;
		if ((file->is_dir == 1) && (dir_modified == 0))
			continue;
		if (evList[i].fflags & NOTE_DELETE ||
		    evList[i].fflags & NOTE_WRITE  ||
		    evList[i].fflags & NOTE_RENAME ||
		    evList[i].fflags & NOTE_TRUNCATE) {
			if ((dir_modified > 0) && (restart_opt == 1))
				continue;
			do_exec = 1;
		}
		if (evList[i].fflags & NOTE_ATTRIB &&
		    S_ISREG(file->mode) != 0 &&
		    xstat(file->fn, &sb) == 0 &&
		    file->mode != sb.st_mode) {
			do_exec = 1;
			file->mode = sb.st_mode;
		}
	}

	if (collate_only == 1)
		goto main;
	if (do_exec == 1) {
		do_exec = 0;
		run_utility(argv);
		reopen_only = 1;
		leading_edge_set = 0;
	}
	if (dir_modified > 0) {
		terminate_utility();
		xerrx(2, "directory altered");
	}

	goto main;
}
Exemple #11
0
static int run_pipe(const char *pager, char *man_filename, int man, int level)
{
	char *cmd;

	/* Prevent man page link loops */
	if (level > 10)
		return 0;

	if (access(man_filename, R_OK) != 0)
		return 0;

	if (option_mask32 & OPT_w) {
		puts(man_filename);
		return 1;
	}

	if (man) { /* man page, not cat page */
		/* Is this a link to another manpage? */
		/* The link has the following on the first line: */
		/* ".so another_man_page" */

		struct stat sb;
		char *line;
		char *linkname, *p;

		/* On my system:
		 * man1/genhostid.1.gz: 203 bytes - smallest real manpage
		 * man2/path_resolution.2.gz: 114 bytes - largest link
		 */
		xstat(man_filename, &sb);
		if (sb.st_size > 300) /* err on the safe side */
			goto ordinary_manpage;

		line = xmalloc_open_zipped_read_close(man_filename, NULL);
		if (!line || strncmp(line, ".so ", 4) != 0) {
			free(line);
			goto ordinary_manpage;
		}
		/* Example: man2/path_resolution.2.gz contains
		 * ".so man7/path_resolution.7\n<junk>"
		 */
		*strchrnul(line, '\n') = '\0';
		linkname = skip_whitespace(&line[4]);

		/* If link has no slashes, we just replace man page name.
		 * If link has slashes (however many), we go back *once*.
		 * ".so zzz/ggg/page.3" does NOT go back two levels. */
		p = strrchr(man_filename, '/');
		if (!p)
			goto ordinary_manpage;
		*p = '\0';
		if (strchr(linkname, '/')) {
			p = strrchr(man_filename, '/');
			if (!p)
				goto ordinary_manpage;
			*p = '\0';
		}

		/* Links do not have .gz extensions, even if manpage
		 * is compressed */
		man_filename = xasprintf("%s/%s", man_filename, linkname);
		free(line);
		/* Note: we leak "new" man_filename string as well... */
		if (show_manpage(pager, man_filename, man, level + 1))
			return 1;
		/* else: show the link, it's better than nothing */
	}

 ordinary_manpage:
	close(STDIN_FILENO);
	open_zipped(man_filename, /*fail_if_not_compressed:*/ 0); /* guaranteed to use fd 0 (STDIN_FILENO) */
	/* "2>&1" is added so that nroff errors are shown in pager too.
	 * Otherwise it may show just empty screen */
	cmd = xasprintf(
		/* replaced -Tlatin1 with -Tascii for non-UTF8 displays */
		man ? "gtbl | nroff -Tascii -mandoc 2>&1 | %s"
		    : "%s",
		pager);
	system(cmd);
	free(cmd);
	return 1;
}
Exemple #12
0
int fuser_main(int argc UNUSED_PARAM, char **argv)
{
	pid_list *plist;
	pid_t mypid;
	char **pp;
	struct stat st;
	unsigned port;
	int opt;
	int exitcode;
	int killsig;
/*
fuser [OPTIONS] FILE or PORT/PROTO
Find processes which use FILEs or PORTs
        -m      Find processes which use same fs as FILEs
        -4      Search only IPv4 space
        -6      Search only IPv6 space
        -s      Don't display PIDs
        -k      Kill found processes
        -SIGNAL Signal to send (default: KILL)
*/
	/* Handle -SIGNAL. Oh my... */
	killsig = SIGKILL; /* yes, the default is not SIGTERM */
	pp = argv;
	while (*++pp) {
		char *arg = *pp;
		if (arg[0] != '-')
			continue;
		if (arg[1] == '-' && arg[2] == '\0') /* "--" */
			break;
		if ((arg[1] == '4' || arg[1] == '6') && arg[2] == '\0')
			continue; /* it's "-4" or "-6" */
		opt = get_signum(&arg[1]);
		if (opt < 0)
			continue;
		/* "-SIGNAL" option found. Remove it and bail out */
		killsig = opt;
		do {
			pp[0] = arg = pp[1];
			pp++;
		} while (arg);
		break;
	}

	opt_complementary = "-1"; /* at least one param */
	opt = getopt32(argv, OPTION_STRING);
	argv += optind;

	pp = argv;
	while (*pp) {
		/* parse net arg */
		char path[20], tproto[5];
		if (sscanf(*pp, "%u/%4s", &port, tproto) != 2)
			goto file;
		sprintf(path, "/proc/net/%s", tproto);
		if (access(path, R_OK) != 0) { /* PORT/PROTO */
			scan_proc_net(path, port);
		} else { /* FILE */
 file:
			xstat(*pp, &st);
			add_inode(&st);
		}
		pp++;
	}

	scan_proc_pids(); /* changes dir to "/proc" */

	mypid = getpid();
	plist = G.pid_list_head;
	while (1) {
		if (!plist)
			return EXIT_FAILURE;
		if (plist->pid != mypid)
			break;
		plist = plist->next;
	}

	exitcode = EXIT_SUCCESS;
	do {
		if (plist->pid != mypid) {
			if (opt & OPT_KILL) {
				if (kill(plist->pid, killsig) != 0) {
					bb_perror_msg("kill pid %u", (unsigned)plist->pid);
					exitcode = EXIT_FAILURE;
				}
			}
			if (!(opt & OPT_SILENT)) {
				printf("%u ", (unsigned)plist->pid);
			}
		}
		plist = plist->next;
	} while (plist);

	if (!(opt & (OPT_SILENT))) {
		bb_putchar('\n');
	}

	return exitcode;
}
Exemple #13
0
int run_parts(char **args, const unsigned char test_mode, char **env)
{
	struct dirent **namelist = 0;
	struct stat st;
	char *filename;
	char *arg0 = args[0];
	int entries;
	int i;
	int exitstatus = 0;

#if __GNUC__
	/* Avoid longjmp clobbering */
	(void) &i;
	(void) &exitstatus;
#endif
	/* scandir() isn't POSIX, but it makes things easy. */
	entries = scandir(arg0, &namelist, valid_name, alphasort);

	if (entries == -1) {
		if (test_mode & 2) {
			return(2);
		}
		bb_perror_msg_and_die("failed to open directory %s", arg0);
	}

	for (i = 0; i < entries; i++) {

		filename = concat_path_file(arg0, namelist[i]->d_name);

		xstat(filename, &st);
		if (S_ISREG(st.st_mode) && !access(filename, X_OK)) {
			if (test_mode) {
				puts(filename);
			} else {
				/* exec_errno is common vfork variable */
				volatile int exec_errno = 0;
				int result;
				int pid;

				if ((pid = vfork()) < 0) {
					bb_perror_msg_and_die("failed to fork");
				} else if (!pid) {
					args[0] = filename;
					execve(filename, args, env);
					exec_errno = errno;
					_exit(1);
				}

				waitpid(pid, &result, 0);
				if(exec_errno) {
					errno = exec_errno;
					bb_perror_msg("failed to exec %s", filename);
					exitstatus = 1;
				}
				if (WIFEXITED(result) && WEXITSTATUS(result)) {
					bb_perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result));
					exitstatus = 1;
				} else if (WIFSIGNALED(result)) {
					bb_perror_msg("%s exited because of uncaught signal %d", filename, WTERMSIG(result));
					exitstatus = 1;
				}
			}
		}
		else if (!S_ISDIR(st.st_mode)) {
			bb_error_msg("component %s is not an executable plain file", filename);
			exitstatus = 1;
		}

		free(namelist[i]);
		free(filename);
	}
	free(namelist);

	return(exitstatus);
}
Exemple #14
0
string
xgetcwd (void)
{
    /* If the system provides getcwd, use it.  If not, use getwd if
       available.  But provide a way not to use getcwd: on some systems
       getcwd forks, which is expensive and may in fact be impossible for
       large programs like tex.  If your system needs this define and it
       is not detected by configure, let me know.
                                       -- Olaf Weber <[email protected] */
#if defined (HAVE_GETCWD) && !defined (GETCWD_FORKS)
    char path[PATH_MAX + 1];
#if defined(WIN32)
    string pp;
#endif

    if (getcwd (path, PATH_MAX + 1) == NULL) {
        FATAL_PERROR ("getcwd");
    }

#if defined(WIN32)
    for (pp = path; *pp; pp++) {
        if (*pp == '\\')
            *pp = '/';
#if defined (KPSE_COMPAT_API)
        else if (IS_KANJI(pp))
            pp++;
#endif
    }
#endif

    return xstrdup (path);
#elif defined (HAVE_GETWD)
    char path[PATH_MAX + 1];

    if (getwd (path) == NULL) {
        FATAL_PERROR ("getwd");
    }

    return xstrdup (path);
#else /* (not HAVE_GETCWD || GETCWD_FORKS) && not HAVE_GETWD */
    struct stat root_stat, cwd_stat;
    string cwd_path = (string)xmalloc(2); /* In case we assign "/" below.  */

    *cwd_path = 0;

    /* Find the inodes of the root and current directories.  */
    root_stat = xstat("/");
    cwd_stat  = xstat(".");

    /* Go up the directory hierarchy until we get to root, prepending each
       directory we pass through to `cwd_path'.  */
    while (!SAME_FILE_P(root_stat, cwd_stat)) {
        struct dirent *e;
        DIR *parent_dir;
        boolean found = false;

        xchdir("..");
        parent_dir = xopendir(".");

        /* Look through the parent directory for the entry with the same
           inode, so we can get its name.  */
        while ((e = readdir (parent_dir)) != NULL && !found) {
            struct stat test_stat;
            test_stat = xlstat(e->d_name);

            if (SAME_FILE_P(test_stat, cwd_stat)) {
                /* We've found it.  Prepend the pathname.  */
                string temp = cwd_path;
                cwd_path = concat3("/", e->d_name, cwd_path);
                free(temp);

                /* Set up to test the next parent.  */
                cwd_stat = xstat(".");

                /* Stop reading this directory.  */
                found = true;
            }
        }
        if (!found)
            LIB_FATAL2("No inode %d/device %d in parent directory",
                   cwd_stat.st_ino, cwd_stat.st_dev);

        xclosedir(parent_dir);
    }

    /* If the current directory is the root, cwd_path will be the empty
       string, and we will have not gone through the loop.  */
    if (*cwd_path == 0)
        strcpy(cwd_path, "/");
    else
        /* Go back to where we were.  */
        xchdir(cwd_path);

#ifdef DOSISH
    /* Prepend the drive letter to CWD_PATH, since this technique
       never tells us what the drive is.

       Note that on MS-DOS/MS-Windows, the branch that works around
       missing `getwd' will probably only work for DJGPP (which does
       have `getwd'), because only DJGPP reports meaningful
       st_ino numbers.  But someday, somebody might need this...  */
    {
        char drive[3];
        string temp = cwd_path;

        /* Make the drive letter lower-case, unless it is beyond Z: (yes,
           there ARE such drives, in case of Novell Netware on MS-DOS).  */
        drive[0] = root_stat.st_dev + (root_stat.st_dev < 26 ? 'a' : 'A');
        drive[1] = ':';
        drive[2] = '\0';

        cwd_path = concat(drive, cwd_path);
        free(temp);
    }
#endif

    return cwd_path;
#endif /* (not HAVE_GETCWD || GETCWD_FORKS) && not HAVE_GETWD */
}
Exemple #15
0
static void
compile_dex_with_dexopt(const char* dex_file_name,
                        const char* odex_file_name)
{
    SCOPED_RESLIST(rl);

    int dex_file = xopen(dex_file_name, O_RDONLY, 0);
    const char* odex_temp_filename = xaprintf(
        "%s.tmp.%s",
        odex_file_name,
        gen_hex_random(ENOUGH_ENTROPY));
    cleanup_commit(cleanup_allocate(), cleanup_tmpfile, odex_temp_filename);
    int odex_temp_file = xopen(odex_temp_filename,
                               O_RDWR | O_CREAT | O_EXCL,
                               0644);

    allow_inherit(dex_file);
    allow_inherit(odex_temp_file);

    struct child_start_info csi = {
        .io[0] = CHILD_IO_DEV_NULL,
        .io[1] = CHILD_IO_PIPE,
        .io[2] = CHILD_IO_DUP_TO_STDOUT,
        .exename = "dexopt",
        .argv = ARGV(
            "dexopt",
            "--zip",
            xaprintf("%d", dex_file),
            xaprintf("%d", odex_temp_file),
            dex_file_name,
            "v=ao=fm=y"),
    };

    struct child* dexopt = child_start(&csi);
    struct growable_buffer output = slurp_fd_buf(dexopt->fd[1]->fd);
    int status = child_status_to_exit_code(child_wait(dexopt));
    if (status != 0)
        die(EINVAL,
            "dexopt failed: %s",
            massage_output_buf(output));

    xrename(odex_temp_filename, odex_file_name);
}

static void
compile_dex(const char* dex_file_name,
            const char* odex_file_name)
{
    if (api_level() < 21)
        compile_dex_with_dexopt(dex_file_name, odex_file_name);
}

int
rdex_main(const struct cmd_rdex_info* info)
{
    const char* dex_file_name = info->dexfile;
    struct stat dex_stat = xstat(dex_file_name);
    const char* odex_file_name = make_odex_name(dex_file_name);

    bool need_recompile = true;

    struct stat odex_stat;
    if (stat(odex_file_name, &odex_stat) == 0 &&
        dex_stat.st_mtime <= odex_stat.st_mtime)
    {
        need_recompile = false;
    }

    (void) need_recompile;
    (void) odex_file_name;
    (void) compile_dex;

    if (need_recompile)
        compile_dex(dex_file_name, odex_file_name);

    if (setenv("CLASSPATH", dex_file_name, 1) == -1)
        die_errno("setenv");

    if (info->classname[0] == '-')
        die(EINVAL, "class name cannot begin with '-'");

    execvp("app_process",
           (char* const*)
           ARGV_CONCAT(
               ARGV("app_process",
                    xdirname(dex_file_name),
                    info->classname),
               info->args ?: empty_argv));
    die_errno("execvp(\"app_process\", ...");
}
Exemple #16
0
int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
{
	static const struct suffix_mult size_suffixes[] = {
		{ "KiB", 1024 },
		{ "MiB", 1024*1024 },
		{ "GiB", 1024*1024*1024 },
		{ "", 0 }
	};

	unsigned opts;
	char *ubi_ctrl;
	int fd;
	int mtd_num;
	int dev_num = UBI_DEV_NUM_AUTO;
	int vol_id = UBI_VOL_NUM_AUTO;
	char *vol_name;
	unsigned long long size_bytes = size_bytes; /* for compiler */
	char *size_bytes_str;
	int alignment = 1;
	char *type;
	union {
		struct ubi_attach_req attach_req;
		struct ubi_mkvol_req  mkvol_req;
		struct ubi_rsvol_req  rsvol_req;
	} req_structs;
#define attach_req req_structs.attach_req
#define mkvol_req  req_structs.mkvol_req
#define rsvol_req  req_structs.rsvol_req
	char path[sizeof("/sys/class/ubi/ubi%d_%d/usable_eb_size")
				+ 2 * sizeof(int)*3 + /*just in case:*/ 16];
#define path_sys_class_ubi_ubi (path + sizeof("/sys/class/ubi/ubi")-1)

	strcpy(path, "/sys/class/ubi/ubi");
	memset(&req_structs, 0, sizeof(req_structs));

	if (do_mkvol) {
		opt_complementary = "-1:d+:n+:a+";
		opts = getopt32(argv, "md:n:N:s:a:t:",
				&dev_num, &vol_id,
				&vol_name, &size_bytes_str, &alignment, &type
			);
	} else {
		opt_complementary = "-1:m+:d+:n+:a+";
		opts = getopt32(argv, "m:d:n:N:s:a:t:",
				&mtd_num, &dev_num, &vol_id,
				&vol_name, &size_bytes_str, &alignment, &type
		);
	}
#define OPTION_m  (1 << 0)
#define OPTION_d  (1 << 1)
#define OPTION_n  (1 << 2)
#define OPTION_N  (1 << 3)
#define OPTION_s  (1 << 4)
#define OPTION_a  (1 << 5)
#define OPTION_t  (1 << 6)

	if (opts & OPTION_s)
		size_bytes = xatoull_sfx(size_bytes_str, size_suffixes);
	argv += optind;
	ubi_ctrl = *argv++;

	fd = xopen(ubi_ctrl, O_RDWR);
	//xfstat(fd, &st, ubi_ctrl);
	//if (!S_ISCHR(st.st_mode))
	//	bb_error_msg_and_die("%s: not a char device", ubi_ctrl);

//usage:#define ubiattach_trivial_usage
//usage:       "-m MTD_NUM [-d UBI_NUM] UBI_CTRL_DEV"
//usage:#define ubiattach_full_usage "\n\n"
//usage:       "Attach MTD device to UBI\n"
//usage:     "\n	-m MTD_NUM	MTD device number to attach"
//usage:     "\n	-d UBI_NUM	UBI device number to assign"
	if (do_attach) {
		if (!(opts & OPTION_m))
			bb_error_msg_and_die("%s device not specified", "MTD");

		attach_req.mtd_num = mtd_num;
		attach_req.ubi_num = dev_num;

		xioctl(fd, UBI_IOCATT, &attach_req);
	} else

//usage:#define ubidetach_trivial_usage
//usage:       "-d UBI_NUM UBI_CTRL_DEV"
//usage:#define ubidetach_full_usage "\n\n"
//usage:       "Detach MTD device from UBI\n"
//usage:     "\n	-d UBI_NUM	UBI device number"
	if (do_detach) {
		if (!(opts & OPTION_d))
			bb_error_msg_and_die("%s device not specified", "UBI");

		/* FIXME? kernel expects int32_t* here: */
		xioctl(fd, UBI_IOCDET, &dev_num);
	} else

//usage:#define ubimkvol_trivial_usage
//usage:       "UBI_DEVICE -N NAME [-s SIZE | -m]"
//usage:#define ubimkvol_full_usage "\n\n"
//usage:       "Create UBI volume\n"
//usage:     "\n	-a ALIGNMENT	Volume alignment (default 1)"
//usage:     "\n	-m		Set volume size to maximum available"
//usage:     "\n	-n VOLID	Volume ID. If not specified,"
//usage:     "\n			assigned automatically"
//usage:     "\n	-N NAME		Volume name"
//usage:     "\n	-s SIZE		Size in bytes"
//usage:     "\n	-t TYPE		Volume type (static|dynamic)"
	if (do_mkvol) {
		if (opts & OPTION_m) {
			unsigned leb_avail;
			unsigned leb_size;
			unsigned num;
			char *p;

			if (sscanf(ubi_ctrl, "/dev/ubi%u", &num) != 1)
				bb_error_msg_and_die("wrong format of UBI device name");

			p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num);

			strcpy(p, "avail_eraseblocks");
			leb_avail = get_num_from_file(path, UINT_MAX, "Can't get available eraseblocks from '%s'");

			strcpy(p, "eraseblock_size");
			leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK, "Can't get eraseblock size from '%s'");

			size_bytes = leb_avail * (unsigned long long)leb_size;
			//if (size_bytes <= 0)
			//	bb_error_msg_and_die("%s invalid maximum size calculated", "UBI");
		} else
		if (!(opts & OPTION_s))
			bb_error_msg_and_die("size not specified");

		if (!(opts & OPTION_N))
			bb_error_msg_and_die("name not specified");

		mkvol_req.vol_id = vol_id;
		mkvol_req.vol_type = UBI_DYNAMIC_VOLUME;
		if ((opts & OPTION_t) && type[0] == 's')
			mkvol_req.vol_type = UBI_STATIC_VOLUME;
		mkvol_req.alignment = alignment;
		mkvol_req.bytes = size_bytes; /* signed int64_t */
		strncpy(mkvol_req.name, vol_name, UBI_MAX_VOLUME_NAME);
		mkvol_req.name_len = strlen(vol_name);
		if (mkvol_req.name_len > UBI_MAX_VOLUME_NAME)
			bb_error_msg_and_die("volume name too long: '%s'", vol_name);

		xioctl(fd, UBI_IOCMKVOL, &mkvol_req);
	} else

//usage:#define ubirmvol_trivial_usage
//usage:       "UBI_DEVICE -n VOLID"
//usage:#define ubirmvol_full_usage "\n\n"
//usage:       "Remove UBI volume\n"
//usage:     "\n	-n VOLID	Volume ID"
	if (do_rmvol) {
		if (!(opts & OPTION_n))
			bb_error_msg_and_die("volume id not specified");

		/* FIXME? kernel expects int32_t* here: */
		xioctl(fd, UBI_IOCRMVOL, &vol_id);
	} else

//usage:#define ubirsvol_trivial_usage
//usage:       "UBI_DEVICE -n VOLID -s SIZE"
//usage:#define ubirsvol_full_usage "\n\n"
//usage:       "Resize UBI volume\n"
//usage:     "\n	-n VOLID	Volume ID"
//usage:     "\n	-s SIZE		Size in bytes"
	if (do_rsvol) {
		if (!(opts & OPTION_s))
			bb_error_msg_and_die("size not specified");
		if (!(opts & OPTION_n))
			bb_error_msg_and_die("volume id not specified");

		rsvol_req.bytes = size_bytes; /* signed int64_t */
		rsvol_req.vol_id = vol_id;

		xioctl(fd, UBI_IOCRSVOL, &rsvol_req);
	} else

//usage:#define ubiupdatevol_trivial_usage
//usage:       "UBI_DEVICE [-t | [-s SIZE] IMG_FILE]"
//usage:#define ubiupdatevol_full_usage "\n\n"
//usage:       "Update UBI volume\n"
//usage:     "\n	-t	Truncate to zero size"
//usage:     "\n	-s SIZE	Size in bytes to resize to"
	if (do_update) {
		int64_t bytes64;

		if (opts & OPTION_t) {
			/* truncate the volume by starting an update for size 0 */
			bytes64 = 0;
			/* this ioctl expects int64_t* parameter */
			xioctl(fd, UBI_IOCVOLUP, &bytes64);
		}
		else {
			struct stat st;
			unsigned ubinum, volnum;
			unsigned leb_size;
			ssize_t len;
			char *input_data;

			/* Assume that device is in normal format. */
			/* Removes need for scanning sysfs tree as full libubi does. */
			if (sscanf(ubi_ctrl, "/dev/ubi%u_%u", &ubinum, &volnum) != 2)
				bb_error_msg_and_die("wrong format of UBI device name");

			sprintf(path_sys_class_ubi_ubi, "%u_%u/usable_eb_size", ubinum, volnum);
			leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK, "Can't get usable eraseblock size from '%s'");

			if (!(opts & OPTION_s)) {
				if (!*argv)
					bb_show_usage();
				xstat(*argv, &st);
				size_bytes = st.st_size;
				xmove_fd(xopen(*argv, O_RDONLY), STDIN_FILENO);
			}

			bytes64 = size_bytes;
			/* this ioctl expects signed int64_t* parameter */
			xioctl(fd, UBI_IOCVOLUP, &bytes64);

			input_data = xmalloc(leb_size);
			while ((len = full_read(STDIN_FILENO, input_data, leb_size)) > 0) {
				xwrite(fd, input_data, len);
			}
			if (len < 0)
				bb_perror_msg_and_die("UBI volume update failed");
		}
	}

	if (ENABLE_FEATURE_CLEAN_UP)
		close(fd);

	return EXIT_SUCCESS;
}
Exemple #17
0
int gunzip_main(int argc, char **argv)
{
	char status = EXIT_SUCCESS;
	unsigned long opt;

	opt = bb_getopt_ulflags(argc, argv, "cftd");
	/* if called as zcat */
	if (strcmp(bb_applet_name, "zcat") == 0) {
		opt |= GUNZIP_OPT_STDOUT;
	}

	do {
		struct stat stat_buf;
		const char *old_path = argv[optind];
		const char *delete_path = NULL;
		char *new_path = NULL;
		int src_fd;
		int dst_fd;

		optind++;

		if (old_path == NULL || strcmp(old_path, "-") == 0) {
			src_fd = STDIN_FILENO;
			opt |= GUNZIP_OPT_STDOUT;
		} else {
			src_fd = bb_xopen(old_path, O_RDONLY);

			/* Get the time stamp on the input file. */
			xstat(old_path, &stat_buf);
		}

		/* Check that the input is sane.  */
		if (isatty(src_fd) && ((opt & GUNZIP_OPT_FORCE) == 0)) {
			bb_error_msg_and_die
				("compressed data not read from terminal.  Use -f to force it.");
		}

		/* Set output filename and number */
		if (opt & GUNZIP_OPT_TEST) {
			dst_fd = bb_xopen(bb_dev_null, O_WRONLY);	/* why does test use filenum 2 ? */
		} else if (opt & GUNZIP_OPT_STDOUT) {
			dst_fd = STDOUT_FILENO;
		} else {
			char *extension;

			new_path = bb_xstrdup(old_path);

			extension = strrchr(new_path, '.');
#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS
			if (extension && (strcmp(extension, ".Z") == 0)) {
				*extension = '\0';
			} else
#endif
			if (extension && (strcmp(extension, ".gz") == 0)) {
				*extension = '\0';
			} else if (extension && (strcmp(extension, ".tgz") == 0)) {
				extension[2] = 'a';
				extension[3] = 'r';
			} else {
				bb_error_msg_and_die("Invalid extension");
			}

			/* Open output file (with correct permissions) */
			dst_fd = bb_xopen3(new_path, O_WRONLY | O_CREAT, stat_buf.st_mode);

			/* If unzip succeeds remove the old file */
			delete_path = old_path;
		}

		/* do the decompression, and cleanup */
		if (bb_xread_char(src_fd) == 0x1f) {
			unsigned char magic2;

			magic2 = bb_xread_char(src_fd);
#ifdef CONFIG_FEATURE_GUNZIP_UNCOMPRESS
			if (magic2 == 0x9d) {
				status = uncompress(src_fd, dst_fd);
			} else
#endif
				if (magic2 == 0x8b) {
					check_header_gzip(src_fd);
					status = inflate_gunzip(src_fd, dst_fd);
					if (status != 0) {
						bb_error_msg_and_die("Error inflating");
					}
				} else {
					bb_error_msg_and_die("Invalid magic");
				}
		} else {
			bb_error_msg_and_die("Invalid magic");
		}

		if ((status != EXIT_SUCCESS) && (new_path)) {
			/* Unzip failed, remove new path instead of old path */
			delete_path = new_path;
		}

		if (dst_fd != STDOUT_FILENO) {
			close(dst_fd);
		}
		if (src_fd != STDIN_FILENO) {
			close(src_fd);
		}

		/* delete_path will be NULL if in test mode or from stdin */
		if (delete_path && (unlink(delete_path) == -1)) {
			bb_error_msg_and_die("Couldn't remove %s", delete_path);
		}

		free(new_path);

	} while (optind < argc);

	return status;
}
Exemple #18
0
int switch_root_main(int argc UNUSED_PARAM, char **argv)
{
	char *newroot, *console = NULL;
	struct stat st;
	struct statfs stfs;
	dev_t rootdev;

	// Parse args (-c console)
	opt_complementary = "-2"; // minimum 2 params
	getopt32(argv, "+c:", &console); // '+': stop at first non-option
	argv += optind;
	newroot = *argv++;

	// Change to new root directory and verify it's a different fs
	xchdir(newroot);
	xstat("/", &st);
	rootdev = st.st_dev;
	xstat(".", &st);
	if (st.st_dev == rootdev || getpid() != 1) {
		// Show usage, it says new root must be a mountpoint
		// and we must be PID 1
		bb_show_usage();
	}

	// Additional sanity checks: we're about to rm -rf /, so be REALLY SURE
	// we mean it. I could make this a CONFIG option, but I would get email
	// from all the people who WILL destroy their filesystems.
	if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) {
		bb_error_msg_and_die("/init is not a regular file");
	}
	statfs("/", &stfs); // this never fails
	if ((unsigned)stfs.f_type != RAMFS_MAGIC
	 && (unsigned)stfs.f_type != TMPFS_MAGIC
	) {
		bb_error_msg_and_die("root filesystem is not ramfs/tmpfs");
	}

	// Zap everything out of rootdev
	delete_contents("/", rootdev);

	// Overmount / with newdir and chroot into it
	if (mount(".", "/", NULL, MS_MOVE, NULL)) {
		// For example, fails when newroot is not a mountpoint
		bb_perror_msg_and_die("error moving root");
	}
	xchroot(".");
	// The chdir is needed to recalculate "." and ".." links
	/*xchdir("/"); - done in xchroot */

	// If a new console specified, redirect stdin/stdout/stderr to it
	if (console) {
		close(0);
		xopen(console, O_RDWR);
		xdup2(0, 1);
		xdup2(0, 2);
	}

	// Exec real init
	execv(argv[0], argv);
	bb_perror_msg_and_die("can't execute '%s'", argv[0]);
}
Exemple #19
0
int date_main(int argc, char **argv)
{
	char *date_str = NULL;
	char *date_fmt = NULL;
	int set_time;
	int utc;
	time_t tm;
	unsigned long opt;
	struct tm tm_time;
	char *filename = NULL;

	int ifmt = 0;
	char *isofmt_arg;
	char *hintfmt_arg;

	bb_opt_complementally = "?:d--s:s--d";
	opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:"
		  		 	USE_FEATURE_DATE_ISOFMT("I::D:"),
					&date_str, &date_str, &filename
					USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg));
	set_time = opt & DATE_OPT_SET;
	utc = opt & DATE_OPT_UTC;
	if (utc && putenv("TZ=UTC0") != 0) {
		bb_error_msg_and_die(bb_msg_memory_exhausted);
	}

	if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
		if (!isofmt_arg) {
			ifmt = 1;
		} else {
			char *isoformats[]={"date","hours","minutes","seconds"};
			for(ifmt = 4; ifmt;)
				if(!strcmp(isofmt_arg,isoformats[--ifmt]))
					break;
		}
		if (!ifmt) {
			bb_show_usage();
		}
	}

	/* XXX, date_fmt == NULL from this always */
	if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
		date_fmt = &argv[optind][1];	/* Skip over the '+' */
	} else if (date_str == NULL) {
		set_time = 1;
		date_str = argv[optind];
	}

	/* Now we have parsed all the information except the date format
	   which depends on whether the clock is being set or read */

	if(filename) {
		struct stat statbuf;
		xstat(filename,&statbuf);
		tm=statbuf.st_mtime;
	} else time(&tm);
	memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
	/* Zero out fields - take her back to midnight! */
	if (date_str != NULL) {
		tm_time.tm_sec = 0;
		tm_time.tm_min = 0;
		tm_time.tm_hour = 0;

		/* Process any date input to UNIX time since 1 Jan 1970 */
		if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) {
			strptime(date_str, hintfmt_arg, &tm_time);
		} else if (strchr(date_str, ':') != NULL) {
			date_conv_ftime(&tm_time, date_str);
		} else {
			date_conv_time(&tm_time, date_str);
		}

		/* Correct any day of week and day of year etc. fields */
		tm_time.tm_isdst = -1;	/* Be sure to recheck dst. */
		tm = mktime(&tm_time);
		if (tm < 0) {
			bb_error_msg_and_die(bb_msg_invalid_date, date_str);
		}
		if (utc && putenv("TZ=UTC0") != 0) {
			bb_error_msg_and_die(bb_msg_memory_exhausted);
		}

		/* if setting time, set it */
		if (set_time && stime(&tm) < 0) {
			bb_perror_msg("cannot set date");
		}
	}

	/* Display output */

	/* Deal with format string */
	if (date_fmt == NULL) {
		/* Start with the default case */
		
		date_fmt = (opt & DATE_OPT_RFC2822 ?
					(utc ? "%a, %d %b %Y %H:%M:%S GMT" :
					"%a, %d %b %Y %H:%M:%S %z") :
					"%a %b %e %H:%M:%S %Z %Y");

		if (ENABLE_FEATURE_DATE_ISOFMT) {
			if (ifmt == 4)
				date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z";
			else if (ifmt == 3)
				date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z";
			else if (ifmt == 2) 
				date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z";
			else if (ifmt == 1)
				date_fmt = "%Y-%m-%d";
		}
	}
	
	if (*date_fmt == '\0') {

		/* With no format string, just print a blank line */
		
		*bb_common_bufsiz1=0;
	} else {

		/* Handle special conversions */

		if (strncmp(date_fmt, "%f", 2) == 0) {
			date_fmt = "%Y.%m.%d-%H:%M:%S";
		}

		/* Generate output string */
		strftime(bb_common_bufsiz1, 200, date_fmt, &tm_time);
	}
	puts(bb_common_bufsiz1);

	return EXIT_SUCCESS;
}
Exemple #20
0
/* Open directory 'BDMV', change directory to it.
 * Then open directory 'STREAM', change directory to it.
 * Get the filename has the biggest size in it.
 */
int bluray(const char *dir_name)
{
	DIR *dir;
	struct stat buf;
	struct dirent *dirp;
	char *rval = NULL;
	pid_t pid;

	if (!dir_name || !*dir_name)
		return -1;

	if (is_absolute_path(dir_name)) {
		xchdir(dir_name);
		dir = opendir(BLURAY_PATH);
		if (dir == NULL) {
			fprintf(stderr, "\nopen directory '%s' failure: %s\n",
				BLURAY_PATH, strerror(errno));
			xchdir(dir_name);
			xchdir("..");
			return -1;
		}
		xchdir(BLURAY_PATH);

		while ((dirp = readdir(dir)) != NULL) {
			xstat(dirp->d_name, &buf);
			if ((buf.st_size / 1024 / 1024) > FILE_SIZE) {
				size_t len = strlen(dirp->d_name) + 1;
				rval = xmalloc(len);
				strncpy(rval, dirp->d_name, len);
			}
		}
	} else {
		dir = opendir(BLURAY_PATH);
		if (dir == NULL) {
			fprintf(stderr, "\nopen directory '%s' failure: %s\n",
				BLURAY_PATH, strerror(errno));
			return -1;
		}
		xchdir(BLURAY_PATH);

		while ((dirp = readdir(dir)) != NULL) {
			xstat(dirp->d_name, &buf);
			if ((buf.st_size / 1024 / 1024) > FILE_SIZE) {
				size_t len = strlen(dirp->d_name) + 1;
				rval = xmalloc(len);
				strncpy(rval, dirp->d_name, len);
			}
		}
	}

	pid = xfork();
	if (pid == 0) {
		execlp("mplayer", "mplayer", rval, (char *)0);
		perror("execlp error");
		exit(EXIT_FAILURE);
	}

	xchdir(dir_name);
	xchdir("..");
	return 0;
}
void jscoverage_instrument(const char * source,
                           const char * destination,
                           int verbose,
                           char ** exclude,
                           int num_exclude,
                           char ** no_instrument,
                           int num_no_instrument)
{
  assert(source != NULL);
  assert(destination != NULL);

  g_verbose = verbose;

  /* check if they are the same */
  check_same_file(source, destination);

  /* check if source directory is an ancestor of destination directory */
  check_contains_file(source, destination);

  /* check that the source exists and is a directory */
  struct stat buf;
  xstat(source, &buf);
  if (! S_ISDIR(buf.st_mode)) {
    fatal("not a directory: %s", source);
  }

  /* if the destination directory exists, check that it is a jscoverage directory */
  if (stat(destination, &buf) == 0) {
    /* it exists */
    if (! S_ISDIR(buf.st_mode)) {
      fatal("not a directory: %s", destination);
    }
    if (! directory_is_empty(destination)) {
      char * expected_file = NULL;
      if (jscoverage_mode == JSCOVERAGE_MOZILLA) {
        char * modules_directory = make_path(destination, "modules");
        expected_file = make_path(modules_directory, "jscoverage.jsm");
        free(modules_directory);
      }
      else {
        expected_file = make_path(destination, "jscoverage.html");
      }
      if (stat(expected_file, &buf) == -1) {
        fatal("refusing to overwrite directory: %s", destination);
      }
      free(expected_file);
    }
  }
  else if (errno == ENOENT) {
    xmkdir(destination);
  }
  else {
    fatal("cannot stat directory: %s", destination);
  }

  /* copy the resources */
  if (jscoverage_mode == JSCOVERAGE_MOZILLA) {
    char * chrome_directory = make_path(destination, "chrome");
    char * jscoverage_chrome_directory = make_path(chrome_directory, "jscoverage");
    mkdirs(jscoverage_chrome_directory);
    copy_resource("jscoverage.manifest", chrome_directory);
    copy_resource("jscoverage.html", jscoverage_chrome_directory);
    copy_resource("jscoverage.css", jscoverage_chrome_directory);
    copy_resource("jscoverage.js", jscoverage_chrome_directory);
    copy_resource("jscoverage-throbber.gif", jscoverage_chrome_directory);
    copy_resource("jscoverage-highlight.css", jscoverage_chrome_directory);
    copy_resource("jscoverage.xul", jscoverage_chrome_directory);
    copy_resource("jscoverage-overlay.js", jscoverage_chrome_directory);
    free(jscoverage_chrome_directory);
    free(chrome_directory);

    char * modules_directory = make_path(destination, "modules");
    mkdirs(modules_directory);
    copy_resource("jscoverage.jsm", modules_directory);
    free(modules_directory);
  }
  else {
    jscoverage_copy_resources(destination);
  }

  /* finally: copy the directory */
  struct DirListEntry * list = make_recursive_dir_list(source);
  for (struct DirListEntry * p = list; p != NULL; p = p->next) {
    char * s = make_path(source, p->name);
    char * d = make_path(destination, p->name);

    /* check if it's on the exclude list */
    for (int i = 0; i < num_exclude; i++) {
      char * x = make_path(source, exclude[i]);
      if (is_same_file(x, s) || contains_file(x, s)) {
        free(x);
        goto cleanup;
      }
      free(x);
    }

    char * dd = make_dirname(d);
    mkdirs(dd);
    free(dd);

    int instrument_this = 1;

    /* check if it's on the no-instrument list */
    for (int i = 0; i < num_no_instrument; i++) {
      char * ni = make_path(source, no_instrument[i]);
      if (is_same_file(ni, s) || contains_file(ni, s)) {
        instrument_this = 0;
      }
      free(ni);
    }

    instrument_file(s, d, p->name, instrument_this);

  cleanup:
    free(s);
    free(d);
  }

  free_dir_list(list);
}
Exemple #22
0
int date_main(int argc, char **argv)
{
	time_t tm;
	struct tm tm_time;
	unsigned opt;
	int ifmt = -1;
	char *date_str = NULL;
	char *date_fmt = NULL;
	char *filename = NULL;
	char *isofmt_arg;
	char *hintfmt_arg;

	opt_complementary = "d--s:s--d"
		USE_FEATURE_DATE_ISOFMT(":R--I:I--R");
	opt = getopt32(argv, "Rs:ud:r:"
			USE_FEATURE_DATE_ISOFMT("I::D:"),
			&date_str, &date_str, &filename
			USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg));
	maybe_set_utc(opt);

	if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) {
		if (!isofmt_arg) {
			ifmt = 0; /* default is date */
		} else {
			static const char *const isoformats[] = {
				"date", "hours", "minutes", "seconds"
			};

			for (ifmt = 0; ifmt < 4; ifmt++)
				if (!strcmp(isofmt_arg, isoformats[ifmt]))
					goto found;
			/* parse error */
			bb_show_usage();
 found: ;
		}
	}

	/* XXX, date_fmt == NULL from this always */
	if ((date_fmt == NULL) && (optind < argc) && (argv[optind][0] == '+')) {
		date_fmt = &argv[optind][1];	/* Skip over the '+' */
	} else if (date_str == NULL) {
		opt |= DATE_OPT_SET;
		date_str = argv[optind];
	}

	/* Now we have parsed all the information except the date format
	   which depends on whether the clock is being set or read */

	if (filename) {
		struct stat statbuf;
		xstat(filename, &statbuf);
		tm = statbuf.st_mtime;
	} else
		time(&tm);
	memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
	/* Zero out fields - take her back to midnight! */
	if (date_str != NULL) {
		tm_time.tm_sec = 0;
		tm_time.tm_min = 0;
		tm_time.tm_hour = 0;

		/* Process any date input to UNIX time since 1 Jan 1970 */
		if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_HINT)) {
			strptime(date_str, hintfmt_arg, &tm_time);
		} else if (strchr(date_str, ':') != NULL) {
			/* Parse input and assign appropriately to tm_time */

			if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min,
								 &tm_time.tm_sec) == 3) {
				/* no adjustments needed */
			} else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour,
										&tm_time.tm_min) == 2) {
				/* no adjustments needed */
			} else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon,
								&tm_time.tm_mday, &tm_time.tm_hour,
								&tm_time.tm_min, &tm_time.tm_sec) == 5) {
				/* Adjust dates from 1-12 to 0-11 */
				tm_time.tm_mon -= 1;
			} else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon,
								&tm_time.tm_mday,
								&tm_time.tm_hour, &tm_time.tm_min) == 4) {
				/* Adjust dates from 1-12 to 0-11 */
				tm_time.tm_mon -= 1;
			} else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year,
								&tm_time.tm_mon, &tm_time.tm_mday,
								&tm_time.tm_hour, &tm_time.tm_min,
									&tm_time.tm_sec) == 6) {
				tm_time.tm_year -= 1900;	/* Adjust years */
				tm_time.tm_mon -= 1;	/* Adjust dates from 1-12 to 0-11 */
			} else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year,
								&tm_time.tm_mon, &tm_time.tm_mday,
								&tm_time.tm_hour, &tm_time.tm_min) == 5) {
				tm_time.tm_year -= 1900;	/* Adjust years */
				tm_time.tm_mon -= 1;	/* Adjust dates from 1-12 to 0-11 */
			} else {
				bb_error_msg_and_die(bb_msg_invalid_date, date_str);
			}
		} else {
			int nr;
			char *cp;

			nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon,
						&tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min,
						&tm_time.tm_year);

			if (nr < 4 || nr > 5) {
				bb_error_msg_and_die(bb_msg_invalid_date, date_str);
			}

			cp = strchr(date_str, '.');
			if (cp) {
				nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec);
				if (nr != 1) {
					bb_error_msg_and_die(bb_msg_invalid_date, date_str);
				}
			}

			/* correct for century  - minor Y2K problem here? */
			if (tm_time.tm_year >= 1900) {
				tm_time.tm_year -= 1900;
			}
			/* adjust date */
			tm_time.tm_mon -= 1;
		}

		/* Correct any day of week and day of year etc. fields */
		tm_time.tm_isdst = -1;	/* Be sure to recheck dst. */
		tm = mktime(&tm_time);
		if (tm < 0) {
			bb_error_msg_and_die(bb_msg_invalid_date, date_str);
		}
		maybe_set_utc(opt);

		/* if setting time, set it */
		if ((opt & DATE_OPT_SET) && stime(&tm) < 0) {
			bb_perror_msg("cannot set date");
		}
	}

	/* Display output */

	/* Deal with format string */

	if (date_fmt == NULL) {
		int i;
		date_fmt = xzalloc(32);
		if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) {
			strcpy(date_fmt, "%Y-%m-%d");
			if (ifmt > 0) {
				i = 8;
				date_fmt[i++] = 'T';
				date_fmt[i++] = '%';
				date_fmt[i++] = 'H';
				if (ifmt > 1) {
					date_fmt[i++] = ':';
					date_fmt[i++] = '%';
					date_fmt[i++] = 'M';
				}
				if (ifmt > 2) {
					date_fmt[i++] = ':';
					date_fmt[i++] = '%';
					date_fmt[i++] = 'S';
				}
 format_utc:
				date_fmt[i++] = '%';
				date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z';
			}
		} else if (opt & DATE_OPT_RFC2822) {
			/* Undo busybox.c for date -R */
			if (ENABLE_LOCALE_SUPPORT)
				setlocale(LC_TIME, "C");
			strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S ");
			i = 22;
			goto format_utc;
		} else /* default case */
			date_fmt = (char*)"%a %b %e %H:%M:%S %Z %Y";
	}

#define date_buf bb_common_bufsiz1
	if (*date_fmt == '\0') {
		/* With no format string, just print a blank line */
		date_buf[0] = '\0';
	} else {
		/* Handle special conversions */

		if (strncmp(date_fmt, "%f", 2) == 0) {
			date_fmt = (char*)"%Y.%m.%d-%H:%M:%S";
		}

		/* Generate output string */
		strftime(date_buf, sizeof(date_buf), date_fmt, &tm_time);
	}
	puts(date_buf);

	return EXIT_SUCCESS;
}