示例#1
0
/* cp->cache[N] is allocated and must be filled in this case */
static int get_cached(cache_t *cp, uid_t id)
{
	int i;
	for (i = 0; i < cp->size; i++)
		if (cp->cache[i].id == id)
			return i;
	i = cp->size++;
	cp->cache = xrealloc_vector(cp->cache, 2, i);
	cp->cache[i++].id = id;
	return -i;
}
示例#2
0
文件: less.c 项目: ack3000/busybox
static void fill_match_lines(unsigned pos)
{
	if (!pattern_valid)
		return;
	/* Run the regex on each line of the current file */
	while (pos <= max_fline) {
		/* If this line matches */
		if (regexec(&pattern, flines[pos], 0, NULL, 0) == 0
		/* and we didn't match it last time */
		 && !(num_matches && match_lines[num_matches-1] == pos)
		) {
			match_lines = xrealloc_vector(match_lines, 4, num_matches);
			match_lines[num_matches++] = pos;
		}
		pos++;
	}
}
示例#3
0
/* Add line and/or update count */
static void save_line(const char *string, int count)
{
	int i;
	for (i = 0; i < G.lines_cnt; i++) {
		if (strcmp(string, G.lines[i].string) == 0) {
			/* It's already there, only update count */
			G.lines[i].count += count;
			return;
		}
	}

	/* Add new line */
	G.lines = xrealloc_vector(G.lines, 4, G.lines_cnt);
	G.lines[G.lines_cnt].string = xstrdup(string);
	G.lines[G.lines_cnt].count = count;
	/*G.lines[G.lines_cnt].disk_count = 0;*/
	G.lines_cnt++;
}
示例#4
0
static void parse_conf_file(const char *filename)
{
	parser_t *parser;
	char *tokens[2];

	parser = config_open2(filename, fopen_for_read);

	if (parser) {
		while (config_read(parser, tokens, 2, 2, "# \t", PARSE_NORMAL)) {
			act_tab = xrealloc_vector(act_tab, 1, n_act);
			act_tab[n_act].key = xstrdup(tokens[0]);
			act_tab[n_act].action = xstrdup(tokens[1]);
			n_act++;
		}
		config_close(parser);
	} else {
		act_tab = (void*)f_act_tab;
		n_act = ARRAY_SIZE(f_act_tab);
	}
}
示例#5
0
文件: mtab.c 项目: dzo/busybox
void FAST_FUNC erase_mtab(const char *name)
{
	struct mntent *entries;
	int i, count;
	FILE *mountTable;
	struct mntent *m;

	mountTable = setmntent(bb_path_mtab_file, "r");
	/* Bummer. Fall back on trying the /proc filesystem */
	if (!mountTable) mountTable = setmntent("/proc/mounts", "r");
	if (!mountTable) {
		bb_perror_msg(bb_path_mtab_file);
		return;
	}

	entries = NULL;
	count = 0;
	while ((m = getmntent(mountTable)) != 0) {
		entries = xrealloc_vector(entries, 3, count);
		entries[count].mnt_fsname = xstrdup(m->mnt_fsname);
		entries[count].mnt_dir = xstrdup(m->mnt_dir);
		entries[count].mnt_type = xstrdup(m->mnt_type);
		entries[count].mnt_opts = xstrdup(m->mnt_opts);
		entries[count].mnt_freq = m->mnt_freq;
		entries[count].mnt_passno = m->mnt_passno;
		count++;
	}
	endmntent(mountTable);

//TODO: make update atomic
	mountTable = setmntent(bb_path_mtab_file, "w");
	if (mountTable) {
		for (i = 0; i < count; i++) {
			if (strcmp(entries[i].mnt_fsname, name) != 0
			 && strcmp(entries[i].mnt_dir, name) != 0)
				addmntent(mountTable, &entries[i]);
		}
		endmntent(mountTable);
	} else if (errno != EROFS)
		bb_perror_msg(bb_path_mtab_file);
}
/* This finds the pid of the specified process.
 * Currently, it's implemented by rummaging through
 * the proc filesystem.
 *
 * Returns a list of all matching PIDs
 * It is the caller's duty to free the returned pidlist.
 *
 * Modified by Vladimir Oleynik for use with libbb/procps.c
 */
pid_t* FAST_FUNC find_pid_by_name(const char *procName)
{
	pid_t* pidList;
	int i = 0;
	procps_status_t* p = NULL;

	pidList = xzalloc(sizeof(*pidList));
	while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN/*|PSSCAN_EXE*/))) {
		if (comm_match(p, procName)
		/* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/
		 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
		/* or we require /proc/PID/exe link to match */
/*		 || (p->exe && strcmp(bb_basename(p->exe), procName) == 0)*/
		) {
			pidList = xrealloc_vector(pidList, 2, i);
			pidList[i++] = p->pid;
		}
	}

	pidList[i] = 0;
	return pidList;
}
示例#7
0
/*
 * Register several long options. options is a string of long options,
 * separated by commas or whitespace.
 * This nukes options!
 */
