Example #1
0
int __parsespent(char *s, struct spwd *sp)
{
	sp->sp_namp = s;
	if (!(s = strchr(s, ':'))) return -1;
	*s = 0;

	sp->sp_pwdp = ++s;
	if (!(s = strchr(s, ':'))) return -1;
	*s = 0;

	s++; sp->sp_lstchg = xatol(&s);
	if (*s != ':') return -1;

	s++; sp->sp_min = xatol(&s);
	if (*s != ':') return -1;

	s++; sp->sp_max = xatol(&s);
	if (*s != ':') return -1;

	s++; sp->sp_warn = xatol(&s);
	if (*s != ':') return -1;

	s++; sp->sp_inact = xatol(&s);
	if (*s != ':') return -1;

	s++; sp->sp_expire = xatol(&s);
	if (*s != ':') return -1;

	s++; sp->sp_flag = xatol(&s);
	if (*s != '\n') return -1;
	return 0;
}
Example #2
0
int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res)
{
	char path[20+NAME_MAX];
	FILE *f = 0;
	int rv = 0;
	int fd;
	size_t k, l = strlen(name);
	char *s;
	int skip = 0;
	int cs;

	*res = 0;

	/* Disallow potentially-malicious user names */
	if (*name=='.' || strchr(name, '/') || !l)
		return EINVAL;

	/* Buffer size must at least be able to hold name, plus some.. */
	if (size < l+100) return ERANGE;

	/* Protect against truncation */
	if (snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= sizeof path)
		return EINVAL;

	fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK);
	if (fd >= 0) {
		struct stat st = { 0 };
		errno = EINVAL;
		if (fstat(fd, &st) || !S_ISREG(st.st_mode) || !(f = fdopen(fd, "rb"))) {
			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
			close(fd);
			pthread_setcancelstate(cs, 0);
			return errno;
		}
	} else {
		f = fopen("/etc/shadow", "rb");
		if (!f) return errno;
	}

	pthread_cleanup_push(cleanup, f);
	while (fgets(buf, size, f) && (k=strlen(buf))>0) {
		if (skip || strncmp(name, buf, l)) {
			skip = buf[k-1] != '\n';
			continue;
		}
		if (buf[k-1] != '\n') {
			rv = ERANGE;
			break;
		}
		buf[k-1] = 0;

		s = buf;
		sp->sp_namp = s;
		if (!(s = strchr(s, ':'))) continue;

		*s++ = 0; sp->sp_pwdp = s;
		if (!(s = strchr(s, ':'))) continue;

		*s++ = 0; sp->sp_lstchg = xatol(s);
		if (!(s = strchr(s, ':'))) continue;

		*s++ = 0; sp->sp_min = xatol(s);
		if (!(s = strchr(s, ':'))) continue;

		*s++ = 0; sp->sp_max = xatol(s);
		if (!(s = strchr(s, ':'))) continue;

		*s++ = 0; sp->sp_warn = xatol(s);
		if (!(s = strchr(s, ':'))) continue;

		*s++ = 0; sp->sp_inact = xatol(s);
		if (!(s = strchr(s, ':'))) continue;

		*s++ = 0; sp->sp_expire = xatol(s);
		if (!(s = strchr(s, ':'))) continue;

		*s++ = 0; sp->sp_flag = xatol(s);
		*res = sp;
		break;
	}
	pthread_cleanup_pop(1);
	return rv;
}
Example #3
0
int rtcwake_main(int argc UNUSED_PARAM, char **argv)
{
	time_t rtc_time;

	unsigned opt;
	const char *rtcname = NULL;
	const char *suspend;
	const char *opt_seconds;
	const char *opt_time;

	time_t sys_time;
	time_t alarm_time = 0;
	unsigned seconds = 0;
	int utc = -1;
	int fd;

#if ENABLE_LONG_OPTS
	static const char rtcwake_longopts[] ALIGN1 =
		"auto\0"    No_argument "a"
		"local\0"   No_argument "l"
		"utc\0"     No_argument "u"
		"device\0"  Required_argument "d"
		"mode\0"    Required_argument "m"
		"seconds\0" Required_argument "s"
		"time\0"    Required_argument "t"
		;
	applet_long_options = rtcwake_longopts;
#endif
	opt = getopt32(argv, "alud:m:s:t:", &rtcname, &suspend, &opt_seconds, &opt_time);

	/* this is the default
	if (opt & RTCWAKE_OPT_AUTO)
		utc = -1;
	*/
	if (opt & (RTCWAKE_OPT_UTC | RTCWAKE_OPT_LOCAL))
		utc = opt & RTCWAKE_OPT_UTC;
	if (!(opt & RTCWAKE_OPT_SUSPEND_MODE))
		suspend = DEFAULT_MODE;
	if (opt & RTCWAKE_OPT_SECONDS)
		/* alarm time, seconds-to-sleep (relative) */
		seconds = xatoi(opt_seconds);
	if (opt & RTCWAKE_OPT_TIME)
		/* alarm time, time_t (absolute, seconds since 1/1 1970 UTC) */
		alarm_time = xatol(opt_time);

	if (!alarm_time && !seconds)
		bb_error_msg_and_die("must provide wake time");

	if (utc == -1)
		utc = rtc_adjtime_is_utc();

	/* the rtcname is relative to /dev */
	xchdir("/dev");

	/* this RTC must exist and (if we'll sleep) be wakeup-enabled */
	fd = rtc_xopen(&rtcname, O_RDONLY);

	if (strcmp(suspend, "on") && !may_wakeup(rtcname))
		bb_error_msg_and_die("%s not enabled for wakeup events", rtcname);

	/* relative or absolute alarm time, normalized to time_t */
	sys_time = time(NULL);
	{
		struct tm tm_time;
		rtc_read_tm(&tm_time, fd);
		rtc_time = rtc_tm2time(&tm_time, utc);
	}


	if (alarm_time) {
		if (alarm_time < sys_time)
			bb_error_msg_and_die("time doesn't go backward to %s", ctime(&alarm_time));
		alarm_time += sys_time - rtc_time;
	} else
		alarm_time = rtc_time + seconds + 1;
	setup_alarm(fd, &alarm_time, rtc_time);

	sync();
	printf("wakeup from \"%s\" at %s", suspend, ctime(&alarm_time));
	fflush_all();
	usleep(10 * 1000);

	if (strcmp(suspend, "on"))
		xopen_xwrite_close(SYS_POWER_PATH, suspend);
	else {
		/* "fake" suspend ... we'll do the delay ourselves */
		unsigned long data;

		do {
			ssize_t ret = safe_read(fd, &data, sizeof(data));
			if (ret < 0) {
				bb_perror_msg("rtc read");
				break;
			}
		} while (!(data & RTC_AF));
	}

	xioctl(fd, RTC_AIE_OFF, 0);

	if (ENABLE_FEATURE_CLEAN_UP)
		close(fd);

	return EXIT_SUCCESS;
}
Example #4
0
int rtcwake_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned opt;
	const char *rtcname = NULL;
	const char *suspend = "standby";
	const char *opt_seconds;
	const char *opt_time;

	time_t rtc_time;
	time_t sys_time;
	time_t alarm_time = alarm_time;
	unsigned seconds = seconds; /* for compiler */
	int utc = -1;
	int fd;

