Example #1
0
void bb_debug_dump_packet(unsigned char *outpack, int pktsize)
{
	int i;
	printf("packet dump:\n");
	for (i = 0; i < pktsize; ++i) {
		printf("%2.2x ", outpack[i]);
		if (i % 20 == 19) bb_putchar('\n');
	}
	printf("\n\n");
}
Example #2
0
int getsebool_main(int argc, char **argv)
{
	int i, rc = 0, active, pending, len = 0;
	char **names;
	unsigned opt;

	selinux_or_die();
	opt = getopt32(argv, "a");

	if (opt) { /* -a */
		if (argc > 2)
			bb_show_usage();

		rc = security_get_boolean_names(&names, &len);
		if (rc)
			bb_perror_msg_and_die("can't get boolean names");

		if (!len) {
			puts("No booleans");
			return 0;
		}
	}

	if (!len) {
		if (argc < 2)
			bb_show_usage();
		len = argc - 1;
		names = xmalloc(sizeof(char *) * len);
		for (i = 0; i < len; i++)
			names[i] = xstrdup(argv[i + 1]);
	}

	for (i = 0; i < len; i++) {
		active = security_get_boolean_active(names[i]);
		if (active < 0) {
			bb_error_msg_and_die("error getting active value for %s", names[i]);
		}
		pending = security_get_boolean_pending(names[i]);
		if (pending < 0) {
			bb_error_msg_and_die("error getting pending value for %s", names[i]);
		}
		printf("%s --> %s", names[i], (active ? "on" : "off"));
		if (pending != active)
			printf(" pending: %s", (pending ? "on" : "off"));
		bb_putchar('\n');
	}

	if (ENABLE_FEATURE_CLEAN_UP) {
		for (i = 0; i < len; i++)
			free(names[i]);
		free(names);
	}

	return rc;
}
Example #3
0
static void display_recoverable(const struct termios *mode,
				int UNUSED_PARAM dummy)
{
	int i;
	printf("%lx:%lx:%lx:%lx",
		   (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag,
		   (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag);
	for (i = 0; i < NCCS; ++i)
		printf(":%x", (unsigned int) mode->c_cc[i]);
	bb_putchar('\n');
}
int mountpoint_main(int argc, char **argv)
{
	struct stat st;
	char *arg;
	int opt = getopt32(argv, "qdx");
#define OPT_q (1)
#define OPT_d (2)
#define OPT_x (4)

	if (optind != argc - 1)
		bb_show_usage();

	arg = argv[optind];

	if ( (opt & OPT_x && stat(arg, &st) == 0) || (lstat(arg, &st) == 0) ) {
		if (opt & OPT_x) {
			if (S_ISBLK(st.st_mode)) {
				printf("%u:%u\n", major(st.st_rdev),
							minor(st.st_rdev));
				return EXIT_SUCCESS;
			} else {
				if (opt & OPT_q)
					bb_putchar('\n');
				else
					bb_error_msg("%s: not a block device", arg);
			}
			return EXIT_FAILURE;
		} else
		if (S_ISDIR(st.st_mode)) {
			dev_t st_dev = st.st_dev;
			ino_t st_ino = st.st_ino;
			char *p = xasprintf("%s/..", arg);

			if (stat(p, &st) == 0) {
				int ret = (st_dev != st.st_dev) ||
					(st_dev == st.st_dev && st_ino == st.st_ino);
				if (opt & OPT_d)
					printf("%u:%u\n", major(st_dev), minor(st_dev));
				else if (!(opt & OPT_q))
					printf("%s is %sa mountpoint\n", arg, ret?"":"not ");
				return !ret;
			}
		} else {
			if (!(opt & OPT_q))
				bb_error_msg("%s: not a directory", arg);
			return EXIT_FAILURE;
		}
	}
	if (!(opt & OPT_q))
		bb_simple_perror_msg(arg);
	return EXIT_FAILURE;
}
Example #5
0
int dmesg_main(int argc, char **argv)
{
	char *size, *level;
	int flags = getopt32(argv, "cs:n:", &size, &level);

	if (flags & 4) {
		if (klogctl(8, NULL, xatoul_range(level, 0, 10)))
			bb_perror_msg_and_die("klogctl");
	} else {
		int len;
		char *buf;

		len = (flags & 2) ? xatoul_range(size, 2, INT_MAX) : 16384;
		buf = xmalloc(len);
		if (0 > (len = klogctl(3 + (flags & 1), buf, len)))
			bb_perror_msg_and_die("klogctl");

		// Skip <#> at the start of lines, and make sure we end with a newline.

		if (ENABLE_FEATURE_DMESG_PRETTY) {
			int last = '\n';
			int in;

			for (in = 0; in<len;) {
				if (last == '\n' && buf[in] == '<') in += 3;
				else bb_putchar(last = buf[in++]);
			}
			if (last != '\n') bb_putchar('\n');
		} else {
			write(1,buf,len);
			if (len && buf[len-1]!='\n') bb_putchar('\n');
		}

		if (ENABLE_FEATURE_CLEAN_UP) free(buf);
	}

	return 0;
}
static int fuser_print_pid_list(pid_list *plist)
{
	pid_list *curr = plist;

	if (plist == NULL)
		return 0;
	while (curr != NULL) {
		if (curr->pid > 0)
			printf("%d ", curr->pid);
		curr = curr->next;
	}
	bb_putchar('\n');
	return 1;
}
Example #7
0
static void regex_process(void)
{
	char *uncomp_regex, *err;

	/* Reset variables */
	free(match_lines);
	match_lines = NULL;
	match_pos = 0;
	num_matches = 0;
	if (pattern_valid) {
		regfree(&pattern);
		pattern_valid = 0;
	}

	/* Get the uncompiled regular expression from the user */
	clear_line();
	bb_putchar((option_mask32 & LESS_STATE_MATCH_BACKWARDS) ? '?' : '/');
	uncomp_regex = less_gets(1);
	if (!uncomp_regex[0]) {
		free(uncomp_regex);
		buffer_print();
		return;
	}

	/* Compile the regex and check for errors */
	err = regcomp_or_errmsg(&pattern, uncomp_regex,
				(option_mask32 & FLAG_I) ? REG_ICASE : 0);
	free(uncomp_regex);
	if (err) {
		print_statusline(err);
		free(err);
		return;
	}

	pattern_valid = 1;
	match_pos = 0;
	fill_match_lines(0);
	while (match_pos < num_matches) {
		if ((int)match_lines[match_pos] > cur_fline)
			break;
		match_pos++;
	}
	if (option_mask32 & LESS_STATE_MATCH_BACKWARDS)
		match_pos--;

	/* It's possible that no matches are found yet.
	 * goto_match() will read input looking for match,
	 * if needed */
	goto_match(match_pos);
}
Example #8
0
static void cleanup(int code)
{
	set_cursor(-1); // cursor on
	tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig);
	if (ENABLE_FEATURE_CLEAN_UP) {
		close(G.kbd_fd);
	}
	// Reset attributes
	if (!BW)
		fputs("\033[0m", stdout);
	bb_putchar('\n');
	if (code > 1)
		kill_myself_with_sig(code);
	exit(code);
}
Example #9
0
static void cleanup(int code)
{
	set_cursor(CURSOR_ON);
	tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig);
	if (ENABLE_FEATURE_CLEAN_UP) {
		close(G.kbd_fd);
	}
	// Reset attributes
	if (!BW)
		putcsi("0m");
	bb_putchar('\n');
	if (code > EXIT_FAILURE)
		kill_myself_with_sig(code);
	exit(code);
}
/* lookup the default nameserver and display it */
static void server_print(void)
{
	char *server;

	server = xmalloc_sockaddr2dotted_noport((struct sockaddr*)&_res.nsaddr_list[0]);
	/* I honestly don't know what to do if DNS server has _IPv6 address_.
	 * Probably it is listed in
	 * _res._u._ext_.nsaddrs[MAXNS] (of type "struct sockaddr_in6*" each)
	 * but how to find out whether resolver uses
	 * _res.nsaddr_list[] or _res._u._ext_.nsaddrs[], or both?
	 * Looks like classic design from hell, BIND-grade. Hard to surpass. */
	print_host(server, "Server:");
	if (ENABLE_FEATURE_CLEAN_UP)
		free(server);
	bb_putchar('\n');
}
Example #11
0
/* lookup the default nameserver and display it */
static void server_print(void)
{
	char *server;
	struct sockaddr *sa;

#if ENABLE_FEATURE_IPV6
	sa = (struct sockaddr*)_res._u._ext.nsaddrs[0];
	if (!sa)
#endif
		sa = (struct sockaddr*)&_res.nsaddr_list[0];
	server = xmalloc_sockaddr2dotted_noport(sa);

	print_host(server, "Server:");
	if (ENABLE_FEATURE_CLEAN_UP)
		free(server);
	bb_putchar('\n');
}
Example #12
0
static void print_sem(int semid)
{
	struct semid_ds semds;
	struct ipc_perm *ipcp = &semds.sem_perm;
	union semun arg;
	unsigned int i;

	arg.buf = &semds;
	if (semctl(semid, 0, IPC_STAT, arg)) {
		bb_perror_msg("semctl");
		return;
	}

	printf("\nSemaphore Array semid=%d\n"
			  "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
			  "mode=%#o, access_perms=%#o\n"
			  "nsems = %ld\n"
			  "otime = %-26.24s\n",
			  semid,
			  ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
			  ipcp->mode, ipcp->mode & 0777,
			  (long) semds.sem_nsems,
			  semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
	printf("ctime = %-26.24s\n"
			  "%-10s %-10s %-10s %-10s %-10s\n",
			  ctime(&semds.sem_ctime),
			  "semnum", "value", "ncount", "zcount", "pid");

	arg.val = 0;
	for (i = 0; i < semds.sem_nsems; i++) {
		int val, ncnt, zcnt, pid;

		val = semctl(semid, i, GETVAL, arg);
		ncnt = semctl(semid, i, GETNCNT, arg);
		zcnt = semctl(semid, i, GETZCNT, arg);
		pid = semctl(semid, i, GETPID, arg);
		if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) {
			bb_perror_msg_and_die("semctl");
		}
		printf("%-10d %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid);
	}
	bb_putchar('\n');
}
Example #13
0
File: less.c Project: OPSF/uClinux
static void flag_change(void)
{
    int keypress;

    clear_line();
    bb_putchar('-');
    keypress = less_getch(1);

    switch (keypress) {
    case 'M':
        option_mask32 ^= FLAG_M;
        break;
    case 'm':
        option_mask32 ^= FLAG_m;
        break;
    case 'E':
        option_mask32 ^= FLAG_E;
        break;
    case '~':
        option_mask32 ^= FLAG_TILDE;
        break;
    }
}
Example #14
0
static void
bsd_select(void)
{
#if !defined(__alpha__)
    int t, ss;
    struct partition *p;

    for (t = 0; t < 4; t++) {
        p = get_part_table(t);
        if (p && is_bsd_partition_type(p->sys_ind)) {
            xbsd_part = p;
            xbsd_part_index = t;
            ss = get_start_sect(xbsd_part);
            if (ss == 0) {
                printf("Partition %s has invalid starting sector 0\n",
                       partname(disk_device, t+1, 0));
                return;
            }
            printf("Reading disklabel of %s at sector %u\n",
                   partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR);
            if (xbsd_readlabel(xbsd_part) == 0) {
                if (xbsd_create_disklabel() == 0)
                    return;
                break;
            }
        }
    }

    if (t == 4) {
        printf("There is no *BSD partition on %s\n", disk_device);
        return;
    }

#elif defined(__alpha__)

    if (xbsd_readlabel(NULL) == 0)
        if (xbsd_create_disklabel() == 0)
            exit(EXIT_SUCCESS);

#endif

    while (1) {
        bb_putchar('\n');
        switch (tolower(read_nonempty("BSD disklabel command (m for help): "))) {
        case 'd':
            xbsd_delete_part();
            break;
        case 'e':
            xbsd_edit_disklabel();
            break;
        case 'i':
            xbsd_write_bootstrap();
            break;
        case 'l':
            xbsd_list_types();
            break;
        case 'n':
            xbsd_new_part();
            break;
        case 'p':
            xbsd_print_disklabel(0);
            break;
        case 'q':
            if (ENABLE_FEATURE_CLEAN_UP)
                close_dev_fd();
            exit(EXIT_SUCCESS);
        case 'r':
            return;
        case 's':
            xbsd_print_disklabel(1);
            break;
        case 't':
            xbsd_change_fstype();
            break;
        case 'u':
            change_units();
            break;
        case 'w':
            xbsd_write_disklabel();
            break;
#if !defined(__alpha__)
        case 'x':
            xbsd_link_part();
            break;
#endif
        default:
            bsd_menu();
            break;
        }
    }
}
Example #15
0
static void summarize(const char *fmt, char **command, resource_t *resp)
{
	unsigned vv_ms;     /* Elapsed virtual (CPU) milliseconds */
	unsigned cpu_ticks; /* Same, in "CPU ticks" */
	unsigned pagesize = getpagesize();

	/* Impossible: we do not use WUNTRACED flag in wait()...
	if (WIFSTOPPED(resp->waitstatus))
		printf("Command stopped by signal %u\n",
				WSTOPSIG(resp->waitstatus));
	else */
	if (WIFSIGNALED(resp->waitstatus))
		printf("Command terminated by signal %u\n",
				WTERMSIG(resp->waitstatus));
	else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus))
		printf("Command exited with non-zero status %u\n",
				WEXITSTATUS(resp->waitstatus));

	vv_ms = (resp->ru.ru_utime.tv_sec + resp->ru.ru_stime.tv_sec) * 1000
	      + (resp->ru.ru_utime.tv_usec + resp->ru.ru_stime.tv_usec) / 1000;