static struct option *add_long_options(struct option *long_options, char *options)
{
    int long_nr = 0;
    int arg_opt, tlen;
    char *tokptr = strtok(options, ", \t\n");

    if (long_options)
        while (long_options[long_nr].name)
            long_nr++;

    while (tokptr) {
        arg_opt = no_argument;
        tlen = strlen(tokptr);
        if (tlen) {
            tlen--;
            if (tokptr[tlen] == ':') {
                arg_opt = required_argument;
                if (tlen && tokptr[tlen-1] == ':') {
                    tlen--;
                    arg_opt = optional_argument;
                }
                tokptr[tlen] = '\0';
                if (tlen == 0)
                    bb_error_msg_and_die("empty long option specified");
            }
            long_options = xrealloc_vector(long_options, 4, long_nr);
            long_options[long_nr].has_arg = arg_opt;
            /*long_options[long_nr].flag = NULL; - xrealloc_vector did it */
            long_options[long_nr].val = LONG_OPT;
            long_options[long_nr].name = xstrdup(tokptr);
            long_nr++;
            /*memset(&long_options[long_nr], 0, sizeof(long_options[0])); - xrealloc_vector did it */
        }
        tokptr = strtok(NULL, ", \t\n");
    }
    return long_options;
}
示例#8
0
static void parse_map_file(const char *filename)
{
	parser_t *parser;
	char *tokens[6];

	parser = config_open2(filename, fopen_for_read);

	if (parser) {
		while (config_read(parser, tokens, 6, 6, "# \t", PARSE_NORMAL)) {
			evt_tab = xrealloc_vector(evt_tab, 1, n_evt);
			evt_tab[n_evt].s_type = xstrdup(tokens[0]);
			evt_tab[n_evt].n_type = xstrtou(tokens[1], 16);
			evt_tab[n_evt].s_code = xstrdup(tokens[2]);
			evt_tab[n_evt].n_code = xatou16(tokens[3]);
			evt_tab[n_evt].value = xatoi_positive(tokens[4]);
			evt_tab[n_evt].desc = xstrdup(tokens[5]);
			n_evt++;
		}
		config_close(parser);
	} else {
		evt_tab = (void*)f_evt_tab;
		n_evt = ARRAY_SIZE(f_evt_tab);
	}
}
示例#9
0
文件: less.c 项目: ack3000/busybox
/* Devilishly complex routine.
 *
 * Has to deal with EOF and EPIPE on input,
 * with line wrapping, with last line not ending in '\n'
 * (possibly not ending YET!), with backspace and tabs.
 * It reads input again if last time we got an EOF (thus supporting
 * growing files) or EPIPE (watching output of slow process like make).
 *
 * Variables used:
 * flines[] - array of lines already read. Linewrap may cause
 *      one source file line to occupy several flines[n].
 * flines[max_fline] - last line, possibly incomplete.
 * terminated - 1 if flines[max_fline] is 'terminated'
 *      (if there was '\n' [which isn't stored itself, we just remember
 *      that it was seen])
 * max_lineno - last line's number, this one doesn't increment
 *      on line wrap, only on "real" new lines.
 * readbuf[0..readeof-1] - small preliminary buffer.
 * readbuf[readpos] - next character to add to current line.
 * last_line_pos - screen line position of next char to be read
 *      (takes into account tabs and backspaces)
 * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error
 */