#if ENABLE_LONG_OPTS
	static const char rtcwake_longopts[] ALIGN1 =
		"auto\0"    No_argument "a"
		"local\0"   No_argument "l"
		"utc\0"     No_argument "u"
		"device\0"  Required_argument "d"
		"mode\0"    Required_argument "m"
		"seconds\0" Required_argument "s"
		"time\0"    Required_argument "t"
		;
#endif
	opt = getopt32long(argv,
			/* Must have -s or -t, exclusive */
			"^alud:m:s:t:" "\0" "s:t:s--t:t--s", rtcwake_longopts,
			&rtcname, &suspend, &opt_seconds, &opt_time);

	/* this is the default
	if (opt & RTCWAKE_OPT_AUTO)
		utc = -1;
	*/
	if (opt & (RTCWAKE_OPT_UTC | RTCWAKE_OPT_LOCAL))
		utc = opt & RTCWAKE_OPT_UTC;
	if (opt & RTCWAKE_OPT_SECONDS) {
		/* alarm time, seconds-to-sleep (relative) */
		seconds = xatou(opt_seconds);
	} else {
		/* RTCWAKE_OPT_TIME */
		/* alarm time, time_t (absolute, seconds since 1/1 1970 UTC) */
		if (sizeof(alarm_time) <= sizeof(long))
			alarm_time = xatol(opt_time);
		else
			alarm_time = xatoll(opt_time);
	}

	if (utc == -1)
		utc = rtc_adjtime_is_utc();

	/* the rtcname is relative to /dev */
	xchdir("/dev");

	/* this RTC must exist and (if we'll sleep) be wakeup-enabled */
	fd = rtc_xopen(&rtcname, O_RDONLY);

	if (strcmp(suspend, "on") != 0)
		if (!may_wakeup(rtcname))
			bb_error_msg_and_die("%s not enabled for wakeup events", rtcname);

	/* relative or absolute alarm time, normalized to time_t */
	sys_time = time(NULL);
	{
		struct tm tm_time;
		rtc_read_tm(&tm_time, fd);
		rtc_time = rtc_tm2time(&tm_time, utc);
	}

	if (opt & RTCWAKE_OPT_TIME) {
		/* Correct for RTC<->system clock difference */
		alarm_time += rtc_time - sys_time;
		if (alarm_time < rtc_time)
			/*
			 * Compat message text.
			 * I'd say "RTC time is already ahead of ..." instead.
			 */
			bb_error_msg_and_die("time doesn't go backward to %s", ctime(&alarm_time));
	} else
		alarm_time = rtc_time + seconds + 1;

	setup_alarm(fd, &alarm_time, rtc_time);
	sync();