#if (1000 / TICKS_PER_SEC) * TICKS_PER_SEC == 1000
	/* 1000 is exactly divisible by TICKS_PER_SEC (typical) */
	cpu_ticks = vv_ms / (1000 / TICKS_PER_SEC);
#else
	cpu_ticks = vv_ms * (unsigned long long)TICKS_PER_SEC / 1000;
#endif
	if (!cpu_ticks) cpu_ticks = 1; /* we divide by it, must be nonzero */

	while (*fmt) {
		/* Handle leading literal part */
		int n = strcspn(fmt, "%\\");
		if (n) {
			printf("%.*s", n, fmt);
			fmt += n;
			continue;
		}

		switch (*fmt) {
#ifdef NOT_NEEDED
		/* Handle literal char */
		/* Usually we optimize for size, but there is a limit
		 * for everything. With this we do a lot of 1-byte writes */
		default:
			bb_putchar(*fmt);
			break;
#endif

		case '%':
			switch (*++fmt) {
#ifdef NOT_NEEDED_YET
		/* Our format strings do not have these */
		/* and we do not take format str from user */
			default:
				bb_putchar('%');
				/*FALLTHROUGH*/
			case '%':
				if (!*fmt) goto ret;
				bb_putchar(*fmt);
				break;
#endif
			case 'C':	/* The command that got timed.  */
				printargv(command);
				break;
			case 'D':	/* Average unshared data size.  */
				printf("%lu",
					(ptok(pagesize, (UL) resp->ru.ru_idrss) +
					 ptok(pagesize, (UL) resp->ru.ru_isrss)) / cpu_ticks);
				break;
			case 'E': {	/* Elapsed real (wall clock) time.  */
				unsigned seconds = resp->elapsed_ms / 1000;
				if (seconds >= 3600)	/* One hour -> h:m:s.  */
					printf("%uh %um %02us",
							seconds / 3600,
							(seconds % 3600) / 60,
							seconds % 60);
				else
					printf("%um %u.%02us",	/* -> m:s.  */
							seconds / 60,
							seconds % 60,
							(unsigned)(resp->elapsed_ms / 10) % 100);
				break;
			}
			case 'F':	/* Major page faults.  */
				printf("%lu", resp->ru.ru_majflt);
				break;
			case 'I':	/* Inputs.  */
				printf("%lu", resp->ru.ru_inblock);
				break;
			case 'K':	/* Average mem usage == data+stack+text.  */
				printf("%lu",
					(ptok(pagesize, (UL) resp->ru.ru_idrss) +
					 ptok(pagesize, (UL) resp->ru.ru_isrss) +
					 ptok(pagesize, (UL) resp->ru.ru_ixrss)) / cpu_ticks);
				break;
			case 'M':	/* Maximum resident set size.  */
				printf("%lu", ptok(pagesize, (UL) resp->ru.ru_maxrss));
				break;
			case 'O':	/* Outputs.  */
				printf("%lu", resp->ru.ru_oublock);
				break;
			case 'P':	/* Percent of CPU this job got.  */
				/* % cpu is (total cpu time)/(elapsed time).  */
				if (resp->elapsed_ms > 0)
					printf("%u%%", (unsigned)(vv_ms * 100 / resp->elapsed_ms));
				else
					printf("?%%");
				break;
			case 'R':	/* Minor page faults (reclaims).  */
				printf("%lu", resp->ru.ru_minflt);
				break;
			case 'S':	/* System time.  */
				printf("%u.%02u",
						(unsigned)resp->ru.ru_stime.tv_sec,
						(unsigned)(resp->ru.ru_stime.tv_usec / 10000));
				break;
			case 'T':	/* System time.  */
				if (resp->ru.ru_stime.tv_sec >= 3600) /* One hour -> h:m:s.  */
					printf("%uh %um %02us",
							(unsigned)(resp->ru.ru_stime.tv_sec / 3600),
							(unsigned)(resp->ru.ru_stime.tv_sec % 3600) / 60,
							(unsigned)(resp->ru.ru_stime.tv_sec % 60));
				else
					printf("%um %u.%02us",	/* -> m:s.  */
							(unsigned)(resp->ru.ru_stime.tv_sec / 60),
							(unsigned)(resp->ru.ru_stime.tv_sec % 60),
							(unsigned)(resp->ru.ru_stime.tv_usec / 10000));
				break;
			case 'U':	/* User time.  */
				printf("%u.%02u",
						(unsigned)resp->ru.ru_utime.tv_sec,
						(unsigned)(resp->ru.ru_utime.tv_usec / 10000));
				break;
			case 'u':	/* User time.  */
				if (resp->ru.ru_utime.tv_sec >= 3600) /* One hour -> h:m:s.  */
					printf("%uh %um %02us",
							(unsigned)(resp->ru.ru_utime.tv_sec / 3600),
							(unsigned)(resp->ru.ru_utime.tv_sec % 3600) / 60,
							(unsigned)(resp->ru.ru_utime.tv_sec % 60));
				else
					printf("%um %u.%02us",	/* -> m:s.  */
							(unsigned)(resp->ru.ru_utime.tv_sec / 60),
							(unsigned)(resp->ru.ru_utime.tv_sec % 60),
							(unsigned)(resp->ru.ru_utime.tv_usec / 10000));
				break;
			case 'W':	/* Times swapped out.  */
				printf("%lu", resp->ru.ru_nswap);
				break;
			case 'X':	/* Average shared text size.  */
				printf("%lu", ptok(pagesize, (UL) resp->ru.ru_ixrss) / cpu_ticks);
				break;
			case 'Z':	/* Page size.  */
				printf("%u", pagesize);
				break;
			case 'c':	/* Involuntary context switches.  */
				printf("%lu", resp->ru.ru_nivcsw);
				break;
			case 'e':	/* Elapsed real time in seconds.  */
				printf("%u.%02u",
						(unsigned)resp->elapsed_ms / 1000,
						(unsigned)(resp->elapsed_ms / 10) % 100);
				break;
			case 'k':	/* Signals delivered.  */
				printf("%lu", resp->ru.ru_nsignals);
				break;
			case 'p':	/* Average stack segment.  */
				printf("%lu", ptok(pagesize, (UL) resp->ru.ru_isrss) / cpu_ticks);
				break;
			case 'r':	/* Incoming socket messages received.  */
				printf("%lu", resp->ru.ru_msgrcv);
				break;
			case 's':	/* Outgoing socket messages sent.  */
				printf("%lu", resp->ru.ru_msgsnd);
				break;
			case 't':	/* Average resident set size.  */
				printf("%lu", ptok(pagesize, (UL) resp->ru.ru_idrss) / cpu_ticks);
				break;
			case 'w':	/* Voluntary context switches.  */
				printf("%lu", resp->ru.ru_nvcsw);
				break;
			case 'x':	/* Exit status.  */
				printf("%u", WEXITSTATUS(resp->waitstatus));
				break;
			}
			break;

#ifdef NOT_NEEDED_YET
		case '\\':		/* Format escape.  */
			switch (*++fmt) {
			default:
				bb_putchar('\\');
				/*FALLTHROUGH*/
			case '\\':
				if (!*fmt) goto ret;
				bb_putchar(*fmt);
				break;
			case 't':
				bb_putchar('\t');
				break;
			case 'n':
				bb_putchar('\n');
				break;
			}
			break;
#endif
		}
		++fmt;
	}
 /* ret: */
	bb_putchar('\n');
}
Example #16
0
static void progress_newline(void)
{
	if (!option_mask32) //if (!(option_mask32 & OPT_v))
		return;
	bb_putchar('\n');
}
Example #17
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;
}
Example #18
0
int seq_main(int argc, char **argv)
{
	enum {
		OPT_w = (1 << 0),
		OPT_s = (1 << 1),
	};
	double first, last, increment, v;
	unsigned n;
	unsigned width;
	unsigned frac_part;
	const char *sep, *opt_s = "\n";
	unsigned opt;

#if ENABLE_LOCALE_SUPPORT
	/* Undo busybox.c: on input, we want to use dot
	 * as fractional separator, regardless of current locale */
	setlocale(LC_NUMERIC, "C");
#endif

	opt = getopt32(argv, "+ws:", &opt_s);
	argc -= optind;
	argv += optind;
	first = increment = 1;
	errno = 0;
	switch (argc) {
			char *pp;
		case 3:
			increment = strtod(argv[1], &pp);
			errno |= *pp;
		case 2:
			first = strtod(argv[0], &pp);
			errno |= *pp;
		case 1:
			last = strtod(argv[argc-1], &pp);
			if (!errno && *pp == '\0')
				break;
		default:
			bb_show_usage();
	}

#if ENABLE_LOCALE_SUPPORT
	setlocale(LC_NUMERIC, "");
#endif

	/* Last checked to be compatible with: coreutils-6.10 */
	width = 0;
	frac_part = 0;
	while (1) {
		char *dot = strchrnul(*argv, '.');
		int w = (dot - *argv);
		int f = strlen(dot);
		if (width < w)
			width = w;
		argv++;
		if (!*argv)
			break;
		/* Why do the above _before_ frac check below?
		 * Try "seq 1 2.0" and "seq 1.0 2.0":
		 * coreutils never pay attention to the number
		 * of fractional digits in last arg. */
		if (frac_part < f)
			frac_part = f;
	}
	if (frac_part) {
		frac_part--;
		if (frac_part)
			width += frac_part + 1;
	}
	if (!(opt & OPT_w))
		width = 0;

	sep = "";
	v = first;
	n = 0;
	while (increment >= 0 ? v <= last : v >= last) {
		if (printf("%s%0*.*f", sep, width, frac_part, v) < 0)
			break; /* I/O error, bail out (yes, this really happens) */
		sep = opt_s;
		/* v += increment; - would accumulate floating point errors */
		n++;
		v = first + n * increment;
	}
	if (n) /* if while loop executed at least once */
		bb_putchar('\n');

	return fflush_all();
}
Example #19
0
/* Dump all but word data. */
static void dump_data(int bus_fd, int mode, unsigned first,
		      unsigned last, int *block, int blen)
{
	int i, j, res;

	puts("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f"
	     "    0123456789abcdef");

	for (i = 0; i < I2CDUMP_NUM_REGS; i += 0x10) {
		if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen)
			break;
		if (i/16 < first/16)
			continue;
		if (i/16 > last/16)
			break;

		printf("%02x: ", i);
		for (j = 0; j < 16; j++) {
			fflush_all();
			/* Skip unwanted registers */
			if (i+j < first || i+j > last) {
				printf("   ");
				if (mode == I2C_SMBUS_WORD_DATA) {
					printf("   ");
					j++;
				}
				continue;
			}

			switch (mode) {
			case I2C_SMBUS_BYTE_DATA:
				res = i2c_smbus_read_byte_data(bus_fd, i+j);
				block[i+j] = res;
				break;
			case I2C_SMBUS_WORD_DATA:
				res = i2c_smbus_read_word_data(bus_fd, i+j);
				if (res < 0) {
					block[i+j] = res;
					block[i+j+1] = res;
				} else {
					block[i+j] = res & 0xff;
					block[i+j+1] = res >> 8;
				}
				break;
			case I2C_SMBUS_BYTE:
				res = i2c_smbus_read_byte(bus_fd);
				block[i+j] = res;
				break;
			default:
				res = block[i+j];
			}

			if (mode == I2C_SMBUS_BLOCK_DATA &&
			    i+j >= blen) {
				printf("   ");
			} else if (res < 0) {
				printf("XX ");
				if (mode == I2C_SMBUS_WORD_DATA)
					printf("XX ");
			} else {
				printf("%02x ", block[i+j]);
				if (mode == I2C_SMBUS_WORD_DATA)
					printf("%02x ", block[i+j+1]);
			}

			if (mode == I2C_SMBUS_WORD_DATA)
				j++;
		}
		printf("   ");

		for (j = 0; j < 16; j++) {
			if (mode == I2C_SMBUS_BLOCK_DATA && i+j >= blen)
				break;
			/* Skip unwanted registers */
			if (i+j < first || i+j > last) {
				bb_putchar(' ');
				continue;
			}

			res = block[i+j];
			if (res < 0) {
				bb_putchar('X');
			} else if (res == 0x00 || res == 0xff) {
				bb_putchar('.');
			} else if (res < 32 || res >= 127) {
				bb_putchar('?');
			} else {
				bb_putchar(res);
			}
		}
		bb_putchar('\n');
	}
}
Example #20
0
static void
xbsd_print_disklabel(int show_all)
{
    struct xbsd_disklabel *lp = &xbsd_dlabel;
    struct xbsd_partition *pp;
    int i, j;

    if (show_all) {
        static const int d_masks[] = { BSD_D_REMOVABLE, BSD_D_ECC, BSD_D_BADSECT };

#if defined(__alpha__)
        printf("# %s:\n", disk_device);
#else
        printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0));