static void read_lines(void)
{
#define readbuf bb_common_bufsiz1
	char *current_line, *p;
	int w = width;
	char last_terminated = terminated;
#if ENABLE_FEATURE_LESS_REGEXP
	unsigned old_max_fline = max_fline;
	time_t last_time = 0;
	unsigned seconds_p1 = 3; /* seconds_to_loop + 1 */
#endif

	if (option_mask32 & FLAG_N)
		w -= 8;

 IF_FEATURE_LESS_REGEXP(again0:)

	p = current_line = ((char*)xmalloc(w + 4)) + 4;
	max_fline += last_terminated;
	if (!last_terminated) {
		const char *cp = flines[max_fline];
		strcpy(p, cp);
		p += strlen(current_line);
		free(MEMPTR(flines[max_fline]));
		/* last_line_pos is still valid from previous read_lines() */
	} else {
		last_line_pos = 0;
	}

	while (1) { /* read lines until we reach cur_fline or wanted_match */
		*p = '\0';
		terminated = 0;
		while (1) { /* read chars until we have a line */
			char c;
			/* if no unprocessed chars left, eat more */
			if (readpos >= readeof) {
				ndelay_on(0);
				eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf));
				ndelay_off(0);
				readpos = 0;
				readeof = eof_error;
				if (eof_error <= 0)
					goto reached_eof;
			}
			c = readbuf[readpos];
			/* backspace? [needed for manpages] */
			/* <tab><bs> is (a) insane and */
			/* (b) harder to do correctly, so we refuse to do it */
			if (c == '\x8' && last_line_pos && p[-1] != '\t') {
				readpos++; /* eat it */
				last_line_pos--;
			/* was buggy (p could end up <= current_line)... */
				*--p = '\0';
				continue;
			}
			{
				size_t new_last_line_pos = last_line_pos + 1;
				if (c == '\t') {
					new_last_line_pos += 7;
					new_last_line_pos &= (~7);
				}
				if ((int)new_last_line_pos >= w)
					break;
				last_line_pos = new_last_line_pos;
			}
			/* ok, we will eat this char */
			readpos++;
			if (c == '\n') {
				terminated = 1;
				last_line_pos = 0;
				break;
			}
			/* NUL is substituted by '\n'! */
			if (c == '\0') c = '\n';
			*p++ = c;
			*p = '\0';
		} /* end of "read chars until we have a line" loop */
		/* Corner case: linewrap with only "" wrapping to next line */
		/* Looks ugly on screen, so we do not store this empty line */
		if (!last_terminated && !current_line[0]) {
			last_terminated = 1;
			max_lineno++;
			continue;
		}
 reached_eof:
		last_terminated = terminated;
		flines = xrealloc_vector(flines, 8, max_fline);

		flines[max_fline] = (char*)xrealloc(MEMPTR(current_line), strlen(current_line) + 1 + 4) + 4;
		LINENO(flines[max_fline]) = max_lineno;
		if (terminated)
			max_lineno++;

		if (max_fline >= MAXLINES) {
			eof_error = 0; /* Pretend we saw EOF */
			break;
		}
		if (!(option_mask32 & FLAG_S)
		  ? (max_fline > cur_fline + max_displayed_line)
		  : (max_fline >= cur_fline
		     && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line)
		) {
#if !ENABLE_FEATURE_LESS_REGEXP
			break;
#else
			if (wanted_match >= num_matches) { /* goto_match called us */
				fill_match_lines(old_max_fline);
				old_max_fline = max_fline;
			}
			if (wanted_match < num_matches)
				break;
#endif
		}
		if (eof_error <= 0) {
			if (eof_error < 0) {
				if (errno == EAGAIN) {
					/* not yet eof or error, reset flag (or else
					 * we will hog CPU - select() will return
					 * immediately */
					eof_error = 1;
				} else {
					print_statusline(bb_msg_read_error);
				}
			}
#if !ENABLE_FEATURE_LESS_REGEXP
			break;
#else
			if (wanted_match < num_matches) {
				break;
			} else { /* goto_match called us */
				time_t t = time(NULL);
				if (t != last_time) {
					last_time = t;
					if (--seconds_p1 == 0)
						break;
				}
				sched_yield();
				goto again0; /* go loop again (max 2 seconds) */
			}
#endif
		}
		max_fline++;
		current_line = ((char*)xmalloc(w + 4)) + 4;
		p = current_line;
		last_line_pos = 0;
	} /* end of "read lines until we reach cur_fline" loop */
	fill_match_lines(old_max_fline);
#if ENABLE_FEATURE_LESS_REGEXP
	/* prevent us from being stuck in search for a match */
	wanted_match = -1;