#if 0 /*debug*/
	printf("sys_time: %s", ctime(&sys_time));
	printf("rtc_time: %s", ctime(&rtc_time));
#endif
	printf("wakeup from \"%s\" at %s", suspend, ctime(&alarm_time));
	fflush_all();
	usleep(10 * 1000);

	if (strcmp(suspend, "on") != 0)
		xopen_xwrite_close(SYS_POWER_PATH, suspend);
	else {
		/* "fake" suspend ... we'll do the delay ourselves */
		unsigned long data;

		do {
			ssize_t ret = safe_read(fd, &data, sizeof(data));
			if (ret < 0) {
				bb_perror_msg("rtc read");
				break;
			}
		} while (!(data & RTC_AF));
	}

	xioctl(fd, RTC_AIE_OFF, 0);

	if (ENABLE_FEATURE_CLEAN_UP)
		close(fd);

	return EXIT_SUCCESS;
}
Example #5
0
int adjtimex_main(int argc UNUSED_PARAM, char **argv)
{
    enum {
        OPT_quiet = 0x1
    };
    unsigned opt;
    char *opt_o, *opt_f, *opt_p, *opt_t;
    struct timex txc;
    int i, ret;
    const char *descript;

    opt_complementary = "=0"; /* no valid non-option parameters */
    opt = getopt32(argv, "qo:f:p:t:",
                   &opt_o, &opt_f, &opt_p, &opt_t);
    txc.modes = 0;
    //if (opt & 0x1) // -q
    if (opt & 0x2) { // -o
        txc.offset = xatol(opt_o);
        txc.modes |= ADJ_OFFSET_SINGLESHOT;
    }
    if (opt & 0x4) { // -f
        txc.freq = xatol(opt_f);
        txc.modes |= ADJ_FREQUENCY;
    }
    if (opt & 0x8) { // -p
        txc.constant = xatol(opt_p);
        txc.modes |= ADJ_TIMECONST;
    }
    if (opt & 0x10) { // -t
        txc.tick = xatol(opt_t);
        txc.modes |= ADJ_TICK;
    }

    ret = adjtimex(&txc);

    if (ret < 0) {
        bb_perror_nomsg_and_die();
    }

    if (!(opt & OPT_quiet)) {
        int sep;
        const char *name;

        printf(
            "    mode:         %d\n"
            "-o  offset:       %ld\n"
            "-f  frequency:    %ld\n"
            "    maxerror:     %ld\n"
            "    esterror:     %ld\n"
            "    status:       %d (",
            txc.modes, txc.offset, txc.freq, txc.maxerror,
            txc.esterror, txc.status);

        /* representative output of next code fragment:
           "PLL | PPSTIME" */
        name = statlist_name;
        sep = 0;
        for (i = 0; statlist_bit[i]; i++) {
            if (txc.status & statlist_bit[i]) {
                if (sep)
                    fputs(" | ", stdout);
                fputs(name, stdout);
                sep = 1;
            }
            name += strlen(name) + 1;
        }

        descript = "error";
        if (ret <= 5)
            descript = nth_string(ret_code_descript, ret);
        printf(")\n"
               "-p  timeconstant: %ld\n"
               "    precision:    %ld\n"
               "    tolerance:    %ld\n"
               "-t  tick:         %ld\n"
               "    time.tv_sec:  %ld\n"
               "    time.tv_usec: %ld\n"
               "    return value: %d (%s)\n",
               txc.constant,
               txc.precision, txc.tolerance, txc.tick,
               (long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript);
    }

    return 0;
}
Example #6
0
int adjtimex_main(int argc UNUSED_PARAM, char **argv)
{
	enum {
		OPT_quiet = 0x1
	};
	unsigned opt;
	char *opt_o, *opt_f, *opt_p, *opt_t;
	struct timex txc;
	int ret;
	const char *descript;

	memset(&txc, 0, sizeof(txc));

	opt = getopt32(argv, "^" "qo:f:p:t:"
			"\0" "=0"/*no valid non-option args*/,
			&opt_o, &opt_f, &opt_p, &opt_t
	);
	//if (opt & 0x1) // -q
	if (opt & 0x2) { // -o
		txc.offset = xatol(opt_o);
		txc.modes |= ADJ_OFFSET_SINGLESHOT;
	}
	if (opt & 0x4) { // -f
		txc.freq = xatol(opt_f);
		txc.modes |= ADJ_FREQUENCY;
	}
	if (opt & 0x8) { // -p
		txc.constant = xatol(opt_p);
		txc.modes |= ADJ_TIMECONST;
	}
	if (opt & 0x10) { // -t
		txc.tick = xatol(opt_t);
		txc.modes |= ADJ_TICK;
	}

	/* It's NOFORK applet because the code is very simple:
	 * just some printf. No opens, no allocs.
	 * If you need to make it more complex, feel free to downgrade to NOEXEC
	 */

	ret = adjtimex(&txc);
	if (ret < 0)
		bb_perror_nomsg_and_die();

	if (!(opt & OPT_quiet)) {
		const char *sep;
		const char *name;
		int i;

		printf(
			"    mode:         %d\n"
			"-o  offset:       %ld us\n"
			"-f  freq.adjust:  %ld (65536 = 1ppm)\n"
			"    maxerror:     %ld\n"
			"    esterror:     %ld\n"
			"    status:       %d (",
			txc.modes, txc.offset, txc.freq, txc.maxerror,
			txc.esterror, txc.status
		);

		/* representative output of next code fragment:
		 * "PLL | PPSTIME"
		 */
		name = statlist_name;
		sep = "";
		for (i = 0; statlist_bit[i]; i++) {
			if (txc.status & statlist_bit[i]) {
				printf("%s%s", sep, name);
				sep = " | ";
			}
			name += strlen(name) + 1;
		}

		descript = "error";
		if (ret <= 5)
			descript = nth_string(ret_code_descript, ret);
		printf(")\n"
			"-p  timeconstant: %ld\n"
			"    precision:    %ld us\n"
			"    tolerance:    %ld\n"
			"-t  tick:         %ld us\n"
			"    time.tv_sec:  %ld\n"
			"    time.tv_usec: %ld\n"
			"    return value: %d (%s)\n",
			txc.constant,
			txc.precision, txc.tolerance, txc.tick,
			(long)txc.time.tv_sec, (long)txc.time.tv_usec,
			ret, descript
		);
	}

	return 0;
}
Example #7
0
int adjtimex_main(int argc, char **argv)
{
	enum {
		OPT_quiet = 0x1
	};
	unsigned opt;
	char *opt_o, *opt_f, *opt_p, *opt_t;
	struct timex txc;
	int i, ret, sep;
	const char *descript;
	txc.modes=0;

	opt = getopt32(argv, "qo:f:p:t:",
			&opt_o, &opt_f, &opt_p, &opt_t);
	//if (opt & 0x1) // -q
	if (opt & 0x2) { // -o
		txc.offset = xatol(opt_o);
		txc.modes |= ADJ_OFFSET_SINGLESHOT;
	}
	if (opt & 0x4) { // -f
		txc.freq = xatol(opt_f);
		txc.modes |= ADJ_FREQUENCY;
	}
	if (opt & 0x8) { // -p
		txc.constant = xatol(opt_p);
		txc.modes |= ADJ_TIMECONST;
	}
	if (opt & 0x10) { // -t
		txc.tick = xatol(opt_t);
		txc.modes |= ADJ_TICK;
	}
	if (argc != optind) { /* no valid non-option parameters */
		bb_show_usage();
	}

	ret = adjtimex(&txc);

	if (ret < 0) perror("adjtimex");

	if (!(opt & OPT_quiet) && ret>=0) {
		printf(
			"    mode:         %d\n"
			"-o  offset:       %ld\n"
			"-f  frequency:    %ld\n"
			"    maxerror:     %ld\n"
			"    esterror:     %ld\n"
			"    status:       %d ( ",
		txc.modes, txc.offset, txc.freq, txc.maxerror,
		txc.esterror, txc.status);

		/* representative output of next code fragment:
		   "PLL | PPSTIME" */
		sep=0;
		for (i=0; statlist[i].name; i++) {
			if (txc.status & statlist[i].bit) {
				if (sep) fputs(" | ",stdout);
				fputs(statlist[i].name,stdout);
				sep=1;
			}
		}

		descript = "error";
		if (ret >= 0 && ret <= 5) descript = ret_code_descript[ret];
		printf(" )\n"
			"-p  timeconstant: %ld\n"
			"    precision:    %ld\n"
			"    tolerance:    %ld\n"
			"-t  tick:         %ld\n"
			"    time.tv_sec:  %ld\n"
			"    time.tv_usec: %ld\n"
			"    return value: %d (%s)\n",
		txc.constant,
		txc.precision, txc.tolerance, txc.tick,
		(long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript);
	}
	return (ret<0);
}