Example #1
0
int mknod_main(int argc, char **argv)
{
	mode_t mode;
	dev_t dev;
	const char *name;

	mode = getopt_mk_fifo_nod(argc, argv);
	argv += optind;
	argc -= optind;

	if ((argc >= 2) && ((name = strchr(modes_chars, argv[1][0])) != NULL)) {
		mode |= modes_cubp[(int)(name[4])];

		dev = 0;
		if ((*name != 'p') && ((argc -= 2) == 2)) {
			/* Autodetect what the system supports; these macros should
			 * optimize out to two constants. */
			dev = makedev(xatoul_range(argv[2], 0, major(UINT_MAX)),
			              xatoul_range(argv[3], 0, minor(UINT_MAX)));
		}

		if (argc == 2) {
			name = *argv;
			if (mknod(name, mode, dev) == 0) {
				return EXIT_SUCCESS;
			}
			bb_perror_msg_and_die("%s", name);
		}
	}
	bb_show_usage();
}
Example #2
0
int vconfig_main(int argc, char **argv)
{
	struct vlan_ioctl_args ifr;
	const char *p;
	int fd;

	if (argc < 3) {
		bb_show_usage();
	}

	/* Don't bother closing the filedes.  It will be closed on cleanup. */
	/* Will die if 802.1q is not present */
	xopen(conf_file_name, O_RDONLY);

	memset(&ifr, 0, sizeof(struct vlan_ioctl_args));

	++argv;
	p = xfind_str(cmds+2, *argv);
	ifr.cmd = *p;
	if (argc != p[-1]) {
		bb_show_usage();
	}

	if (ifr.cmd == SET_VLAN_NAME_TYPE_CMD) { /* set_name_type */
		ifr.u.name_type = *xfind_str(name_types+1, argv[1]);
	} else {
		if (strlen(argv[1]) >= IF_NAMESIZE) {
			bb_error_msg_and_die("if_name >= %d chars", IF_NAMESIZE);
		}
		strcpy(ifr.device1, argv[1]);
		p = argv[2];

		/* I suppose one could try to combine some of the function calls below,
		 * since ifr.u.flag, ifr.u.VID, and ifr.u.skb_priority are all same-sized
		 * (unsigned) int members of a unions.  But because of the range checking,
		 * doing so wouldn't save that much space and would also make maintainence
		 * more of a pain. */
		if (ifr.cmd == SET_VLAN_FLAG_CMD) { /* set_flag */
			ifr.u.flag = xatoul_range(p, 0, 1);
			/* DM: in order to set reorder header, qos must be set */
			ifr.vlan_qos = xatoul_range(argv[3], 0, 7);
		} else if (ifr.cmd == ADD_VLAN_CMD) { /* add */
			ifr.u.VID = xatoul_range(p, 0, VLAN_GROUP_ARRAY_LEN-1);
		} else if (ifr.cmd != DEL_VLAN_CMD) { /* set_{egress|ingress}_map */
			ifr.u.skb_priority = xatou(p);
			ifr.vlan_qos = xatoul_range(argv[3], 0, 7);
		}
	}

	fd = xsocket(AF_INET, SOCK_STREAM, 0);
	if (ioctl(fd, SIOCSIFVLAN, &ifr) < 0) {
		bb_perror_msg_and_die("ioctl error for %s", *argv);
	}

	return 0;
}
Example #3
0
int dmesg_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
	int len;
	char *buf;
	char *size, *level;
	unsigned flags = getopt32(argv, "cs:n:", &size, &level);
	enum {
		OPT_c = 1<<0,
		OPT_s = 1<<1,
		OPT_n = 1<<2
	};

	if (flags & OPT_n) {
		if (klogctl(8, NULL, xatoul_range(level, 0, 10)))
			bb_perror_msg_and_die("klogctl");
		return EXIT_SUCCESS;
	}

	len = (flags & OPT_s) ? xatoul_range(size, 2, INT_MAX) : 16384;
	buf = xmalloc(len);
	len = klogctl(3 + (flags & OPT_c), buf, len);
	if (len < 0)
		bb_perror_msg_and_die("klogctl");
	if (len == 0)
		return EXIT_SUCCESS;

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

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

		do {
			if (last == '\n' && buf[in] == '<')
				in += 3;
			else {
				last = buf[in++];
				bb_putchar(last);
			}
		} while (in < len);
		if (last != '\n')
			bb_putchar('\n');
	} else {
		full_write(STDOUT_FILENO, buf, len);
		if (buf[len-1] != '\n')
			bb_putchar('\n');
	}

	if (ENABLE_FEATURE_CLEAN_UP) free(buf);

	return EXIT_SUCCESS;
}
Example #4
0
int openvt_main(int argc, char **argv)
{
	int fd;
	char vtname[sizeof(VC_FORMAT) + 2];

	if (argc < 3) {
		bb_show_usage();
	}
	/* check for illegal vt number: < 1 or > 63 */
	sprintf(vtname, VC_FORMAT, (int)xatoul_range(argv[1], 1, 63));

	if (fork() == 0) {
		/* child */
		/* leave current vt (controlling tty) */
		setsid();
		/* and grab new one */
		fd = xopen(vtname, O_RDWR);
		/* Reassign stdin, stdout and sterr */
		dup2(fd, STDIN_FILENO);
		dup2(fd, STDOUT_FILENO);
		dup2(fd, STDERR_FILENO);
		while (fd > 2) close(fd--);

		BB_EXECVP(argv[2], &argv[2]);
		_exit(1);
	}
	return EXIT_SUCCESS;
}
Example #5
0
int ipcalc_main(int argc UNUSED_PARAM, char **argv)
{
	unsigned opt;
	bool have_netmask = 0;
	struct in_addr s_netmask, s_broadcast, s_network, s_ipaddr;
	/* struct in_addr { in_addr_t s_addr; }  and  in_addr_t
	 * (which in turn is just a typedef to uint32_t)
	 * are essentially the same type. A few macros for less verbosity: */
#define netmask   (s_netmask.s_addr)
#define broadcast (s_broadcast.s_addr)
#define network   (s_network.s_addr)
#define ipaddr    (s_ipaddr.s_addr)
	char *ipstr;

#if ENABLE_FEATURE_IPCALC_LONG_OPTIONS
	applet_long_options = ipcalc_longopts;
#endif
	opt_complementary = "-1:?2"; /* minimum 1 arg, maximum 2 args */
	opt = getopt32(argv, "mbn" IF_FEATURE_IPCALC_FANCY("phs"));
	argv += optind;
	if (opt & SILENT)
		logmode = LOGMODE_NONE; /* suppress error_msg() output */
	opt &= ~SILENT;
	if (!(opt & (BROADCAST | NETWORK | NETPREFIX))) {
		/* if no options at all or
		 * (no broadcast,network,prefix) and (two args)... */
		if (!opt || argv[1])
			bb_show_usage();
	}

	ipstr = argv[0];
	if (ENABLE_FEATURE_IPCALC_FANCY) {
		unsigned long netprefix = 0;
		char *prefixstr;

		prefixstr = ipstr;

		while (*prefixstr) {
			if (*prefixstr == '/') {
				*prefixstr++ = '\0';
				if (*prefixstr) {
					unsigned msk;
					netprefix = xatoul_range(prefixstr, 0, 32);
					netmask = 0;
					msk = 0x80000000;
					while (netprefix > 0) {
						netmask |= msk;
						msk >>= 1;
						netprefix--;
					}
					netmask = htonl(netmask);
					/* Even if it was 0, we will signify that we have a netmask. This allows */
					/* for specification of default routes, etc which have a 0 netmask/prefix */
					have_netmask = 1;
				}
				break;
			}
			prefixstr++;
		}
	}
Example #6
0
int ipcalc_main(int argc, char **argv)
{
	unsigned opt;
	int have_netmask = 0;
	in_addr_t netmask, broadcast, network, ipaddr;
	struct in_addr a;
	char *ipstr;

#if ENABLE_FEATURE_IPCALC_LONG_OPTIONS
	applet_long_options = ipcalc_longopts;
#endif
	opt = getopt32(argv, "mbn" USE_FEATURE_IPCALC_FANCY("phs"));
	argc -= optind;
	argv += optind;
	if (opt & (BROADCAST | NETWORK | NETPREFIX)) {
		if (argc > 2 || argc <= 0)
			bb_show_usage();
	} else {
		if (argc != 1)
			bb_show_usage();
	}
	if (opt & SILENT)
		logmode = LOGMODE_NONE; /* Suppress error_msg() output */

	ipstr = argv[0];
	if (ENABLE_FEATURE_IPCALC_FANCY) {
		unsigned long netprefix = 0;
		char *prefixstr;

		prefixstr = ipstr;

		while (*prefixstr) {
			if (*prefixstr == '/') {
				*prefixstr = (char)0;
				prefixstr++;
				if (*prefixstr) {
					unsigned msk;
					netprefix = xatoul_range(prefixstr, 0, 32);
					netmask = 0;
					msk = 0x80000000;
					while (netprefix > 0) {
						netmask |= msk;
						msk >>= 1;
						netprefix--;
					}
					netmask = htonl(netmask);
					/* Even if it was 0, we will signify that we have a netmask. This allows */
					/* for specification of default routes, etc which have a 0 netmask/prefix */
					have_netmask = 1;
				}
				break;
			}
			prefixstr++;
		}
	}
Example #7
0
int taskset_main(int argc, char** argv)
{
	cpu_set_t mask, new_mask;
	pid_t pid = 0;
	unsigned opt;
	const char *state = "current\0new";
	char *p_opt = NULL, *aff = NULL;

	opt = getopt32(argc, argv, "+p:", &p_opt);

	if (opt & OPT_p) {
		if (argc == optind+1) { /* -p <aff> <pid> */
			aff = p_opt;
			p_opt = argv[optind];
		}
		argv += optind; /* me -p <arg> */
		pid = xatoul_range(p_opt, 1, ULONG_MAX); /* -p <pid> */
	} else
		aff = *++argv; /* <aff> <cmd...> */
	if (aff) {
		unsigned i = 0;
		unsigned long l = xstrtol_range(aff, 0, 1, LONG_MAX);

		CPU_ZERO(&new_mask);
		while (i < CPU_SETSIZE && l >= (1<<i)) {
			if ((1<<i) & l)
				CPU_SET(i, &new_mask);
			++i;
		}
	}

	if (opt & OPT_p) {
 print_aff:
		if (sched_getaffinity(pid, sizeof(mask), &mask) < 0)
			bb_perror_msg_and_die("failed to %cet pid %d's affinity", 'g', pid);
		printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n",
				pid, state, from_cpuset(mask));
		if (!*argv) /* no new affinity given or we did print already, done. */
			return EXIT_SUCCESS;
	}

	if (sched_setaffinity(pid, sizeof(new_mask), &new_mask))
		bb_perror_msg_and_die("failed to %cet pid %d's affinity", 's', pid);
	if (opt & OPT_p) {
		state += 8;
		++argv;
		goto print_aff;
	}
	++argv;
	BB_EXECVP(*argv, argv);
	bb_perror_msg_and_die("%s", *argv);
}
Example #8
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;
}
Example #9
0
static NOINLINE void INET_setroute(int action, char **args)
{
	/* char buffer instead of bona-fide struct avoids aliasing warning */
	char rt_buf[sizeof(struct rtentry)];
	struct rtentry *const rt = (void *)rt_buf;

	const char *netmask = NULL;
	int skfd, isnet, xflag;

	/* Grab the -net or -host options.  Remember they were transformed. */
	xflag = kw_lookup(tbl_hash_net_host, &args);

	/* If we did grab -net or -host, make sure we still have an arg left. */
	if (*args == NULL) {
		bb_show_usage();
	}

	/* Clean out the RTREQ structure. */
	memset(rt, 0, sizeof(*rt));

	{
		const char *target = *args++;
		char *prefix;

		/* recognize x.x.x.x/mask format. */
		prefix = strchr(target, '/');
		if (prefix) {
			int prefix_len;

			prefix_len = xatoul_range(prefix+1, 0, 32);
			mask_in_addr(*rt) = htonl( ~(0xffffffffUL >> prefix_len));
			*prefix = '\0';
#if HAVE_NEW_ADDRT
			rt->rt_genmask.sa_family = AF_INET;
#endif
		} else {
			/* Default netmask. */
			netmask = "default";
		}
		/* Prefer hostname lookup is -host flag (xflag==1) was given. */
		isnet = INET_resolve(target, (struct sockaddr_in *) &rt->rt_dst,
							 (xflag & HOST_FLAG));
		if (isnet < 0) {
			bb_error_msg_and_die("resolving %s", target);
		}
		if (prefix) {
			/* do not destroy prefix for process args */
			*prefix = '/';
		}
	}
Example #10
0
static int xconnect_ftpdata(ftp_host_info_t *server, char *buf)
{
    printf("xconnect_ftpdata++++++++++++++++++++++\n");
    char *buf_ptr;
    unsigned short port_num;
    
    /* Response is "NNN garbageN1,N2,N3,N4,P1,P2[)garbage]
     * Server's IP is N1.N2.N3.N4 (we ignore it)
     * Server's port for data connection is P1*256+P2 */
    buf_ptr = strrchr(buf, ')');
    if (buf_ptr) 
        *buf_ptr = '\0';
    buf_ptr = strrchr(buf, ',');
    *buf_ptr = '\0';
    port_num = xatoul_range(buf_ptr + 1, 0, 255);
    buf_ptr = strrchr(buf, ',');
    *buf_ptr = '\0';
    port_num += xatoul_range(buf_ptr + 1, 0, 255) * 256;
    set_nport(server->lsa, htons(port_num));
    
    printf("xconnect_ftpdata============\n");
    return xconnect_stream(server->lsa);
}
Example #11
0
int chvt_main(int argc, char **argv)
{
	int fd, num;

	if (argc != 2) {
		bb_show_usage();
	}

	fd = get_console_fd();
	num = xatoul_range(argv[1], 1, 63);
	if ((-1 == ioctl(fd, VT_ACTIVATE, num))
	|| (-1 == ioctl(fd, VT_WAITACTIVE, num))) {
		bb_perror_msg_and_die("ioctl");
	}
	return EXIT_SUCCESS;
}
Example #12
0
int chrt_main(int argc, char **argv)
{
	pid_t pid = 0;
	unsigned opt;
	struct sched_param sp;
	char *p_opt = NULL, *priority = NULL;
	const char *state = "current\0new";
	int prio = 0, policy = SCHED_RR;

	opt_complementary = "r--fo:f--ro:r--fo"; /* only one policy accepted */
	opt = getopt32(argv, "+mp:rfo", &p_opt);
	if (opt & OPT_r)
		policy = SCHED_RR;
	if (opt & OPT_f)
		policy = SCHED_FIFO;
	if (opt & OPT_o)
		policy = SCHED_OTHER;

	if (opt & OPT_m) { /* print min/max */
		show_min_max(SCHED_FIFO);
		show_min_max(SCHED_RR);
		show_min_max(SCHED_OTHER);
		fflush_stdout_and_exit(EXIT_SUCCESS);
	}
	if (opt & OPT_p) {
		if (argc == optind+1) { /* -p <priority> <pid> */
			priority = p_opt;
			p_opt = argv[optind];
		}
		argv += optind; /* me -p <arg> */
		pid = xatoul_range(p_opt, 1, ULONG_MAX); /* -p <pid> */
	} else {
		argv += optind; /* me -p <arg> */
		priority = *argv;
	}
	if (priority) {
		/* from the manpage of sched_getscheduler:
		   [...] sched_priority can have a value
		   in the range 0 to 99.
		   [...] SCHED_OTHER or SCHED_BATCH  must  be  assigned
		   the  static  priority  0. [...] SCHED_FIFO  or
		   SCHED_RR can have a static priority in the range 1 to 99.
		 */
		prio = xstrtol_range(priority, 0, policy == SCHED_OTHER
													 ? 0 : 1, 99);
	}

	if (opt & OPT_p) {
		int pol = 0;
print_rt_info:
		pol = sched_getscheduler(pid);
		if (pol < 0)
			bb_perror_msg_and_die("failed to %cet pid %d's policy", 'g', pid);
		printf("pid %d's %s scheduling policy: %s\n",
				pid, state, policies[pol].name);
		if (sched_getparam(pid, &sp))
			bb_perror_msg_and_die("failed to get pid %d's attributes", pid);
		printf("pid %d's %s scheduling priority: %d\n",
				pid, state, sp.sched_priority);
		if (!*argv) /* no new prio given or we did print already, done. */
			return EXIT_SUCCESS;
	}

	sp.sched_priority = prio;
	if (sched_setscheduler(pid, policy, &sp) < 0)
		bb_perror_msg_and_die("failed to %cet pid %d's policy", 's', pid);
	if (opt & OPT_p) {
		state += 8;
		++argv;
		goto print_rt_info;
	}
	++argv;
	BB_EXECVP(*argv, argv);
	bb_simple_perror_msg_and_die(*argv);
}
Example #13
0
int arping_main(int argc, char **argv)
{
	const char *device = "eth0";
	int ifindex;
	char *source = NULL;
	char *target;

	s = xsocket(PF_PACKET, SOCK_DGRAM, 0);

	// Drop suid root privileges
	xsetuid(getuid());

	{
		unsigned opt;
		char *_count, *_timeout;

		/* Dad also sets quit_on_reply.
		 * Advert also sets unsolicited.
		 */
		opt_complementary = "Df:AU";
		opt = getopt32(argc, argv, "DUAqfbc:w:i:s:",
					&_count, &_timeout, &device, &source);
		cfg |= opt & 0x3f; /* set respective flags */
		if (opt & 0x40) /* -c: count */
			count = xatou(_count);
		if (opt & 0x80) /* -w: timeout */
			timeout = xatoul_range(_timeout, 0, INT_MAX/2000);
		//if (opt & 0x100) /* -i: interface */
		if (strlen(device) > IF_NAMESIZE) {
			bb_error_msg_and_die("interface name '%s' is too long",
							device);
		}
		//if (opt & 0x200) /* -s: source */
	}
	argc -= optind;
	argv += optind;

	if (argc != 1)
		bb_show_usage();

	target = *argv;

	xfunc_error_retval = 2;

	{
		struct ifreq ifr;

		memset(&ifr, 0, sizeof(ifr));
		strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
		if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
			bb_error_msg_and_die("interface %s not found", device);
		}
		ifindex = ifr.ifr_ifindex;

		if (ioctl(s, SIOCGIFFLAGS, (char *) &ifr)) {
			bb_error_msg_and_die("SIOCGIFFLAGS");
		}
		if (!(ifr.ifr_flags & IFF_UP)) {
			bb_error_msg_and_die("interface %s is down", device);
		}
		if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) {
			bb_error_msg("interface %s is not ARPable", device);
			return (cfg & dad ? 0 : 2);
		}
	}

	if (!inet_aton(target, &dst)) {
		len_and_sockaddr *lsa;
		lsa = xhost_and_af2sockaddr(target, 0, AF_INET);
		memcpy(&dst, &lsa->sin.sin_addr.s_addr, 4);
		if (ENABLE_FEATURE_CLEAN_UP)
			free(lsa);
	}

	if (source && !inet_aton(source, &src)) {
		bb_error_msg_and_die("invalid source address %s", source);
	}

	if (!(cfg & dad) && (cfg & unsolicited) && src.s_addr == 0)
		src = dst;

	if (!(cfg & dad) || src.s_addr) {
		struct sockaddr_in saddr;
		int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0);

		if (device) {
			if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1)
				bb_error_msg("warning: interface %s is ignored", device);
		}
		memset(&saddr, 0, sizeof(saddr));
		saddr.sin_family = AF_INET;
		if (src.s_addr) {
			saddr.sin_addr = src;
			xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
		} else if (!(cfg & dad)) {
			socklen_t alen = sizeof(saddr);

			saddr.sin_port = htons(1025);
			saddr.sin_addr = dst;

			if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1)
				bb_perror_msg("warning: setsockopt(SO_DONTROUTE)");
			xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
			if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) {
				bb_error_msg_and_die("getsockname");
			}
			src = saddr.sin_addr;
		}
		close(probe_fd);
	}

	me.sll_family = AF_PACKET;
	me.sll_ifindex = ifindex;
	me.sll_protocol = htons(ETH_P_ARP);
	xbind(s, (struct sockaddr *) &me, sizeof(me));

	{
		socklen_t alen = sizeof(me);

		if (getsockname(s, (struct sockaddr *) &me, &alen) == -1) {
			bb_error_msg_and_die("getsockname");
		}
	}
	if (me.sll_halen == 0) {
		bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device);
		return (cfg & dad ? 0 : 2);
	}
	he = me;
	memset(he.sll_addr, -1, he.sll_halen);

	if (!(cfg & quiet)) {
		printf("ARPING to %s from %s via %s\n",
			inet_ntoa(dst), inet_ntoa(src),
			device ? device : "unknown");
	}

	if (!src.s_addr && !(cfg & dad)) {
		bb_error_msg_and_die("no src address in the non-DAD mode");
	}

	{
		struct sigaction sa;

		memset(&sa, 0, sizeof(sa));
		sa.sa_flags = SA_RESTART;

		sa.sa_handler = (void (*)(int)) finish;
		sigaction(SIGINT, &sa, NULL);

		sa.sa_handler = (void (*)(int)) catcher;
		sigaction(SIGALRM, &sa, NULL);
	}

	catcher();

	while (1) {
		sigset_t sset, osset;
		RESERVE_CONFIG_UBUFFER(packet, 4096);
		struct sockaddr_ll from;
		socklen_t alen = sizeof(from);
		int cc;

		cc = recvfrom(s, packet, 4096, 0, (struct sockaddr *) &from, &alen);
		if (cc < 0) {
			bb_perror_msg("recvfrom");
			continue;
		}
		sigemptyset(&sset);
		sigaddset(&sset, SIGALRM);
		sigaddset(&sset, SIGINT);
		sigprocmask(SIG_BLOCK, &sset, &osset);
		recv_pack(packet, cc, &from);
		sigprocmask(SIG_SETMASK, &osset, NULL);
		RELEASE_CONFIG_BUFFER(packet);
	}
}
Example #14
0
int klogd_main(int argc, char **argv)
{
	int i = i; /* silence gcc */
	char *start;

	/* do normal option parsing */
	getopt32(argv, "c:n", &start);

	if (option_mask32 & OPT_LEVEL) {
		/* Valid levels are between 1 and 8 */
		i = xatoul_range(start, 1, 8);
	}

	if (!(option_mask32 & OPT_FOREGROUND)) {
		bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
	}

	openlog("kernel", 0, LOG_KERN);

	/* Set up sig handlers */
	signal(SIGINT, klogd_signal);
	signal(SIGKILL, klogd_signal);
	signal(SIGTERM, klogd_signal);
	signal(SIGHUP, SIG_IGN);

	/* "Open the log. Currently a NOP." */
	klogctl(1, NULL, 0);

	/* Set level of kernel console messaging. */
	if (option_mask32 & OPT_LEVEL)
		klogctl(8, NULL, i);

	syslog(LOG_NOTICE, "klogd started: %s", bb_banner);

	/* Note: this code does not detect incomplete messages
	 * (messages not ending with '\n' or just when kernel
	 * generates too many messages for us to keep up)
	 * and will split them in two separate lines */
	while (1) {
		int n;
		int priority;

		n = klogctl(2, log_buffer, KLOGD_LOGBUF_SIZE - 1);
		if (n < 0) {
			if (errno == EINTR)
				continue;
			syslog(LOG_ERR, "klogd: error from klogctl(2): %d - %m",
					errno);
			break;
		}
		log_buffer[n] = '\n';
		i = 0;
		while (i < n) {
			priority = LOG_INFO;
			start = &log_buffer[i];
			if (log_buffer[i] == '<') {
				i++;
				// kernel never ganerates multi-digit prios
				//priority = 0;
				//while (log_buffer[i] >= '0' && log_buffer[i] <= '9') {
				//	priority = priority * 10 + (log_buffer[i] - '0');
				//	i++;
				//}
				if (isdigit(log_buffer[i])) {
					priority = (log_buffer[i] - '0');
					i++;
				}
				if (log_buffer[i] == '>')
					i++;
				start = &log_buffer[i];
			}
			while (log_buffer[i] != '\n')
				i++;
			log_buffer[i] = '\0';
			syslog(priority, "%s", start);
			i++;
		}
	}

	return EXIT_FAILURE;
}
Example #15
0
static uint16_t xatou16(const char *numstr)
{
    return (uint16_t)xatoul_range((char *)numstr, 0, 0xffff);
}