#endif
#undef readbuf
}
示例#10
0
文件: less.c 项目: ack3000/busybox
static void re_wrap(void)
{
	int w = width;
	int new_line_pos;
	int src_idx;
	int dst_idx;
	int new_cur_fline = 0;
	uint32_t lineno;
	char linebuf[w + 1];
	const char **old_flines = flines;
	const char *s;
	char **new_flines = NULL;
	char *d;

	if (option_mask32 & FLAG_N)
		w -= 8;

	src_idx = 0;
	dst_idx = 0;
	s = old_flines[0];
	lineno = LINENO(s);
	d = linebuf;
	new_line_pos = 0;
	while (1) {
		*d = *s;
		if (*d != '\0') {
			new_line_pos++;
			if (*d == '\t') /* tab */
				new_line_pos += 7;
			s++;
			d++;
			if (new_line_pos >= w) {
				int sz;
				/* new line is full, create next one */
				*d = '\0';
 next_new:
				sz = (d - linebuf) + 1; /* + 1: NUL */
				d = ((char*)xmalloc(sz + 4)) + 4;
				LINENO(d) = lineno;
				memcpy(d, linebuf, sz);
				new_flines = xrealloc_vector(new_flines, 8, dst_idx);
				new_flines[dst_idx] = d;
				dst_idx++;
				if (new_line_pos < w) {
					/* if we came here thru "goto next_new" */
					if (src_idx > max_fline)
						break;
					lineno = LINENO(s);
				}
				d = linebuf;
				new_line_pos = 0;
			}
			continue;
		}
		/* *d == NUL: old line ended, go to next old one */
		free(MEMPTR(old_flines[src_idx]));
		/* btw, convert cur_fline... */
		if (cur_fline == src_idx)
			new_cur_fline = dst_idx;
		src_idx++;
		/* no more lines? finish last new line (and exit the loop) */
		if (src_idx > max_fline)
			goto next_new;
		s = old_flines[src_idx];
		if (lineno != LINENO(s)) {
			/* this is not a continuation line!
			 * create next _new_ line too */
			goto next_new;
		}
	}

	free(old_flines);
	flines = (const char **)new_flines;

	max_fline = dst_idx - 1;
	last_line_pos = new_line_pos;
	cur_fline = new_cur_fline;
	/* max_lineno is screen-size independent */
#if ENABLE_FEATURE_LESS_REGEXP
	pattern_valid = 0;
#endif
}
示例#11
0
int sort_main(int argc UNUSED_PARAM, char **argv)
{
	FILE *fp, *outfile = stdout;
	char *line, **lines = NULL;
	char *str_ignored, *str_o, *str_t;
	llist_t *lst_k = NULL;
	int i, flag;
	int linecount = 0;

	xfunc_error_retval = 2;

	/* Parse command line options */
	/* -o and -t can be given at most once */
	opt_complementary = "o--o:t--t:" /* -t, -o: maximum one of each */
			"k::"; /* -k takes list */
	getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t);
#if ENABLE_FEATURE_SORT_BIG
	if (option_mask32 & FLAG_o) outfile = xfopen_for_write(str_o);
	if (option_mask32 & FLAG_t) {
		if (!str_t[0] || str_t[1])
			bb_error_msg_and_die("bad -t parameter");
		key_separator = str_t[0];
	}
	/* parse sort key */
	while (lst_k) {
		enum {
			FLAG_allowed_for_k =
				FLAG_n | /* Numeric sort */
				FLAG_g | /* Sort using strtod() */
				FLAG_M | /* Sort date */
				FLAG_b | /* Ignore leading blanks */
				FLAG_r | /* Reverse */
				FLAG_d | /* Ignore !(isalnum()|isspace()) */
				FLAG_f | /* Force uppercase */
				FLAG_i | /* Ignore !isprint() */
			0
		};
		struct sort_key *key = add_key();
		char *str_k = llist_pop(&lst_k);
		const char *temp2;

		i = 0; /* i==0 before comma, 1 after (-k3,6) */
		while (*str_k) {
			/* Start of range */
			/* Cannot use bb_strtou - suffix can be a letter */
			key->range[2*i] = str2u(&str_k);
			if (*str_k == '.') {
				str_k++;
				key->range[2*i+1] = str2u(&str_k);
			}
			while (*str_k) {
				if (*str_k == ',' && !i++) {
					str_k++;
					break;
				} /* no else needed: fall through to syntax error
					 because comma isn't in OPT_STR */
				temp2 = strchr(OPT_STR, *str_k);
				if (!temp2)
					bb_error_msg_and_die("unknown key option");
				flag = 1 << (temp2 - OPT_STR);
				if (flag & ~FLAG_allowed_for_k)
					bb_error_msg_and_die("unknown sort type");
				/* b after ',' means strip _trailing_ space */
				if (i && flag == FLAG_b) flag = FLAG_bb;
				key->flags |= flag;
				str_k++;
			}
		}
	}
#endif
	/* global b strips leading and trailing spaces */
	if (option_mask32 & FLAG_b) option_mask32 |= FLAG_bb;

	/* Open input files and read data */
	argv += optind;
	if (!*argv)
		*--argv = (char*)"-";
	do {
		/* coreutils 6.9 compat: abort on first open error,
		 * do not continue to next file: */
		fp = xfopen_stdin(*argv);
		for (;;) {
			line = GET_LINE(fp);
			if (!line) break;
			lines = xrealloc_vector(lines, 6, linecount);
			lines[linecount++] = line;
		}
		fclose_if_not_stdin(fp);
	} while (*++argv);

#if ENABLE_FEATURE_SORT_BIG
	/* if no key, perform alphabetic sort */
	if (!key_list)
		add_key()->range[0] = 1;
	/* handle -c */
	if (option_mask32 & FLAG_c) {
		int j = (option_mask32 & FLAG_u) ? -1 : 0;
		for (i = 1; i < linecount; i++)
			if (compare_keys(&lines[i-1], &lines[i]) > j) {
				fprintf(stderr, "Check line %d\n", i);
				return EXIT_FAILURE;
			}
		return EXIT_SUCCESS;
	}
