Пример #1
0
static void expand(FILE *file, unsigned tab_size, unsigned opt)
{
	char *line;
	char *ptr;
	int convert;
	int pos;

	/* Increment tab_size by 1 locally.*/
	tab_size++;

	while ((line = xmalloc_fgets(file)) != NULL) {
		convert = 1;
		pos = 0;
		ptr = line;
		while (*line) {
			pos++;
			if (*line == '\t' && convert) {
				for (; pos < tab_size; pos++) {
					xputchar(' ');
				}
			} else {
				if ((opt & OPT_INITIAL) && !isblank(*line)) {
					convert = 0;
				}
				xputchar(*line);
			}
			if (pos == tab_size) {
				pos = 0;
			}
			line++;
		}
		free(ptr);
	}
}
Пример #2
0
char *ask_password(const char *question)
{
    if (is_slave_mode())
        printf(REPORT_PREFIX_ASK_PASSWORD "%s\n", question);
    else
        printf("%s ", question);

    fflush(stdout);

    if (!is_slave_mode() && is_noninteractive_mode())
    {
        putchar('\n');
        fflush(stdout);
        return xstrdup("");
    }

    bool changed = set_echo(false);

    char *result = xmalloc_fgets(stdin);
    strtrimch(result, '\n');

    if (changed)
        set_echo(true);

    return result;
}
static void expand(FILE *file, unsigned tab_size, unsigned opt)
{
	char *line;

	while ((line = xmalloc_fgets(file)) != NULL) {
		unsigned char c;
		char *ptr;
		char *ptr_strbeg;

		ptr = ptr_strbeg = line;
		while ((c = *ptr) != '\0') {
			if ((opt & OPT_INITIAL) && !isblank(c)) {
				/* not space or tab */
				break;
			}
			if (c == '\t') {
				unsigned len;
				*ptr = '\0';
# if ENABLE_UNICODE_SUPPORT
				len = unicode_strwidth(ptr_strbeg);
# else
				len = ptr - ptr_strbeg;
# endif
				len = tab_size - (len % tab_size);
				/*while (ptr[1] == '\t') { ptr++; len += tab_size; } - can handle many tabs at once */
				printf("%s%*s", ptr_strbeg, len, "");
				ptr_strbeg = ptr + 1;
			}
			ptr++;
		}
		fputs(ptr_strbeg, stdout);
		free(line);
	}
}
Пример #4
0
static void expand(FILE *file, int tab_size, unsigned opt)
{
	char *line;

	tab_size = -tab_size;

	while ((line = xmalloc_fgets(file)) != NULL) {
		int pos;
		unsigned char c;
		char *ptr = line;

		goto start;
		while ((c = *ptr) != '\0') {
			if ((opt & OPT_INITIAL) && !isblank(c)) {
				fputs(ptr, stdout);
				break;
			}
			ptr++;
			if (c == '\t') {
				c = ' ';
				while (++pos < 0)
					bb_putchar(c);
			}
			bb_putchar(c);
			if (++pos >= 0) {
 start:
				pos = tab_size;
			}
		}
		free(line);
	}
}
Пример #5
0
static void unexpand(FILE *file, unsigned tab_size, unsigned opt)
{
	char *line;

	while ((line = xmalloc_fgets(file)) != NULL) {
		char *ptr = line;
		unsigned column = 0;

		while (*ptr) {
			unsigned n;
			unsigned len = 0;

			while (*ptr == ' ') {
				ptr++;
				len++;
			}
			column += len;
			if (*ptr == '\t') {
				column += tab_size - (column % tab_size);
				ptr++;
				continue;
			}

			n = column / tab_size;
			if (n) {
				len = column = column % tab_size;
				while (n--)
					putchar('\t');
			}

			if ((opt & OPT_INITIAL) && ptr != line) {
				printf("%*s%s", len, "", ptr);
				break;
			}
			n = strcspn(ptr, "\t ");
			printf("%*s%.*s", len, "", n, ptr);
# if ENABLE_UNICODE_SUPPORT
			{
				char c;
				uni_stat_t uni_stat;
				c = ptr[n];
				ptr[n] = '\0';
				printable_string(&uni_stat, ptr);
				len = uni_stat.unicode_width;
				ptr[n] = c;
			}
# else
			len = n;
# endif
			ptr += n;
			column = (column + len) % tab_size;
		}
		free(line);
	}
}
Пример #6
0
static void unexpand(FILE *file, unsigned int tab_size, unsigned opt)
{
	char *line;
	char *ptr;
	int convert;
	int pos;
	int i = 0;
	int column = 0;

	while ((line = xmalloc_fgets(file)) != NULL) {
		convert = 1;
		pos = 0;
		ptr = line;
		while (*line) {
			while ((*line == ' ' || *line == '\t') && convert) {
				pos += (*line == ' ') ? 1 : tab_size;
				line++;
				column++;
				if ((opt & OPT_ALL) && column == tab_size) {
					column = 0;
					goto put_tab;
				}
			}
			if (pos) {
				i = pos / tab_size;
				if (i) {
					for (; i > 0; i--) {
 put_tab:
						xputchar('\t');
					}
				} else {
					for (i = pos % tab_size; i > 0; i--) {
						xputchar(' ');
					}
				}
				pos = 0;
			} else {
				if (opt & OPT_INITIAL) {
					convert = 0;
				}
				if (opt & OPT_ALL) {
					column++;
				}
				xputchar(*line);
				line++;
			}
		}
		free(ptr);
	}
}
Пример #7
0
static void del_line_matching(const char *login, const char *filename)
{
	char *line;
	FILE *passwd;
	int len = strlen(login);
	int found = 0;
	llist_t *plist = NULL;

	passwd = fopen_or_warn(filename, "r");
	if (!passwd) return;

	while ((line = xmalloc_fgets(passwd))) {
		if (!strncmp(line, login, len)
		 && line[len] == ':'
		) {
			found++;
			free(line);
		} else {
			llist_add_to_end(&plist, line);
		}
	}

	if (!ENABLE_FEATURE_CLEAN_UP) {
		if (!found) {
			bb_error_msg("can't find '%s' in '%s'", login, filename);
			return;
		}
		passwd = fopen_or_warn(filename, "w");
		if (passwd)
			while ((line = llist_pop(&plist)))
				fputs(line, passwd);
	} else {
		if (!found) {
			bb_error_msg("can't find '%s' in '%s'", login, filename);
			goto clean_up;
		}
		fclose(passwd);
		passwd = fopen_or_warn(filename, "w");
		if (passwd) {
 clean_up:
			while ((line = llist_pop(&plist))) {
				if (found) fputs(line, passwd);
				free(line);
			}
			fclose(passwd);
		}
	}
}
Пример #8
0
static unsigned copy_lines(FILE *src_stream, FILE *dst_stream, unsigned lines_count)
{
	while (src_stream && lines_count) {
		char *line;
		line = xmalloc_fgets(src_stream);
		if (line == NULL) {
			break;
		}
		if (fputs(line, dst_stream) == EOF) {
			bb_perror_msg_and_die("error writing to new file");
		}
		free(line);
		lines_count--;
	}
	return lines_count;
}
Пример #9
0
int lsmod_main(int argc, char **argv)
{
	FILE *file = xfopen("/proc/modules", "r");

	printf("Module                  Size  Used by");
	check_tainted();
#if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT)
	{
		char *line;
		while ((line = xmalloc_fgets(file)) != NULL) {
			char *tok;

			tok = strtok(line, " \t");
			printf("%-19s", tok);
			tok = strtok(NULL, " \t\n");
			printf(" %8s", tok);
			tok = strtok(NULL, " \t\n");
			/* Null if no module unloading support. */
			if (tok) {
				printf("  %s", tok);
				tok = strtok(NULL, "\n");
				if (!tok)
					tok = (char*)"";
				/* New-style has commas, or -.  If so,
				truncate (other fields might follow). */
				else if (strchr(tok, ',')) {
					tok = strtok(tok, "\t ");
					/* Strip trailing comma. */
					if (tok[strlen(tok)-1] == ',')
						tok[strlen(tok)-1] = '\0';
				} else if (tok[0] == '-'
				 && (tok[1] == '\0' || isspace(tok[1]))
				) {
					tok = (char*)"";
				}
				printf(" %s", tok);
			}
			puts("");
			free(line);
		}
		fclose(file);
	}
#else
	xprint_and_close_file(file);
#endif  /*  CONFIG_FEATURE_2_6_MODULES  */
	return EXIT_SUCCESS;
}
Пример #10
0
static unsigned int copy_lines(FILE *src_stream, FILE *dest_stream, const unsigned int lines_count)
{
	unsigned int i = 0;

	while (src_stream && (i < lines_count)) {
		char *line;
		line = xmalloc_fgets(src_stream);
		if (line == NULL) {
			break;
		}
		if (fputs(line, dest_stream) == EOF) {
			bb_perror_msg_and_die("error writing to new file");
		}
		free(line);

		i++;
	}
	return i;
}
Пример #11
0
char *ask(const char *question)
{
    if (is_slave_mode())
        printf(REPORT_PREFIX_ASK "%s\n", question);
    else
        printf("%s ", question);

    fflush(stdout);

    if (!is_slave_mode() && is_noninteractive_mode())
    {
        putchar('\n');
        fflush(stdout);
        return xstrdup("");
    }

    char *result = xmalloc_fgets(stdin);
    strtrimch(result, '\n');

    return result;
}
Пример #12
0
static void unexpand(FILE *file, unsigned tab_size, unsigned opt)
{
	char *line;

	while ((line = xmalloc_fgets(file)) != NULL) {
		char *ptr = line;
		unsigned column = 0;

		while (*ptr) {
			unsigned n;

			while (*ptr == ' ') {
				column++;
				ptr++;
			}
			if (*ptr == '\t') {
				column += tab_size - (column % tab_size);
				ptr++;
				continue;
			}

			n = column / tab_size;
			column = column % tab_size;
			while (n--)
				putchar('\t');

			if ((opt & OPT_INITIAL) && ptr != line) {
				printf("%*s%s", column, "", ptr);
				break;
			}
			n = strcspn(ptr, "\t ");
			printf("%*s%.*s", column, "", n, ptr);
			ptr += n;
			column = (column + n) % tab_size;
		}
		free(line);
	}
}
Пример #13
0
static void do_info(const char *file, const char *name, void (*proc)(int, const char *))
{
	int lnr = 0;
	FILE *procinfo;

	procinfo = fopen(file, "r");
	if (procinfo == NULL) {
		if (errno != ENOENT) {
			bb_perror_msg("%s", file);
		} else {
			bb_error_msg("no support for '%s' on this system", name);
		}
		return;
	}
	do {
		char *buffer = xmalloc_fgets(procinfo);
		if (buffer) {
			(proc)(lnr++, buffer);
			free(buffer);
		}
	} while (!feof(procinfo));
	fclose(procinfo);
}
Пример #14
0
int nameif_main(int argc, char **argv)
{
	ethtable_t *clist = NULL;
	FILE *ifh;
	const char *fname = "/etc/mactab";
	char *line;
	char *line_ptr;
	int linenum;
	int ctl_sk;
	ethtable_t *ch;

	if (1 & getopt32(argv, "sc:", &fname)) {
		openlog(applet_name, 0, LOG_LOCAL0);
		logmode = LOGMODE_SYSLOG;
	}
	argc -= optind;
	argv += optind;

	if (argc & 1)
		bb_show_usage();

	if (argc) {
		while (*argv) {
			char *ifname = xstrdup(*argv++);
			prepend_new_eth_table(&clist, ifname, *argv++);
		}
	} else {
		ifh = xfopen(fname, "r");
		while ((line = xmalloc_fgets(ifh)) != NULL) {
			char *next;

			line_ptr = skip_whitespace(line);
			if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) {
				free(line);
				continue;
			}
			next = skip_non_whitespace(line_ptr);
			if (*next)
				*next++ = '\0';
			prepend_new_eth_table(&clist, line_ptr, next);
			free(line);
		}
		fclose(ifh);
	}

	ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0);
	ifh = xfopen("/proc/net/dev", "r");

	linenum = 0;
	while (clist) {
		struct ifreq ifr;
#if  ENABLE_FEATURE_NAMEIF_EXTENDED
		struct ethtool_drvinfo drvinfo;
#endif

		line = xmalloc_fgets(ifh);
		if (line == NULL)
			break; /* Seems like we're done */
		if (linenum++ < 2 )
			goto next_line; /* Skip the first two lines */

		/* Find the current interface name and copy it to ifr.ifr_name */
		line_ptr = skip_whitespace(line);
		*skip_non_whitespace(line_ptr) = '\0';

		memset(&ifr, 0, sizeof(struct ifreq));
		strncpy(ifr.ifr_name, line_ptr, sizeof(ifr.ifr_name));

#if ENABLE_FEATURE_NAMEIF_EXTENDED
		/* Check for driver etc. */
		memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
		drvinfo.cmd = ETHTOOL_GDRVINFO;
		ifr.ifr_data = (caddr_t) &drvinfo;
		/* Get driver and businfo first, so we have it in drvinfo */
		ioctl(ctl_sk, SIOCETHTOOL, &ifr);
#endif
		ioctl(ctl_sk, SIOCGIFHWADDR, &ifr);

		/* Search the list for a matching device */
		for (ch = clist; ch; ch = ch->next) {
#if ENABLE_FEATURE_NAMEIF_EXTENDED
			if (ch->bus_info && strcmp(ch->bus_info, drvinfo.bus_info) != 0)
				continue;
			if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0)
				continue;
#endif
			if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0)
				continue;
			/* if we came here, all selectors have matched */
			goto found;
		}
		/* Nothing found for current interface */
		goto next_line;
 found:
		if (strcmp(ifr.ifr_name, ch->ifname) != 0) {
			strcpy(ifr.ifr_newname, ch->ifname);
			ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr,
					"cannot change ifname %s to %s",
					ifr.ifr_name, ch->ifname);
		}
		/* Remove list entry of renamed interface */
		if (ch->prev != NULL)
			ch->prev->next = ch->next;
		else
			clist = ch->next;
		if (ch->next != NULL)
			ch->next->prev = ch->prev;
		if (ENABLE_FEATURE_CLEAN_UP) {
			free(ch->ifname);
			free(ch->mac);
			free(ch);
		}
 next_line:
		free(line);
	}
	if (ENABLE_FEATURE_CLEAN_UP) {
		fclose(ifh);
	};

	return 0;
}
Пример #15
0
int patch_main(int argc UNUSED_PARAM, char **argv)
{
	struct stat saved_stat;
	char *patch_line;
	FILE *patch_file;
	int patch_level;
	int ret = 0;
	char plus = '+';

	xfunc_error_retval = 2;
	{
		const char *p = "-1";
		const char *i = "-"; /* compat */
		if (getopt32(argv, "p:i:R", &p, &i) & 4)
			plus = '-';
		patch_level = xatoi(p); /* can be negative! */
		patch_file = xfopen_stdin(i);
	}

	patch_line = xmalloc_fgetline(patch_file);
	while (patch_line) {
		FILE *src_stream;
		FILE *dst_stream;
		//char *old_filename;
		char *new_filename;
		char *backup_filename;
		unsigned src_cur_line = 1;
		unsigned dst_cur_line = 0;
		unsigned dst_beg_line;
		unsigned bad_hunk_count = 0;
		unsigned hunk_count = 0;
		smallint copy_trailing_lines_flag = 0;

		/* Skip everything upto the "---" marker
		 * No need to parse the lines "Only in <dir>", and "diff <args>"
		 */
		do {
			/* Extract the filename used before the patch was generated */
			new_filename = extract_filename(patch_line, patch_level, "--- ");
			// was old_filename above
			patch_line = xmalloc_fgetline(patch_file);
			if (!patch_line) goto quit;
		} while (!new_filename);
		free(new_filename); // "source" filename is irrelevant

		new_filename = extract_filename(patch_line, patch_level, "+++ ");
		if (!new_filename) {
			bb_error_msg_and_die("invalid patch");
		}

		/* Get access rights from the file to be patched */
		if (stat(new_filename, &saved_stat) != 0) {
			char *slash = strrchr(new_filename, '/');
			if (slash) {
				/* Create leading directories */
				*slash = '\0';
				bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
				*slash = '/';
			}
			backup_filename = NULL;
			src_stream = NULL;
			saved_stat.st_mode = 0644;
		} else {
			backup_filename = xasprintf("%s.orig", new_filename);
			xrename(new_filename, backup_filename);
			src_stream = xfopen_for_read(backup_filename);
		}
		dst_stream = xfopen_for_write(new_filename);
		fchmod(fileno(dst_stream), saved_stat.st_mode);

		printf("patching file %s\n", new_filename);

		/* Handle all hunks for this file */
		patch_line = xmalloc_fgets(patch_file);
		while (patch_line) {
			unsigned count;
			unsigned src_beg_line;
			unsigned hunk_offset_start;
			unsigned src_last_line = 1;
			unsigned dst_last_line = 1;

			if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3)
			 && (sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dst_beg_line, &dst_last_line) < 2)
			) {
				/* No more hunks for this file */
				break;
			}
			if (plus != '+') {
				/* reverse patch */
				unsigned tmp = src_last_line;
				src_last_line = dst_last_line;
				dst_last_line = tmp;
				tmp = src_beg_line;
				src_beg_line = dst_beg_line;
				dst_beg_line = tmp;
			}
			hunk_count++;

			if (src_beg_line && dst_beg_line) {
				/* Copy unmodified lines upto start of hunk */
				/* src_beg_line will be 0 if it's a new file */
				count = src_beg_line - src_cur_line;
				if (copy_lines(src_stream, dst_stream, count)) {
					bb_error_msg_and_die("bad src file");
				}
				src_cur_line += count;
				dst_cur_line += count;
				copy_trailing_lines_flag = 1;
			}
			src_last_line += hunk_offset_start = src_cur_line;
			dst_last_line += dst_cur_line;

			while (1) {
				free(patch_line);
				patch_line = xmalloc_fgets(patch_file);
				if (patch_line == NULL)
					break; /* EOF */
				if ((*patch_line != '-') && (*patch_line != '+')
				 && (*patch_line != ' ')
				) {
					break; /* End of hunk */
				}
				if (*patch_line != plus) { /* '-' or ' ' */
					char *src_line = NULL;
					if (src_cur_line == src_last_line)
						break;
					if (src_stream) {
						src_line = xmalloc_fgets(src_stream);
						if (src_line) {
							int diff = strcmp(src_line, patch_line + 1);
							src_cur_line++;
							free(src_line);
							if (diff)
								src_line = NULL;
						}
					}
					if (!src_line) {
						bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start);
						bad_hunk_count++;
						break;
					}
					if (*patch_line != ' ') { /* '-' */
						continue;
					}
				}
				if (dst_cur_line == dst_last_line)
					break;
				fputs(patch_line + 1, dst_stream);
				dst_cur_line++;
			} /* end of while loop handling one hunk */
		} /* end of while loop handling one file */

		/* Cleanup last patched file */
		if (copy_trailing_lines_flag) {
			copy_lines(src_stream, dst_stream, (unsigned)(-1));
		}
		if (src_stream) {
			fclose(src_stream);
		}
		fclose(dst_stream);
		if (bad_hunk_count) {
			ret = 1;
			bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count);
		} else {
			/* It worked, we can remove the backup */
			if (backup_filename) {
				unlink(backup_filename);
			}
			if ((dst_cur_line == 0) || (dst_beg_line == 0)) {
				/* The new patched file is empty, remove it */
				xunlink(new_filename);
				// /* old_filename and new_filename may be the same file */
				// unlink(old_filename);
			}
		}
		free(backup_filename);
		//free(old_filename);
		free(new_filename);
	} /* end of "while there are patch lines" */
 quit:
	/* 0 = SUCCESS
	 * 1 = Some hunks failed
	 * 2 = More serious problems (exited earlier)
	 */
	return ret;
}
Пример #16
0
int patch_main(int argc UNUSED_PARAM, char **argv)
{
	struct stat saved_stat;
	char *patch_line;
	FILE *patch_file;
	int patch_level;
	int ret = 0;
	char plus = '+';
	unsigned opt;
	enum {
		OPT_R = (1 << 2),
		OPT_N = (1 << 3),
		/*OPT_f = (1 << 4), ignored */
		/*OPT_E = (1 << 5), ignored, this is the default */
		/*OPT_g = (1 << 6), ignored */
		OPT_dry_run = (1 << 7) * ENABLE_LONG_OPTS,
	};

	xfunc_error_retval = 2;
	{
		const char *p = "-1";
		const char *i = "-"; /* compat */
#if ENABLE_LONG_OPTS
		static const char patch_longopts[] ALIGN1 =
			"strip\0"                 Required_argument "p"
			"input\0"                 Required_argument "i"
			"reverse\0"               No_argument       "R"
			"forward\0"               No_argument       "N"
		/* "Assume user knows what [s]he is doing, do not ask any questions": */
			"force\0"                 No_argument       "f" /*ignored*/
# if ENABLE_DESKTOP
			"remove-empty-files\0"    No_argument       "E" /*ignored*/
		/* "Controls actions when a file is under RCS or SCCS control,
		 * and does not exist or is read-only and matches the default version,
		 * or when a file is under ClearCase control and does not exist..."
		 * IOW: rather obscure option.
		 * But Gentoo's portage does use -g0 */
			"get\0"                   Required_argument "g" /*ignored*/
# endif
			"dry-run\0"               No_argument       "\xfd"
# if ENABLE_DESKTOP
			"backup-if-mismatch\0"    No_argument       "\xfe" /*ignored*/
			"no-backup-if-mismatch\0" No_argument       "\xff" /*ignored*/
# endif
			;
		applet_long_options = patch_longopts;
#endif
		/* -f,-E,-g are ignored */
		opt = getopt32(argv, "p:i:RN""fEg:", &p, &i, NULL);
		if (opt & OPT_R)
			plus = '-';
		patch_level = xatoi(p); /* can be negative! */
		patch_file = xfopen_stdin(i);
	}

	patch_line = xmalloc_fgetline(patch_file);
	while (patch_line) {
		FILE *src_stream;
		FILE *dst_stream;
		//char *old_filename;
		char *new_filename;
		char *backup_filename = NULL;
		unsigned src_cur_line = 1;
		unsigned dst_cur_line = 0;
		unsigned dst_beg_line;
		unsigned bad_hunk_count = 0;
		unsigned hunk_count = 0;
		smallint copy_trailing_lines_flag = 0;

		/* Skip everything upto the "---" marker
		 * No need to parse the lines "Only in <dir>", and "diff <args>"
		 */
		do {
			/* Extract the filename ugsed before the patch was generated */
			new_filename = extract_filename(patch_line, patch_level, "--- ");
			// was old_filename above
			patch_line = xmalloc_fgetline(patch_file);
			if (!patch_line) goto quit;
		} while (!new_filename);
		free(new_filename); // "source" filename is irrelevant

		new_filename = extract_filename(patch_line, patch_level, "+++ ");
		if (!new_filename) {
			bb_error_msg_and_die("invalid patch");
		}

		/* Get access rights from the file to be patched */
		if (stat(new_filename, &saved_stat) != 0) {
			char *slash = strrchr(new_filename, '/');
			if (slash) {
				/* Create leading directories */
				*slash = '\0';
				bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
				*slash = '/';
			}
			src_stream = NULL;
			saved_stat.st_mode = 0644;
		} else if (!(opt & OPT_dry_run)) {
			backup_filename = xasprintf("%s.orig", new_filename);
			xrename(new_filename, backup_filename);
			src_stream = xfopen_for_read(backup_filename);
		} else
			src_stream = xfopen_for_read(new_filename);

		if (opt & OPT_dry_run) {
			dst_stream = xfopen_for_write("/dev/null");
		} else {
			dst_stream = xfopen_for_write(new_filename);
			fchmod(fileno(dst_stream), saved_stat.st_mode);
		}

		printf("patching file %s\n", new_filename);

		/* Handle all hunks for this file */
		patch_line = xmalloc_fgets(patch_file);
		while (patch_line) {
			unsigned count;
			unsigned src_beg_line;
			unsigned hunk_offset_start;
			unsigned src_last_line = 1;
			unsigned dst_last_line = 1;

			if ((sscanf(patch_line, "@@ -%u,%u +%u,%u", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3)
			 && (sscanf(patch_line, "@@ -%u +%u,%u", &src_beg_line, &dst_beg_line, &dst_last_line) < 2)
			) {
				/* No more hunks for this file */
				break;
			}
			if (plus != '+') {
				/* reverse patch */
				unsigned tmp = src_last_line;
				src_last_line = dst_last_line;
				dst_last_line = tmp;
				tmp = src_beg_line;
				src_beg_line = dst_beg_line;
				dst_beg_line = tmp;
			}
			hunk_count++;

			if (src_beg_line && dst_beg_line) {
				/* Copy unmodified lines upto start of hunk */
				/* src_beg_line will be 0 if it's a new file */
				count = src_beg_line - src_cur_line;
				if (copy_lines(src_stream, dst_stream, count)) {
					bb_error_msg_and_die("bad src file");
				}
				src_cur_line += count;
				dst_cur_line += count;
				copy_trailing_lines_flag = 1;
			}
			src_last_line += hunk_offset_start = src_cur_line;
			dst_last_line += dst_cur_line;

			while (1) {
				free(patch_line);
				patch_line = xmalloc_fgets(patch_file);
				if (patch_line == NULL)
					break; /* EOF */
				if (!*patch_line) {
					/* whitespace-damaged patch with "" lines */
					free(patch_line);
					patch_line = xstrdup(" ");
				}
				if ((*patch_line != '-') && (*patch_line != '+')
				 && (*patch_line != ' ')
				) {
					break; /* End of hunk */
				}
				if (*patch_line != plus) { /* '-' or ' ' */
					char *src_line = NULL;
					if (src_cur_line == src_last_line)
						break;
					if (src_stream) {
						src_line = xmalloc_fgets(src_stream);
						if (src_line) {
							int diff = strcmp(src_line, patch_line + 1);
							src_cur_line++;
							free(src_line);
							if (diff)
								src_line = NULL;
						}
					}
					/* Do not patch an already patched hunk with -N */
					if (src_line == 0 && (opt & OPT_N)) {
						continue;
					}
					if (!src_line) {
						bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start);
						bad_hunk_count++;
						break;
					}
					if (*patch_line != ' ') { /* '-' */
						continue;
					}
				}
				if (dst_cur_line == dst_last_line)
					break;
				fputs(patch_line + 1, dst_stream);
				dst_cur_line++;
			} /* end of while loop handling one hunk */
		} /* end of while loop handling one file */

		/* Cleanup last patched file */
		if (copy_trailing_lines_flag) {
			copy_lines(src_stream, dst_stream, (unsigned)(-1));
		}
		if (src_stream) {
			fclose(src_stream);
		}
		fclose(dst_stream);
		if (bad_hunk_count) {
			ret = 1;
			bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count);
		} else {
			/* It worked, we can remove the backup */
			if (backup_filename) {
				unlink(backup_filename);
			}
			if (!(opt & OPT_dry_run)
			 && ((dst_cur_line == 0) || (dst_beg_line == 0))
			) {
				/* The new patched file is empty, remove it */
				xunlink(new_filename);
				// /* old_filename and new_filename may be the same file */
				// unlink(old_filename);
			}
		}
		free(backup_filename);
		//free(old_filename);
		free(new_filename);
	} /* end of "while there are patch lines" */
 quit:
	/* 0 = SUCCESS
	 * 1 = Some hunks failed
	 * 2 = More serious problems (exited earlier)
	 */
	return ret;
}
Пример #17
0
int nameif_main(int argc, char **argv)
{
	mactable_t *clist = NULL;
	FILE *ifh;
	const char *fname = "/etc/mactab";
	char *line;
	int ctl_sk;
	int if_index = 1;
	mactable_t *ch;

	if (1 & getopt32(argc, argv, "sc:", &fname)) {
		openlog(applet_name, 0, LOG_LOCAL0);
		logmode = LOGMODE_SYSLOG;
	}

	if ((argc - optind) & 1)
		bb_show_usage();

	if (optind < argc) {
		char **a = argv + optind;

		while (*a) {
			if (strlen(*a) > IF_NAMESIZE)
				bb_error_msg_and_die("interface name '%s' "
					    "too long", *a);
			ch = xzalloc(sizeof(mactable_t));
			ch->ifname = xstrdup(*a++);
			ch->mac = cc_macaddr(*a++);
			if (clist)
				clist->prev = ch;
			ch->next = clist;
			clist = ch;
		}
	} else {
		ifh = xfopen(fname, "r");

		while ((line = xmalloc_fgets(ifh)) != NULL) {
			char *line_ptr;
			size_t name_length;

			line_ptr = line + strspn(line, " \t");
			if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) {
				free(line);
				continue;
			}
			name_length = strcspn(line_ptr, " \t");
			ch = xzalloc(sizeof(mactable_t));
			ch->ifname = xstrndup(line_ptr, name_length);
			if (name_length > IF_NAMESIZE)
				bb_error_msg_and_die("interface name '%s' "
						"too long", ch->ifname);
			line_ptr += name_length;
			line_ptr += strspn(line_ptr, " \t");
			name_length = strspn(line_ptr, "0123456789ABCDEFabcdef:");
			line_ptr[name_length] = '\0';
			ch->mac = cc_macaddr(line_ptr);
			if (clist)
				clist->prev = ch;
			ch->next = clist;
			clist = ch;
			free(line);
		}
		fclose(ifh);
	}

	ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0);

	while (clist) {
		struct ifreq ifr;

		memset(&ifr, 0, sizeof(struct ifreq));
		if_index++;
		ifr.ifr_ifindex = if_index;

		/* Get ifname by index or die */
		if (ioctl(ctl_sk, SIOCGIFNAME, &ifr))
			break;

		/* Has this device hwaddr? */
		if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr))
			continue;

		/* Search for mac like in ifr.ifr_hwaddr.sa_data */
		for (ch = clist; ch; ch = ch->next)
			if (!memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN))
				break;

		/* Nothing found for current ifr.ifr_hwaddr.sa_data */
		if (ch == NULL)
			continue;

		strcpy(ifr.ifr_newname, ch->ifname);
		if (ioctl(ctl_sk, SIOCSIFNAME, &ifr) < 0)
			bb_perror_msg_and_die("cannot change ifname %s to %s",
				   ifr.ifr_name, ch->ifname);

		/* Remove list entry of renamed interface */
		if (ch->prev != NULL) {
			(ch->prev)->next = ch->next;
		} else {
			clist = ch->next;
		}
		if (ch->next != NULL)
			(ch->next)->prev = ch->prev;
		if (ENABLE_FEATURE_CLEAN_UP) {
			free(ch->ifname);
			free(ch->mac);
			free(ch);
		}
	}

	return 0;
}
Пример #18
0
int patch_main(int argc, char **argv)
{
	int patch_level = -1;
	char *patch_line;
	int ret;
	FILE *patch_file = NULL;

	{
		char *p, *i;
		ret = getopt32(argv, "p:i:", &p, &i);
		if (ret & 1)
			patch_level = xatol_range(p, -1, USHRT_MAX);
		if (ret & 2) {
			patch_file = xfopen(i, "r");
		} else {
			patch_file = stdin;
		}
		ret = 0;
	}

	patch_line = xmalloc_getline(patch_file);
	while (patch_line) {
		FILE *src_stream;
		FILE *dst_stream;
		char *original_filename;
		char *new_filename;
		char *backup_filename;
		unsigned int src_cur_line = 1;
		unsigned int dest_cur_line = 0;
		unsigned int dest_beg_line;
		unsigned int bad_hunk_count = 0;
		unsigned int hunk_count = 0;
		char copy_trailing_lines_flag = 0;

		/* Skip everything upto the "---" marker
		 * No need to parse the lines "Only in <dir>", and "diff <args>"
		 */
		while (patch_line && strncmp(patch_line, "--- ", 4) != 0) {
			free(patch_line);
			patch_line = xmalloc_getline(patch_file);
		}
		/* FIXME: patch_line NULL check?? */

		/* Extract the filename used before the patch was generated */
		original_filename = extract_filename(patch_line, patch_level);
		free(patch_line);

		patch_line = xmalloc_getline(patch_file);
		/* FIXME: NULL check?? */
		if (strncmp(patch_line, "+++ ", 4) != 0) {
			ret = 2;
			bb_error_msg("invalid patch");
			continue;
		}
		new_filename = extract_filename(patch_line, patch_level);
		free(patch_line);

		if (file_doesnt_exist(new_filename)) {
			char *line_ptr;
			/* Create leading directories */
			line_ptr = strrchr(new_filename, '/');
			if (line_ptr) {
				*line_ptr = '\0';
				bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
				*line_ptr = '/';
			}
			dst_stream = xfopen(new_filename, "w+");
			backup_filename = NULL;
		} else {
			backup_filename = xmalloc(strlen(new_filename) + 6);
			strcpy(backup_filename, new_filename);
			strcat(backup_filename, ".orig");
			if (rename(new_filename, backup_filename) == -1) {
				bb_perror_msg_and_die("cannot create file %s",
						backup_filename);
			}
			dst_stream = xfopen(new_filename, "w");
		}

		if ((backup_filename == NULL) || file_doesnt_exist(original_filename)) {
			src_stream = NULL;
		} else {
			if (strcmp(original_filename, new_filename) == 0) {
				src_stream = xfopen(backup_filename, "r");
			} else {
				src_stream = xfopen(original_filename, "r");
			}
		}

		printf("patching file %s\n", new_filename);

		/* Handle each hunk */
		patch_line = xmalloc_fgets(patch_file);
		while (patch_line) {
			unsigned int count;
			unsigned int src_beg_line;
			unsigned int unused;
			unsigned int hunk_offset_start = 0;
			int hunk_error = 0;

			/* This bit should be improved */
			if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line, &unused, &dest_beg_line, &unused) != 4) &&
				(sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line, &unused, &dest_beg_line) != 3) &&
				(sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line, &dest_beg_line, &unused) != 3)) {
				/* No more hunks for this file */
				break;
			}
			free(patch_line);
			hunk_count++;

			if (src_beg_line && dest_beg_line) {
				/* Copy unmodified lines upto start of hunk */
				/* src_beg_line will be 0 if its a new file */
				count = src_beg_line - src_cur_line;
				if (copy_lines(src_stream, dst_stream, count) != count) {
					bb_error_msg_and_die("bad src file");
				}
				src_cur_line += count;
				dest_cur_line += count;
				copy_trailing_lines_flag = 1;
			}
			hunk_offset_start = src_cur_line;

			while ((patch_line = xmalloc_fgets(patch_file)) != NULL) {
				if ((*patch_line == '-') || (*patch_line == ' ')) {
					char *src_line = NULL;
					if (src_stream) {
						src_line = xmalloc_fgets(src_stream);
						if (!src_line) {
							hunk_error++;
							break;
						} else {
							src_cur_line++;
						}
						if (strcmp(src_line, patch_line + 1) != 0) {
							bb_error_msg("hunk #%d FAILED at %d", hunk_count, hunk_offset_start);
							hunk_error++;
							free(patch_line);
							/* Probably need to find next hunk, etc... */
							/* but for now we just bail out */
							patch_line = NULL;
							break;
						}
						free(src_line);
					}
					if (*patch_line == ' ') {
						fputs(patch_line + 1, dst_stream);
						dest_cur_line++;
					}
				} else if (*patch_line == '+') {
					fputs(patch_line + 1, dst_stream);
					dest_cur_line++;
				} else {
					break;
				}
				free(patch_line);
			}
			if (hunk_error) {
				bad_hunk_count++;
			}
		}

		/* Cleanup last patched file */
		if (copy_trailing_lines_flag) {
			copy_lines(src_stream, dst_stream, -1);
		}
		if (src_stream) {
			fclose(src_stream);
		}
		if (dst_stream) {
			fclose(dst_stream);
		}
		if (bad_hunk_count) {
			if (!ret) {
				ret = 1;
			}
			bb_error_msg("%d out of %d hunk FAILED", bad_hunk_count, hunk_count);
		} else {
			/* It worked, we can remove the backup */
			if (backup_filename) {
				unlink(backup_filename);
			}
			if ((dest_cur_line == 0) || (dest_beg_line == 0)) {
				/* The new patched file is empty, remove it */
				xunlink(new_filename);
				if (strcmp(new_filename, original_filename) != 0)
					xunlink(original_filename);
			}
		}
	}

	/* 0 = SUCCESS
	 * 1 = Some hunks failed
	 * 2 = More serious problems
	 */
	return ret;
}