#endif
        if ((unsigned) lp->d_type < ARRAY_SIZE(xbsd_dktypenames)-1)
            printf("type: %s\n", xbsd_dktypenames[lp->d_type]);
        else
            printf("type: %u\n", lp->d_type);
        printf("disk: %.*s\n", (int) sizeof(lp->d_typename), lp->d_typename);
        printf("label: %.*s\n", (int) sizeof(lp->d_packname), lp->d_packname);
        printf("flags: ");
        print_flags_separated(d_masks, "removable\0""ecc\0""badsect\0", lp->d_flags, " ");
        bb_putchar('\n');
        /* On various machines the fields of *lp are short/int/long */
        /* In order to avoid problems, we cast them all to long. */
        printf("bytes/sector: %lu\n", (long) lp->d_secsize);
        printf("sectors/track: %lu\n", (long) lp->d_nsectors);
        printf("tracks/cylinder: %lu\n", (long) lp->d_ntracks);
        printf("sectors/cylinder: %lu\n", (long) lp->d_secpercyl);
        printf("cylinders: %lu\n", (long) lp->d_ncylinders);
        printf("rpm: %u\n", lp->d_rpm);
        printf("interleave: %u\n", lp->d_interleave);
        printf("trackskew: %u\n", lp->d_trackskew);
        printf("cylinderskew: %u\n", lp->d_cylskew);
        printf("headswitch: %lu\t\t# milliseconds\n",
               (long) lp->d_headswitch);
        printf("track-to-track seek: %lu\t# milliseconds\n",
               (long) lp->d_trkseek);
        printf("drivedata: ");
        for (i = NDDATA - 1; i >= 0; i--)
            if (lp->d_drivedata[i])
                break;
        if (i < 0)
            i = 0;
        for (j = 0; j <= i; j++)
            printf("%lu ", (long) lp->d_drivedata[j]);
    }
    printf("\n%u partitions:\n", lp->d_npartitions);
    printf("#       start       end      size     fstype   [fsize bsize   cpg]\n");
    pp = lp->d_partitions;
    for (i = 0; i < lp->d_npartitions; i++, pp++) {
        if (pp->p_size) {
            if (display_in_cyl_units && lp->d_secpercyl) {
                printf("  %c: %8lu%c %8lu%c %8lu%c  ",
                       'a' + i,
                       (unsigned long) pp->p_offset / lp->d_secpercyl + 1,
                       (pp->p_offset % lp->d_secpercyl) ? '*' : ' ',
                       (unsigned long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl,
                       ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ',
                       (long) pp->p_size / lp->d_secpercyl,
                       (pp->p_size % lp->d_secpercyl) ? '*' : ' '
                      );
            } else {
                printf("  %c: %8lu  %8lu  %8lu   ",
                       'a' + i,
                       (long) pp->p_offset,
                       (long) pp->p_offset + pp->p_size - 1,
                       (long) pp->p_size
                      );
            }

            if ((unsigned) pp->p_fstype < ARRAY_SIZE(xbsd_fstypes)-1)
                printf("%8.8s", xbsd_fstypes[pp->p_fstype]);
            else
                printf("%8x", pp->p_fstype);

            switch (pp->p_fstype) {
            case BSD_FS_UNUSED:
                printf("    %5lu %5lu %5.5s ",
                       (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, "");
                break;
            case BSD_FS_BSDFFS:
                printf("    %5lu %5lu %5u ",
                       (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, pp->p_cpg);
                break;
            default:
                printf("%22.22s", "");
                break;
            }
            bb_putchar('\n');
        }
    }
}
Example #21
0
int brctl_main(int argc UNUSED_PARAM, char **argv)
{
	static const char keywords[] ALIGN1 =
		"addbr\0" "delbr\0" "addif\0" "delif\0"
	IF_FEATURE_BRCTL_FANCY(
		"stp\0"
		"setageing\0" "setfd\0" "sethello\0" "setmaxage\0"
		"setpathcost\0" "setportprio\0" "setbridgeprio\0"
	)
	IF_FEATURE_BRCTL_SHOW("show\0");

	enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif
		IF_FEATURE_BRCTL_FANCY(,
			ARG_stp,
			ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage,
			ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio
		)
		IF_FEATURE_BRCTL_SHOW(, ARG_show)
	};

	int fd;
	smallint key;
	struct ifreq ifr;
	char *br, *brif;

	argv++;
	while (*argv) {
#if ENABLE_FEATURE_BRCTL_FANCY
		int ifidx[MAX_PORTS];
		unsigned long args[4];
		ifr.ifr_data = (char *) &args;
#endif

		key = index_in_strings(keywords, *argv);
		if (key == -1) /* no match found in keywords array, bail out. */
			bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
		argv++;
		fd = xsocket(AF_INET, SOCK_STREAM, 0);

#if ENABLE_FEATURE_BRCTL_SHOW
		if (key == ARG_show) { /* show */
			char brname[IFNAMSIZ];
			int bridx[MAX_PORTS];
			int i, num;
			arm_ioctl(args, BRCTL_GET_BRIDGES,
						(unsigned long) bridx, MAX_PORTS);
			num = xioctl(fd, SIOCGIFBR, args);
			puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces");
			for (i = 0; i < num; i++) {
				char ifname[IFNAMSIZ];
				int j, tabs;
				struct __bridge_info bi;
				unsigned char *x;

				if (!if_indextoname(bridx[i], brname))
					bb_perror_msg_and_die("can't get bridge name for index %d", i);
				strncpy_IFNAMSIZ(ifr.ifr_name, brname);

				arm_ioctl(args, BRCTL_GET_BRIDGE_INFO,
							(unsigned long) &bi, 0);
				xioctl(fd, SIOCDEVPRIVATE, &ifr);
				printf("%s\t\t", brname);

				/* print bridge id */
				x = (unsigned char *) &bi.bridge_id;
				for (j = 0; j < 8; j++) {
					printf("%02x", x[j]);
					if (j == 1)
						bb_putchar('.');
				}
				printf(bi.stp_enabled ? "\tyes" : "\tno");

				/* print interface list */
				arm_ioctl(args, BRCTL_GET_PORT_LIST,
							(unsigned long) ifidx, MAX_PORTS);
				xioctl(fd, SIOCDEVPRIVATE, &ifr);
				tabs = 0;
				for (j = 0; j < MAX_PORTS; j++) {
					if (!ifidx[j])
						continue;
					if (!if_indextoname(ifidx[j], ifname))
						bb_perror_msg_and_die("can't get interface name for index %d", j);
					if (tabs)
						printf("\t\t\t\t\t");
					else
						tabs = 1;
					printf("\t\t%s\n", ifname);
				}
				if (!tabs)  /* bridge has no interfaces */
					bb_putchar('\n');
			}
			goto done;
		}
#endif

		if (!*argv) /* all but 'show' need at least one argument */
			bb_show_usage();

		br = *argv++;

		if (key == ARG_addbr || key == ARG_delbr) { /* addbr or delbr */
			ioctl_or_perror_and_die(fd,
					key == ARG_addbr ? SIOCBRADDBR : SIOCBRDELBR,
					br, "bridge %s", br);
			goto done;
		}

		if (!*argv) /* all but 'addbr/delbr' need at least two arguments */
			bb_show_usage();

		strncpy_IFNAMSIZ(ifr.ifr_name, br);
		if (key == ARG_addif || key == ARG_delif) { /* addif or delif */
			brif = *argv;
			ifr.ifr_ifindex = if_nametoindex(brif);
			if (!ifr.ifr_ifindex) {
				bb_perror_msg_and_die("iface %s", brif);
			}
			ioctl_or_perror_and_die(fd,
					key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF,
					&ifr, "bridge %s", br);
			goto done_next_argv;
		}
#if ENABLE_FEATURE_BRCTL_FANCY
		if (key == ARG_stp) { /* stp */
			static const char no_yes[] ALIGN1 =
				"0\0" "off\0" "n\0" "no\0"   /* 0 .. 3 */
				"1\0" "on\0"  "y\0" "yes\0"; /* 4 .. 7 */
			int onoff = index_in_strings(no_yes, *argv);
			if (onoff < 0)
				bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name);
			onoff = (unsigned)onoff / 4;
			arm_ioctl(args, BRCTL_SET_BRIDGE_STP_STATE, onoff, 0);
			goto fire;
		}
		if ((unsigned)(key - ARG_setageing) < 4) { /* time related ops */
			static const uint8_t ops[] ALIGN1 = {
				BRCTL_SET_AGEING_TIME,          /* ARG_setageing */
				BRCTL_SET_BRIDGE_FORWARD_DELAY, /* ARG_setfd     */
				BRCTL_SET_BRIDGE_HELLO_TIME,    /* ARG_sethello  */
				BRCTL_SET_BRIDGE_MAX_AGE        /* ARG_setmaxage */
			};
			arm_ioctl(args, ops[key - ARG_setageing], str_to_jiffies(*argv), 0);
			goto fire;
		}
		if (key == ARG_setpathcost
		 || key == ARG_setportprio
		 || key == ARG_setbridgeprio
		) {
			static const uint8_t ops[] ALIGN1 = {
				BRCTL_SET_PATH_COST,      /* ARG_setpathcost   */
				BRCTL_SET_PORT_PRIORITY,  /* ARG_setportprio   */
				BRCTL_SET_BRIDGE_PRIORITY /* ARG_setbridgeprio */
			};
			int port = -1;
			unsigned arg1, arg2;

			if (key != ARG_setbridgeprio) {
				/* get portnum */
				unsigned i;

				port = if_nametoindex(*argv++);
				if (!port)
					bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, "port");
				memset(ifidx, 0, sizeof ifidx);
				arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx,
						MAX_PORTS);
				xioctl(fd, SIOCDEVPRIVATE, &ifr);
				for (i = 0; i < MAX_PORTS; i++) {
					if (ifidx[i] == port) {
						port = i;
						break;
					}
				}
			}
			arg1 = port;
			arg2 = xatoi_positive(*argv);
			if (key == ARG_setbridgeprio) {
				arg1 = arg2;
				arg2 = 0;
			}
			arm_ioctl(args, ops[key - ARG_setpathcost], arg1, arg2);
		}
 fire:
		/* Execute the previously set command */
		xioctl(fd, SIOCDEVPRIVATE, &ifr);