#endif
	/* Perform the actual sort */
	qsort(lines, linecount, sizeof(char *), compare_keys);
	/* handle -u */
	if (option_mask32 & FLAG_u) {
		flag = 0;
		/* coreutils 6.3 drop lines for which only key is the same */
		/* -- disabling last-resort compare... */
		option_mask32 |= FLAG_s;
		for (i = 1; i < linecount; i++) {
			if (!compare_keys(&lines[flag], &lines[i]))
				free(lines[i]);
			else
				lines[++flag] = lines[i];
		}
		if (linecount) linecount = flag+1;
	}
	/* Print it */
	flag = (option_mask32 & FLAG_z) ? '\0' : '\n';
	for (i = 0; i < linecount; i++)
		fprintf(outfile, "%s%c", lines[i], flag);

	fflush_stdout_and_exit(EXIT_SUCCESS);
}
示例#12
0
文件: sed.c 项目: pgavin/or1k-busybox
static void add_input_file(FILE *file)
{
	G.input_file_list = xrealloc_vector(G.input_file_list, 2, G.input_file_count);
	G.input_file_list[G.input_file_count++] = file;
}
示例#13
0
#if ENABLE_FEATURE_TOPMEM
if (scan_mask != TOPMEM_MASK)
#endif
			{
				n = ntop;
				top = xrealloc_vector(top, 6, ntop++);
				top[n].pid = p->pid;
				top[n].ppid = p->ppid;
				top[n].vsz = p->vsz;
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
				top[n].ticks = p->stime + p->utime;
#endif
				top[n].uid = p->uid;
				strcpy(top[n].state, p->state);
				strcpy(top[n].comm, p->comm);
#if ENABLE_FEATURE_TOP_SMP_PROCESS
				top[n].last_seen_on_cpu = p->last_seen_on_cpu;
#endif
			}
#if ENABLE_FEATURE_TOPMEM
			else { /* TOPMEM */
				if (!(p->smaps.mapped_ro | p->smaps.mapped_rw))
					continue; /* kernel threads are ignored */
				n = ntop;
				/* No bug here - top and topmem are the same */
				top = xrealloc_vector(topmem, 6, ntop++);
				strcpy(topmem[n].comm, p->comm);
				topmem[n].pid      = p->pid;
				topmem[n].vsz      = p->smaps.mapped_rw + p->smaps.mapped_ro;
				topmem[n].vszrw    = p->smaps.mapped_rw;
				topmem[n].rss_sh   = p->smaps.shared_clean + p->smaps.shared_dirty;
示例#14
0
int cut_main(int argc UNUSED_PARAM, char **argv)
{
	/* growable array holding a series of lists */
	struct cut_list *cut_lists = NULL;
	unsigned nlists = 0;	/* number of elements in above list */
	char delim = '\t';	/* delimiter, default is tab */
	char *sopt, *ltok;
	unsigned opt;

	opt_complementary = "b--bcf:c--bcf:f--bcf";
	opt = getopt32(argv, optstring, &sopt, &sopt, &sopt, &ltok);
//	argc -= optind;
	argv += optind;
	if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
		bb_error_msg_and_die("expected a list of bytes, characters, or fields");

	if (opt & CUT_OPT_DELIM_FLGS) {
		if (ltok[0] && ltok[1]) { /* more than 1 char? */
			bb_error_msg_and_die("the delimiter must be a single character");
		}
		delim = ltok[0];
	}

	/*  non-field (char or byte) cutting has some special handling */
	if (!(opt & CUT_OPT_FIELDS_FLGS)) {
		static const char _op_on_field[] ALIGN1 = " only when operating on fields";

		if (opt & CUT_OPT_SUPPRESS_FLGS) {
			bb_error_msg_and_die
				("suppressing non-delimited lines makes sense%s",
				 _op_on_field);
		}
		if (delim != '\t') {
			bb_error_msg_and_die
				("a delimiter may be specified%s", _op_on_field);
		}
	}

	/*
	 * parse list and put values into startpos and endpos.
	 * valid list formats: N, N-, N-M, -M
	 * more than one list can be separated by commas
	 */
	{
		char *ntok;
		int s = 0, e = 0;

		/* take apart the lists, one by one (they are separated with commas) */
		while ((ltok = strsep(&sopt, ",")) != NULL) {

			/* it's actually legal to pass an empty list */
			if (!ltok[0])
				continue;

			/* get the start pos */
			ntok = strsep(&ltok, "-");
			if (!ntok[0]) {
				s = BOL;
			} else {
				s = xatoi_positive(ntok);
				/* account for the fact that arrays are zero based, while
				 * the user expects the first char on the line to be char #1 */
				if (s != 0)
					s--;
			}

			/* get the end pos */
			if (ltok == NULL) {
				e = NON_RANGE;
			} else if (!ltok[0]) {
				e = EOL;
			} else {
				e = xatoi_positive(ltok);
				/* if the user specified and end position of 0,
				 * that means "til the end of the line" */
				if (e == 0)
					e = EOL;
				e--;	/* again, arrays are zero based, lines are 1 based */
				if (e == s)
					e = NON_RANGE;
			}

			/* add the new list */
			cut_lists = xrealloc_vector(cut_lists, 4, nlists);
			/* NB: startpos is always >= 0,
			 * while endpos may be = NON_RANGE (-1) */
			cut_lists[nlists].startpos = s;
			cut_lists[nlists].endpos = e;
			nlists++;
		}

		/* make sure we got some cut positions out of all that */
		if (nlists == 0)
			bb_error_msg_and_die("missing list of positions");

		/* now that the lists are parsed, we need to sort them to make life
		 * easier on us when it comes time to print the chars / fields / lines
		 */
		qsort(cut_lists, nlists, sizeof(cut_lists[0]), cmpfunc);
	}

	{
		int retval = EXIT_SUCCESS;

		if (!*argv)
			*--argv = (char *)"-";

		do {
			FILE *file = fopen_or_warn_stdin(*argv);
			if (!file) {
				retval = EXIT_FAILURE;
				continue;
			}
			cut_file(file, delim, cut_lists, nlists);
			fclose_if_not_stdin(file);
		} while (*++argv);

		if (ENABLE_FEATURE_CLEAN_UP)
			free(cut_lists);
		fflush_stdout_and_exit(retval);
	}
}
示例#15
0
int acpid_main(int argc UNUSED_PARAM, char **argv)
{
	int nfd;
	int opts;
	struct pollfd *pfd;
	const char *opt_dir = "/etc/acpi";
	const char *opt_input = "/dev/input/event";
	const char *opt_logfile = "/var/log/acpid.log";
	const char *opt_action = "/etc/acpid.conf";
	const char *opt_map = "/etc/acpi.map";
#if ENABLE_FEATURE_PIDFILE
	const char *opt_pidfile = "/var/run/acpid.pid";
#endif

	INIT_G();

	opt_complementary = "df:e--e";
	opts = getopt32(argv, "c:de:fl:a:M:" IF_FEATURE_PIDFILE("p:") IF_FEATURE_ACPID_COMPAT("g:m:s:S:v"),
		&opt_dir, &opt_input, &opt_logfile, &opt_action, &opt_map
		IF_FEATURE_PIDFILE(, &opt_pidfile)
		IF_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL)
	);

	if (!(opts & OPT_f)) {
		/* No -f "Foreground", we go to background */
		bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv);
	}

	if (!(opts & OPT_d)) {
		/* No -d "Debug", we log to log file.
		 * This includes any output from children.
		 */
		xmove_fd(xopen(opt_logfile, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
		xdup2(STDOUT_FILENO, STDERR_FILENO);
		/* Also, acpid's messages (but not children) will go to syslog too */
		openlog(applet_name, LOG_PID, LOG_DAEMON);
		logmode = LOGMODE_SYSLOG | LOGMODE_STDIO;
	}
	/* else: -d "Debug", log is not redirected */

	parse_conf_file(opt_action);
	parse_map_file(opt_map);

	xchdir(opt_dir);

	bb_signals((1 << SIGCHLD), SIG_IGN);
	bb_signals(BB_FATAL_SIGS, record_signo);

	pfd = NULL;
	nfd = 0;
	while (1) {
		int fd;
		char *dev_event;

		dev_event = xasprintf((opts & OPT_e) ? "%s" : "%s%u", opt_input, nfd);
		fd = open(dev_event, O_RDONLY | O_NONBLOCK);
		if (fd < 0) {
			if (nfd == 0)
				bb_simple_perror_msg_and_die(dev_event);
			break;
		}
		free(dev_event);
		pfd = xrealloc_vector(pfd, 1, nfd);
		pfd[nfd].fd = fd;
		pfd[nfd].events = POLLIN;
		nfd++;
	}

	write_pidfile(opt_pidfile);

	while (safe_poll(pfd, nfd, -1) > 0) {
		int i;
		for (i = 0; i < nfd; i++) {
			const char *event;

			if (!(pfd[i].revents & POLLIN)) {
				if (pfd[i].revents == 0)
					continue; /* this fd has nothing */

				/* Likely POLLERR, POLLHUP, POLLNVAL.
				 * Do not listen on this fd anymore.
				 */
				close(pfd[i].fd);
				nfd--;
				for (; i < nfd; i++)
					pfd[i].fd = pfd[i + 1].fd;
				break; /* do poll() again */
			}

			event = NULL;
			if (option_mask32 & OPT_e) {
				char *buf;
				int len;

				buf = xmalloc_reads(pfd[i].fd, NULL);
				/* buf = "button/power PWRB 00000080 00000000" */
				len = strlen(buf) - 9;
				if (len >= 0)
					buf[len] = '\0';
				event = find_action(NULL, buf);
				free(buf);
			} else {
				struct input_event ev;

				if (sizeof(ev) != full_read(pfd[i].fd, &ev, sizeof(ev)))
					continue;

				if (ev.value != 1 && ev.value != 0)
					continue;

				event = find_action(&ev, NULL);
			}
			if (!event)
				continue;
			// spawn event handler
			process_event(event);
		}
	}

	if (ENABLE_FEATURE_CLEAN_UP) {
		while (nfd--)
			close(pfd[nfd].fd);
		free(pfd);
	}
	remove_pidfile(opt_pidfile);

	return EXIT_SUCCESS;
}
示例#16
0
int man_main(int argc UNUSED_PARAM, char **argv)
{
	parser_t *parser;
	const char *pager;
	char **man_path_list;
	char *sec_list;
	char *cur_path, *cur_sect;
	int count_mp, cur_mp;
	int opt, not_found;
	char *token[2];

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

	sec_list = xstrdup("1:2:3:4:5:6:7:8:9");
	/* Last valid man_path_list[] is [0x10] */
	count_mp = 0;
	man_path_list = xzalloc(0x11 * sizeof(man_path_list[0]));
	man_path_list[0] = getenv("MANPATH");
	if (!man_path_list[0]) /* default, may be overridden by /etc/man.conf */
		man_path_list[0] = (char*)"/usr/man";
	else
		count_mp++;
	pager = getenv("MANPAGER");
	if (!pager) {
		pager = getenv("PAGER");
		if (!pager)
			pager = "more";
	}

	/* Parse man.conf */
	parser = config_open2("/etc/man.conf", fopen_for_read);
	while (config_read(parser, token, 2, 0, "# \t", PARSE_NORMAL)) {
		if (!token[1])
			continue;
		if (strcmp("MANPATH", token[0]) == 0) {
			/* Do we already have it? */
			char **path_element = man_path_list;
			while (*path_element) {
				if (strcmp(*path_element, token[1]) == 0)
					goto skip;
				path_element++;
			}
			man_path_list = xrealloc_vector(man_path_list, 4, count_mp);
			man_path_list[count_mp] = xstrdup(token[1]);
			count_mp++;
			/* man_path_list is NULL terminated */
			/*man_path_list[count_mp] = NULL; - xrealloc_vector did it */
		}
		if (strcmp("MANSECT", token[0]) == 0) {
			free(sec_list);
			sec_list = xstrdup(token[1]);
		}
 skip: ;
	}
	config_close(parser);

	not_found = 0;
	do { /* for each argv[] */
		int found = 0;
		cur_mp = 0;

		if (strchr(*argv, '/')) {
			found = show_manpage(pager, *argv, /*man:*/ 1, 0);
			goto check_found;
		}
		while ((cur_path = man_path_list[cur_mp++]) != NULL) {
			/* for each MANPATH */
			do { /* for each MANPATH item */
				char *next_path = strchrnul(cur_path, ':');
				int path_len = next_path - cur_path;
				cur_sect = sec_list;
				do { /* for each section */
					char *next_sect = strchrnul(cur_sect, ':');
					int sect_len = next_sect - cur_sect;
					char *man_filename;
					int cat0man1 = 0;

					/* Search for cat, then man page */
					while (cat0man1 < 2) {
						int found_here;
						man_filename = xasprintf("%.*s/%s%.*s/%s.%.*s" Z_SUFFIX,
								path_len, cur_path,
								"cat\0man" + (cat0man1 * 4),
								sect_len, cur_sect,
								*argv,
								sect_len, cur_sect);
						found_here = show_manpage(pager, man_filename, cat0man1, 0);
						found |= found_here;
						cat0man1 += found_here + 1;
						free(man_filename);
					}

					if (found && !(opt & OPT_a))
						goto next_arg;
					cur_sect = next_sect;
					while (*cur_sect == ':')
						cur_sect++;
				} while (*cur_sect);
				cur_path = next_path;
				while (*cur_path == ':')
					cur_path++;
			} while (*cur_path);
		}
 check_found:
		if (!found) {
			bb_error_msg("no manual entry for '%s'", *argv);
			not_found = 1;
		}
 next_arg:
		argv++;
	} while (*argv);

	return not_found;
}
示例#17
0
static ps_out_t* new_out_t(void)
{
	out = xrealloc_vector(out, 2, out_cnt);
	return &out[out_cnt++];
}
示例#18
0
文件: sort.c 项目: chrisfair/busybox
int sort_main(int argc UNUSED_PARAM, char **argv)
{
	char *line, **lines;
	char *str_ignored, *str_o, *str_t;
	llist_t *lst_k = NULL;
	int i;
	int linecount;
	unsigned opts;

	xfunc_error_retval = 2;

	/* Parse command line options */
	/* -o and -t can be given at most once */
	opt_complementary = "o--o:t--t"; /* -t, -o: at most one of each */
	opts = getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t);
	/* global b strips leading and trailing spaces */
	if (opts & FLAG_b)
		option_mask32 |= FLAG_bb;
#if ENABLE_FEATURE_SORT_BIG
	if (opts & FLAG_t) {
		if (!str_t[0] || str_t[1])
			bb_error_msg_and_die("bad -t parameter");
		key_separator = str_t[0];
	}
	/* note: below this point we use option_mask32, not opts,
	 * since that reduces register pressure and makes code smaller */

	/* Parse sort key */
	while (lst_k) {
		enum {
			FLAG_allowed_for_k =
				FLAG_n | /* Numeric sort */
				FLAG_g | /* Sort using strtod() */
				FLAG_M | /* Sort date */
				FLAG_b | /* Ignore leading blanks */
				FLAG_r | /* Reverse */
				FLAG_d | /* Ignore !(isalnum()|isspace()) */
				FLAG_f | /* Force uppercase */
				FLAG_i | /* Ignore !isprint() */
			0
		};
		struct sort_key *key = add_key();
		char *str_k = llist_pop(&lst_k);

		i = 0; /* i==0 before comma, 1 after (-k3,6) */
		while (*str_k) {
			/* Start of range */
			/* Cannot use bb_strtou - suffix can be a letter */
			key->range[2*i] = str2u(&str_k);
			if (*str_k == '.') {
				str_k++;
				key->range[2*i+1] = str2u(&str_k);
			}
			while (*str_k) {
				int flag;
				const char *idx;

				if (*str_k == ',' && !i++) {
					str_k++;
					break;
				} /* no else needed: fall through to syntax error
					because comma isn't in OPT_STR */
				idx = strchr(OPT_STR, *str_k);
				if (!idx)
					bb_error_msg_and_die("unknown key option");
				flag = 1 << (idx - OPT_STR);
				if (flag & ~FLAG_allowed_for_k)
					bb_error_msg_and_die("unknown sort type");
				/* b after ',' means strip _trailing_ space */
				if (i && flag == FLAG_b)
					flag = FLAG_bb;
				key->flags |= flag;
				str_k++;
			}
		}
	}
#endif

	/* Open input files and read data */
	argv += optind;
	if (!*argv)
		*--argv = (char*)"-";
	linecount = 0;
	lines = NULL;
	do {
		/* coreutils 6.9 compat: abort on first open error,
		 * do not continue to next file: */
		FILE *fp = xfopen_stdin(*argv);
		for (;;) {
			line = GET_LINE(fp);
			if (!line)
				break;
			lines = xrealloc_vector(lines, 6, linecount);
			lines[linecount++] = line;
		}
		fclose_if_not_stdin(fp);
	} while (*++argv);

#if ENABLE_FEATURE_SORT_BIG
	/* If no key, perform alphabetic sort */
	if (!key_list)
		add_key()->range[0] = 1;
	/* Handle -c */
	if (option_mask32 & FLAG_c) {
		int j = (option_mask32 & FLAG_u) ? -1 : 0;
		for (i = 1; i < linecount; i++) {
			if (compare_keys(&lines[i-1], &lines[i]) > j) {
				fprintf(stderr, "Check line %u\n", i);
				return EXIT_FAILURE;
			}
		}
		return EXIT_SUCCESS;
	}
#endif
	/* Perform the actual sort */
	qsort(lines, linecount, sizeof(lines[0]), compare_keys);

	/* Handle -u */
	if (option_mask32 & FLAG_u) {
		int j = 0;
		/* coreutils 6.3 drop lines for which only key is the same */
		/* -- disabling last-resort compare... */
		option_mask32 |= FLAG_s;
		for (i = 1; i < linecount; i++) {
			if (compare_keys(&lines[j], &lines[i]) == 0)
				free(lines[i]);
			else
				lines[++j] = lines[i];
		}
		if (linecount)
			linecount = j+1;
	}

	/* Print it */
#if ENABLE_FEATURE_SORT_BIG
	/* Open output file _after_ we read all input ones */
	if (option_mask32 & FLAG_o)
		xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO);
#endif
	{
		int ch = (option_mask32 & FLAG_z) ? '\0' : '\n';
		for (i = 0; i < linecount; i++)
			printf("%s%c", lines[i], ch);
	}

	fflush_stdout_and_exit(EXIT_SUCCESS);
}