#endif
 done_next_argv:
		argv++;
 done:
		close(fd);
	}

	return EXIT_SUCCESS;
}
Example #22
0
static void number_process(int first_digit)
{
	unsigned i;
	int num;
	int keypress;
	char num_input[sizeof(int)*4]; /* more than enough */

	num_input[0] = first_digit;

	/* Clear the current line, print a prompt, and then print the digit */
	clear_line();
	printf(":%c", first_digit);

	/* Receive input until a letter is given */
	i = 1;
	while (i < sizeof(num_input)-1) {
		keypress = less_getch(i + 1);
		if ((unsigned)keypress > 255 || !isdigit(num_input[i]))
			break;
		num_input[i] = keypress;
		bb_putchar(keypress);
		i++;
	}

	num_input[i] = '\0';
	num = bb_strtou(num_input, NULL, 10);
	/* on format error, num == -1 */
	if (num < 1 || num > MAXLINES) {
		buffer_print();
		return;
	}

	/* We now know the number and the letter entered, so we process them */
	switch (keypress) {
	case KEYCODE_DOWN: case 'z': case 'd': case 'e': case ' ': case '\015':
		buffer_down(num);
		break;
	case KEYCODE_UP: case 'b': case 'w': case 'y': case 'u':
		buffer_up(num);
		break;
	case 'g': case '<': case 'G': case '>':
		cur_fline = num + max_displayed_line;
		read_lines();
		buffer_line(num - 1);
		break;
	case 'p': case '%':
		num = num * (max_fline / 100); /* + max_fline / 2; */
		cur_fline = num + max_displayed_line;
		read_lines();
		buffer_line(num);
		break;
#if ENABLE_FEATURE_LESS_REGEXP
	case 'n':
		goto_match(match_pos + num);
		break;
	case '/':
		option_mask32 &= ~LESS_STATE_MATCH_BACKWARDS;
		regex_process();
		break;
	case '?':
		option_mask32 |= LESS_STATE_MATCH_BACKWARDS;
		regex_process();
		break;
#endif
	}
}
Example #23
0
int tunctl_main(int argc UNUSED_PARAM, char **argv)
{
	struct ifreq ifr;
	int fd;
	const char *opt_name = "tap%d";
	const char *opt_device = "/dev/net/tun";
#if ENABLE_FEATURE_TUNCTL_UG
	const char *opt_user, *opt_group;
	long user = -1, group = -1;
#endif
	unsigned opts;

	enum {
		OPT_f = 1 << 0, // control device name (/dev/net/tun)
		OPT_t = 1 << 1, // create named interface
		OPT_d = 1 << 2, // delete named interface
#if ENABLE_FEATURE_TUNCTL_UG
		OPT_u = 1 << 3, // set new interface owner
		OPT_g = 1 << 4, // set new interface group
		OPT_b = 1 << 5, // brief output
#endif
	};

	opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d
	opts = getopt32(argv, "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b"),
			&opt_device, &opt_name, &opt_name
			IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group));

	// select device
	memset(&ifr, 0, sizeof(ifr));
	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
	strncpy_IFNAMSIZ(ifr.ifr_name, opt_name);

	// open device
	fd = xopen(opt_device, O_RDWR);
	IOCTL(fd, TUNSETIFF, (void *)&ifr);

	// delete?
	if (opts & OPT_d) {
		IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0);
		printf("Set '%s' nonpersistent\n", ifr.ifr_name);
		return EXIT_SUCCESS;
	}

	// create
#if ENABLE_FEATURE_TUNCTL_UG
	if (opts & OPT_g) {
		group = xgroup2gid(opt_group);
		IOCTL(fd, TUNSETGROUP, (void *)(uintptr_t)group);
	} else
		user = geteuid();
	if (opts & OPT_u)
		user = xuname2uid(opt_user);
	IOCTL(fd, TUNSETOWNER, (void *)(uintptr_t)user);
#endif
	IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)1);

	// show info
#if ENABLE_FEATURE_TUNCTL_UG
	if (opts & OPT_b) {
		puts(ifr.ifr_name);
	} else {
		printf("Set '%s' %spersistent", ifr.ifr_name, "");
		printf(" and owned by uid %ld", user);
		if (group != -1)
			printf(" gid %ld", group);
		bb_putchar('\n');
	}
#else
	puts(ifr.ifr_name);
#endif
	return EXIT_SUCCESS;
}
Example #24
0
int uname_main(int argc UNUSED_PARAM, char **argv)
{
#if ENABLE_LONG_OPTS
	static const char uname_longopts[] ALIGN1 =
		/* name, has_arg, val */
		"all\0"               No_argument       "a"
		"kernel-name\0"       No_argument       "s"
		"nodename\0"          No_argument       "n"
		"kernel-release\0"    No_argument       "r"
		"release\0"           No_argument       "r"
		"kernel-version\0"    No_argument       "v"
		"machine\0"           No_argument       "m"
		"processor\0"         No_argument       "p"
		"hardware-platform\0" No_argument       "i"
		"operating-system\0"  No_argument       "o"
#ifdef MY_ABC_HERE
		"synology-unique\0"   No_argument       "u"
#endif
	;
#endif
	uname_info_t uname_info;
#if defined(__sparc__) && defined(__linux__)
	char *fake_sparc = getenv("FAKE_SPARC");
#endif
	const char *unknown_str = "unknown";
	const char *fmt;
	const unsigned short *delta;
	unsigned toprint;

	IF_LONG_OPTS(applet_long_options = uname_longopts);
	toprint = getopt32(argv, options);

	if (argv[optind]) { /* coreutils-6.9 compat */
		bb_show_usage();
	}

	if (toprint & (1 << OPT_ALL_BIT)) { /* -a => all opts on */
		toprint = (1 << OPT_ALL_BIT) - 1;
		unknown_str = ""; /* -a does not print unknown fields */
	}

	if (toprint == 0) { /* no opts => -s (sysname) */
		toprint = 1;
	}

	uname(&uname_info.name); /* never fails */

#if defined(__sparc__) && defined(__linux__)
	if (fake_sparc && (fake_sparc[0] | 0x20) == 'y') {
		strcpy(uname_info.name.machine, "sparc");
	}
#endif
	strcpy(uname_info.processor, unknown_str);
	strcpy(uname_info.platform, unknown_str);
	strcpy(uname_info.os, "GNU/Linux");
#ifdef MY_ABC_HERE
	if (1 != GetKeyValue("/etc.defaults/synoinfo.conf", "unique", 
	                     uname_info.unique, sizeof(uname_info.unique))) {
		strcpy(uname_info.unique, unknown_str);
	}
#endif
#if 0
	/* Fedora does something like this */
	strcpy(uname_info.processor, uname_info.name.machine);
	strcpy(uname_info.platform, uname_info.name.machine);
	if (uname_info.platform[0] == 'i'
	 && uname_info.platform[1]
	 && uname_info.platform[2] == '8'
	 && uname_info.platform[3] == '6'
	) {
		uname_info.platform[1] = '3';
	}
#endif

	delta = utsname_offset;
	fmt = " %s" + 1;
	do {
		if (toprint & 1) {
			const char *p = (char *)(&uname_info) + *delta;
			if (p[0]) {
				printf(fmt, p);
				fmt = " %s";
			}
		}
		++delta;
	} while (toprint >>= 1);
	bb_putchar('\n');

	fflush_stdout_and_exit(EXIT_SUCCESS); /* coreutils-6.9 compat */
}
Example #25
0
File: id.c Project: nawawi/busybox
int id_main(int argc UNUSED_PARAM, char **argv)
{
	uid_t ruid;
	gid_t rgid;
	uid_t euid;
	gid_t egid;
	unsigned opt;
	int i;
	int status = EXIT_SUCCESS;
	const char *prefix;
	const char *username;
#if ENABLE_SELINUX
	security_context_t scontext = NULL;
#endif

	if (ENABLE_GROUPS && (!ENABLE_ID || applet_name[0] == 'g')) {
		/* TODO: coreutils groups prepend "USER : "******"") | JUST_ALL_GROUPS | NAME_NOT_NUMBER;
	} else {
		/* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/
		/* Don't allow more than one username */
		opt = getopt32(argv, "^"
			"rnugG" IF_SELINUX("Z")
			"\0"
			"?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG"
			IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G")
		);
	}

	username = argv[optind];
	if (username) {
		struct passwd *p = xgetpwnam(username);
		euid = ruid = p->pw_uid;
		egid = rgid = p->pw_gid;
	} else {
		egid = getegid();
		rgid = getgid();
		euid = geteuid();
		ruid = getuid();
	}
	/* JUST_ALL_GROUPS ignores -r PRINT_REAL flag even if man page for */
	/* id says: print the real ID instead of the effective ID, with -ugG */
	/* in fact in this case egid is always printed if egid != rgid */
	if (!opt || (opt & JUST_ALL_GROUPS)) {
		gid_t *groups;
		int n;

		if (!opt) {
			/* Default Mode */
			status |= print_user(ruid, "uid=");
			status |= print_group(rgid, " gid=");
			if (euid != ruid)
				status |= print_user(euid, " euid=");
			if (egid != rgid)
				status |= print_group(egid, " egid=");
		} else {
			/* JUST_ALL_GROUPS */
			status |= print_group(rgid, NULL);
			if (egid != rgid)
				status |= print_group(egid, " ");
		}
		/* We are supplying largish buffer, trying
		 * to not run get_groups() twice. That might be slow
		 * ("user database in remote SQL server" case) */
		groups = xmalloc(64 * sizeof(groups[0]));
		n = 64;
		if (get_groups(username, rgid, groups, &n) < 0) {
			/* Need bigger buffer after all */
			groups = xrealloc(groups, n * sizeof(groups[0]));
			get_groups(username, rgid, groups, &n);
		}
		if (n > 0) {
			/* Print the list */
			prefix = " groups=";
			for (i = 0; i < n; i++) {
				if (opt && (groups[i] == rgid || groups[i] == egid))
					continue;
				status |= print_group(groups[i], opt ? " " : prefix);
				prefix = ",";
			}
		} else if (n < 0) { /* error in get_groups() */
			if (ENABLE_DESKTOP)
				bb_error_msg_and_die("can't get groups");
			return EXIT_FAILURE;
		}
		if (ENABLE_FEATURE_CLEAN_UP)
			free(groups);
#if ENABLE_SELINUX
		if (is_selinux_enabled()) {
			if (getcon(&scontext) == 0)
				printf(" context=%s", scontext);
		}
#endif
	} else if (opt & PRINT_REAL) {
		euid = ruid;
		egid = rgid;
	}

	if (opt & JUST_USER)
		status |= print_user(euid, NULL);
	else if (opt & JUST_GROUP)
		status |= print_group(egid, NULL);
#if ENABLE_SELINUX
	else if (opt & JUST_CONTEXT) {
		selinux_or_die();
		if (username || getcon(&scontext)) {
			bb_error_msg_and_die("can't get process context%s",
				username ? " for a different user" : "");
		}
		fputs(scontext, stdout);
	}
	/* freecon(NULL) seems to be harmless */
	if (ENABLE_FEATURE_CLEAN_UP)
		freecon(scontext);
#endif
	bb_putchar('\n');
	fflush_stdout_and_exit(status);
}
char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt)
{
	/* Was static char[BIGNUM] */
	enum { sizeof_passwd = 128 };
	static char *passwd;

	char *ret;
	int i;
	struct sigaction sa, oldsa;
	struct termios tio, oldtio;

	tcgetattr(fd, &oldtio);
	tcflush(fd, TCIFLUSH);
	tio = oldtio;
#ifndef IUCLC
# define IUCLC 0
#endif
	tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
	tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
	tcsetattr(fd, TCSANOW, &tio);

	memset(&sa, 0, sizeof(sa));
	/* sa.sa_flags = 0; - no SA_RESTART! */
	/* SIGINT and SIGALRM will interrupt reads below */
	sa.sa_handler = askpass_timeout;
	sigaction(SIGINT, &sa, &oldsa);
	if (timeout) {
		sigaction_set(SIGALRM, &sa);
		alarm(timeout);
	}

	fputs(prompt, stdout);
	fflush_all();

	if (!passwd)
		passwd = xmalloc(sizeof_passwd);
	ret = passwd;
	i = 0;
	while (1) {
		int r = read(fd, &ret[i], 1);
		if (r < 0) {
			/* read is interrupted by timeout or ^C */
			ret = NULL;
			break;
		}
		if (r == 0 /* EOF */
		 || ret[i] == '\r' || ret[i] == '\n' /* EOL */
		 || ++i == sizeof_passwd-1 /* line limit */
		) {
			ret[i] = '\0';
			break;
		}
	}

	if (timeout) {
		alarm(0);
	}
	sigaction_set(SIGINT, &oldsa);
	tcsetattr(fd, TCSANOW, &oldtio);
	bb_putchar('\n');
	fflush_all();
	return ret;
}
Example #27
0
static int generate_output(char **argv, int argc, const char *optstr, const struct option *longopts)
{
    int exit_code = 0; /* We assume everything will be OK */
    int opt;
#if ENABLE_FEATURE_GETOPT_LONG
    int longindex;
#endif
    const char *charptr;

    if (quiet_errors) /* No error reporting from getopt(3) */
        opterr = 0;

    /* We used it already in main() in getopt32(),
     * we *must* reset getopt(3): */
#ifdef __GLIBC__
    optind = 0;
#else /* BSD style */
    optind = 1;
    /* optreset = 1; */
#endif

    while (1) {
        opt =
#if ENABLE_FEATURE_GETOPT_LONG
            alternative ?
            getopt_long_only(argc, argv, optstr, longopts, &longindex) :
            getopt_long(argc, argv, optstr, longopts, &longindex);
#else
            getopt(argc, argv, optstr);
#endif
        if (opt == -1)
            break;
        if (opt == '?' || opt == ':' )
            exit_code = 1;
        else if (!quiet_output) {
#if ENABLE_FEATURE_GETOPT_LONG
            if (opt == LONG_OPT) {
                printf(" --%s", longopts[longindex].name);
                if (longopts[longindex].has_arg)
                    printf(" %s",
                           normalize(optarg ? optarg : ""));
            } else
#endif
                if (opt == NON_OPT)
                    printf(" %s", normalize(optarg));
                else {
                    printf(" -%c", opt);
                    charptr = strchr(optstr, opt);
                    if (charptr != NULL && *++charptr == ':')
                        printf(" %s",
                               normalize(optarg ? optarg : ""));
                }
        }
    }

    if (!quiet_output) {
        printf(" --");
        while (optind < argc)
            printf(" %s", normalize(argv[optind++]));
        bb_putchar('\n');
    }
    return exit_code;
}
Example #28
0
int sendmail_main(int argc UNUSED_PARAM, char **argv)
{
	char *opt_connect = opt_connect;
	char *opt_from = NULL;
	char *s;
	llist_t *list = NULL;
	char *host = sane_address(safe_gethostname());
	unsigned nheaders = 0;
	int code;
	enum {
		HDR_OTHER = 0,
		HDR_TOCC,
		HDR_BCC,
	} last_hdr = 0;
	int check_hdr;
	int has_to = 0;

	enum {
	//--- standard options
		OPT_t = 1 << 0,         // read message for recipients, append them to those on cmdline
		OPT_f = 1 << 1,         // sender address
		OPT_o = 1 << 2,         // various options. -oi IMPLIED! others are IGNORED!
		OPT_i = 1 << 3,         // IMPLIED!
	//--- BB specific options
		OPT_w = 1 << 4,         // network timeout
		OPT_H = 1 << 5,         // use external connection helper
		OPT_S = 1 << 6,         // specify connection string
		OPT_a = 1 << 7,         // authentication tokens
		OPT_v = 1 << 8,         // verbosity
	};

	// init global variables
	INIT_G();

	// save initial stdin since body is piped!
	xdup2(STDIN_FILENO, 3);
	G.fp0 = xfdopen_for_read(3);

	// parse options
	// -v is a counter, -H and -S are mutually exclusive, -a is a list
	opt_complementary = "vv:w+:H--S:S--H:a::";
	// N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect
	// -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility,
	// it is still under development.
	opts = getopt32(argv, "tf:o:iw:H:S:a::v", &opt_from, NULL,
			&timeout, &opt_connect, &opt_connect, &list, &verbose);
	//argc -= optind;
	argv += optind;

	// process -a[upm]<token> options
	if ((opts & OPT_a) && !list)
		bb_show_usage();
	while (list) {
		char *a = (char *) llist_pop(&list);
		if ('u' == a[0])
			G.user = xstrdup(a+1);
		if ('p' == a[0])
			G.pass = xstrdup(a+1);
		// N.B. we support only AUTH LOGIN so far
		//if ('m' == a[0])
		//	G.method = xstrdup(a+1);
	}
	// N.B. list == NULL here
	//bb_info_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv);

	// connect to server

	// connection helper ordered? ->
	if (opts & OPT_H) {
		const char *args[] = { "sh", "-c", opt_connect, NULL };
		// plug it in
		launch_helper(args);
		// Now:
		// our stdout will go to helper's stdin,
		// helper's stdout will be available on our stdin.

		// Wait for initial server message.
		// If helper (such as openssl) invokes STARTTLS, the initial 220
		// is swallowed by helper (and not repeated after TLS is initiated).
		// We will send NOOP cmd to server and check the response.
		// We should get 220+250 on plain connection, 250 on STARTTLSed session.
		//
		// The problem here is some servers delay initial 220 message,
		// and consider client to be a spammer if it starts sending cmds
		// before 220 reached it. The code below is unsafe in this regard:
		// in non-STARTTLSed case, we potentially send NOOP before 220
		// is sent by server.
		// Ideas? (--delay SECS opt? --assume-starttls-helper opt?)
		code = smtp_check("NOOP", -1);
		if (code == 220)
			// we got 220 - this is not STARTTLSed connection,
			// eat 250 response to our NOOP
			smtp_check(NULL, 250);
		else
		if (code != 250)
			bb_error_msg_and_die("SMTP init failed");
	} else {
		// vanilla connection
		int fd;
		// host[:port] not explicitly specified? -> use $SMTPHOST
		// no $SMTPHOST? -> use localhost
		if (!(opts & OPT_S)) {
			opt_connect = getenv("SMTPHOST");
			if (!opt_connect)
				opt_connect = (char *)"127.0.0.1";
		}
		// do connect
		fd = create_and_connect_stream_or_die(opt_connect, 25);
		// and make ourselves a simple IO filter
		xmove_fd(fd, STDIN_FILENO);
		xdup2(STDIN_FILENO, STDOUT_FILENO);

		// Wait for initial server 220 message
		smtp_check(NULL, 220);
	}

	// we should start with modern EHLO
	if (250 != smtp_checkp("EHLO %s", host, -1))
		smtp_checkp("HELO %s", host, 250);

	// perform authentication
	if (opts & OPT_a) {
		smtp_check("AUTH LOGIN", 334);
		// we must read credentials unless they are given via -a[up] options
		if (!G.user || !G.pass)
			get_cred_or_die(4);
		encode_base64(NULL, G.user, NULL);
		smtp_check("", 334);
		encode_base64(NULL, G.pass, NULL);
		smtp_check("", 235);
	}

	// set sender
	// N.B. we have here a very loosely defined algorythm
	// since sendmail historically offers no means to specify secrets on cmdline.
	// 1) server can require no authentication ->
	//	we must just provide a (possibly fake) reply address.
	// 2) server can require AUTH ->
	//	we must provide valid username and password along with a (possibly fake) reply address.
	//	For the sake of security username and password are to be read either from console or from a secured file.
	//	Since reading from console may defeat usability, the solution is either to read from a predefined
	//	file descriptor (e.g. 4), or again from a secured file.

	// got no sender address? use auth name, then UID username as a last resort
	if (!opt_from) {
		opt_from = xasprintf("%s@%s",
		                     G.user ? G.user : xuid2uname(getuid()),
		                     xgethostbyname(host)->h_name);
	}
	free(host);

	smtp_checkp("MAIL FROM:<%s>", opt_from, 250);

	// process message

	// read recipients from message and add them to those given on cmdline.
	// this means we scan stdin for To:, Cc:, Bcc: lines until an empty line
	// and then use the rest of stdin as message body
	code = 0; // set "analyze headers" mode
	while ((s = xmalloc_fgetline(G.fp0)) != NULL) {
 dump:
		// put message lines doubling leading dots
		if (code) {
			// escape leading dots
			// N.B. this feature is implied even if no -i (-oi) switch given
			// N.B. we need to escape the leading dot regardless of
			// whether it is single or not character on the line
			if ('.' == s[0] /*&& '\0' == s[1] */)
				bb_putchar('.');
			// dump read line
			send_r_n(s);
			free(s);
			continue;
		}

		// analyze headers
		// To: or Cc: headers add recipients
		check_hdr = (0 == strncasecmp("To:", s, 3));
		has_to |= check_hdr;
		if (opts & OPT_t) {
			if (check_hdr || 0 == strncasecmp("Bcc:" + 1, s, 3)) {
				rcptto_list(s+3);
				last_hdr = HDR_TOCC;
				goto addheader;
			}
			// Bcc: header adds blind copy (hidden) recipient
			if (0 == strncasecmp("Bcc:", s, 4)) {
				rcptto_list(s+4);
				free(s);
				last_hdr = HDR_BCC;
				continue; // N.B. Bcc: vanishes from headers!
			}
		}
		check_hdr = (list && isspace(s[0]));
		if (strchr(s, ':') || check_hdr) {
			// other headers go verbatim
			// N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines.
			// Continuation is denoted by prefixing additional lines with whitespace(s).
			// Thanks (stefan.seyfried at googlemail.com) for pointing this out.
			if (check_hdr && last_hdr != HDR_OTHER) {
				rcptto_list(s+1);
				if (last_hdr == HDR_BCC)
					continue;
					// N.B. Bcc: vanishes from headers!
			} else {
				last_hdr = HDR_OTHER;
			}
 addheader:
			// N.B. we allow MAX_HEADERS generic headers at most to prevent attacks
			if (MAX_HEADERS && ++nheaders >= MAX_HEADERS)
				goto bail;
			llist_add_to_end(&list, s);
		} else {
			// a line without ":" (an empty line too, by definition) doesn't look like a valid header
			// so stop "analyze headers" mode
 reenter:
			// put recipients specified on cmdline
			check_hdr = 1;
			while (*argv) {
				char *t = sane_address(*argv);
				rcptto(t);
				//if (MAX_HEADERS && ++nheaders >= MAX_HEADERS)
				//	goto bail;
				if (!has_to) {
					const char *hdr;

					if (check_hdr && argv[1])
						hdr = "To: %s,";
					else if (check_hdr)
						hdr = "To: %s";
					else if (argv[1])
						hdr = "To: %s," + 3;
					else
						hdr = "To: %s" + 3;
					llist_add_to_end(&list,
							xasprintf(hdr, t));
					check_hdr = 0;
				}
				argv++;
			}
			// enter "put message" mode
			// N.B. DATA fails iff no recipients were accepted (or even provided)
			// in this case just bail out gracefully
			if (354 != smtp_check("DATA", -1))
				goto bail;
			// dump the headers
			while (list) {
				send_r_n((char *) llist_pop(&list));
			}
			// stop analyzing headers
			code++;
			// N.B. !s means: we read nothing, and nothing to be read in the future.
			// just dump empty line and break the loop
			if (!s) {
				send_r_n("");
				break;
			}
			// go dump message body
			// N.B. "s" already contains the first non-header line, so pretend we read it from input
			goto dump;
		}
	}
	// odd case: we didn't stop "analyze headers" mode -> message body is empty. Reenter the loop
	// N.B. after reenter code will be > 0
	if (!code)
		goto reenter;

	// finalize the message
	smtp_check(".", 250);
 bail:
	// ... and say goodbye
	smtp_check("QUIT", 221);
	// cleanup
	if (ENABLE_FEATURE_CLEAN_UP)
		fclose(G.fp0);

	return EXIT_SUCCESS;
}
Example #29
0
int cal_main(int argc, char **argv)
{
	struct tm *local_time;
	struct tm zero_tm;
	time_t now;
	unsigned month, year, flags, i;
	char *month_names[12];
	char day_headings[28];	/* 28 for julian, 21 for nonjulian */
	char buf[40];

	flags = getopt32(argv, "jy");
	/* This sets julian = flags & 1: */
	option_mask32 &= 1;
	month = 0;
	argv += optind;
	argc -= optind;

	if (argc > 2) {
		bb_show_usage();
	}

	if (!argc) {
		time(&now);
		local_time = localtime(&now);
		year = local_time->tm_year + 1900;
		if (!(flags & 2)) { /* no -y */
			month = local_time->tm_mon + 1;
		}
	} else {
		if (argc == 2) {
			month = xatou_range(*argv++, 1, 12);
		}
		year = xatou_range(*argv, 1, 9999);
	}

	blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian);

	i = 0;
	do {
		zero_tm.tm_mon = i;
		strftime(buf, sizeof(buf), "%B", &zero_tm);
		month_names[i] = xstrdup(buf);

		if (i < 7) {
			zero_tm.tm_wday = i;
			strftime(buf, sizeof(buf), "%a", &zero_tm);
			strncpy(day_headings + i * (3+julian) + julian, buf, 2);
		}
	} while (++i < 12);

	if (month) {
		unsigned row, len, days[MAXDAYS];
		unsigned *dp = days;
		char lineout[30];

		day_array(month, year, dp);
		len = sprintf(lineout, "%s %d", month_names[month - 1], year);
		printf("%*s%s\n%s\n",
			   ((7*julian + WEEK_LEN) - len) / 2, "",
			   lineout, day_headings);
		for (row = 0; row < 6; row++) {
			build_row(lineout, dp)[0] = '\0';
			dp += 7;
			trim_trailing_spaces_and_print(lineout);
		}
	} else {
		unsigned row, which_cal, week_len, days[12][MAXDAYS];
		unsigned *dp;
		char lineout[80];

		sprintf(lineout, "%d", year);
		center(lineout,
			   (WEEK_LEN * 3 + HEAD_SEP * 2)
			   + julian * (J_WEEK_LEN * 2 + HEAD_SEP
						   - (WEEK_LEN * 3 + HEAD_SEP * 2)),
			   0);
		puts("\n");		/* two \n's */
		for (i = 0; i < 12; i++) {
			day_array(i + 1, year, days[i]);
		}
		blank_string(lineout, sizeof(lineout));
		week_len = WEEK_LEN + julian * (J_WEEK_LEN - WEEK_LEN);
		for (month = 0; month < 12; month += 3-julian) {
			center(month_names[month], week_len, HEAD_SEP);
			if (!julian) {
				center(month_names[month + 1], week_len, HEAD_SEP);
			}
			center(month_names[month + 2 - julian], week_len, 0);
			printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings);
			if (!julian) {
				printf("%*s%s", HEAD_SEP, "", day_headings);
			}
			bb_putchar('\n');
			for (row = 0; row < (6*7); row += 7) {
				for (which_cal = 0; which_cal < 3-julian; which_cal++) {
					dp = days[month + which_cal] + row;
					build_row(lineout + which_cal * (week_len + 2), dp);
				}
				/* blank_string took care of nul termination. */
				trim_trailing_spaces_and_print(lineout);
			}
		}
	}

	fflush_stdout_and_exit(EXIT_SUCCESS);
}
int hostname_main(int argc UNUSED_PARAM, char **argv)
{
	enum {
		OPT_d = 0x1,
		OPT_f = 0x2,
		OPT_i = 0x4,
		OPT_s = 0x8,
		OPT_F = 0x10,
		OPT_dfi = 0x7,
	};

	unsigned opts;
	char *buf;
	char *hostname_str;

#if ENABLE_LONG_OPTS
	applet_long_options =
		"domain\0"     No_argument "d"
		"fqdn\0"       No_argument "f"
	//Enable if seen in active use in some distro:
	//	"long\0"       No_argument "f"
	//	"ip-address\0" No_argument "i"
	//	"short\0"      No_argument "s"
	//	"verbose\0"    No_argument "v"
		"file\0"       No_argument "F"
		;

#endif
	/* dnsdomainname from net-tools 1.60, hostname 1.100 (2001-04-14),
	 * supports hostname's options too (not just -v as manpage says) */
	opts = getopt32(argv, "dfisF:v", &hostname_str);
	argv += optind;
	buf = safe_gethostname();
	if (applet_name[0] == 'd') /* dnsdomainname? */
		opts = OPT_d;

	if (opts & OPT_dfi) {
		/* Cases when we need full hostname (or its part) */
		struct hostent *hp;
		char *p;

		hp = xgethostbyname(buf);
		p = strchrnul(hp->h_name, '.');
		if (opts & OPT_f) {
			puts(hp->h_name);
		} else if (opts & OPT_s) {
			*p = '\0';
			puts(hp->h_name);
		} else if (opts & OPT_d) {
			if (*p)
				puts(p + 1);
		} else /*if (opts & OPT_i)*/ {
			if (hp->h_length == sizeof(struct in_addr)) {
				struct in_addr **h_addr_list = (struct in_addr **)hp->h_addr_list;
				while (*h_addr_list) {
					printf(h_addr_list[1] ? "%s " : "%s", inet_ntoa(**h_addr_list));
					h_addr_list++;
				}
				bb_putchar('\n');
			}
		}
	} else if (opts & OPT_s) {
		strchrnul(buf, '.')[0] = '\0';
		puts(buf);
	} else if (opts & OPT_F) {
		/* Set the hostname */
		do_sethostname(hostname_str, 1);
	} else if (argv[0]) {
		/* Set the hostname */
		do_sethostname(argv[0], 0);
	} else {
		/* Just print the current hostname */
		puts(buf);
	}

	if (ENABLE_FEATURE_CLEAN_UP)
		free(buf);
	return EXIT_SUCCESS;
}