Beispiel #1
0
void
check_gnu(char *addr, size_t fsize)
{
	int	i;
	char	c, mc;
	char	*linebuf;
	char	*mbuf, *p, *buf;
	unsigned int	n;
	size_t	ln_size;
	size_t	bufsize, index;
	size_t	size = fsize;
	int	quotefound = 0;
	const char	*field;

	buf = NULL;
	linebuf = NULL;
	mbuf = addr;

loop:
	ln_size = get_one_line(&linebuf, &mbuf, &size);
	if ((ln_size == (size_t)-1) ||
		(ln_size == 0)) {
		goto no_gnu;
	}
	p = linebuf;

	while ((*p == '#') || (*p == '\n')) {
		ln_size = get_one_line(&linebuf, &mbuf, &size);
		if ((ln_size == (size_t)-1) ||
			(ln_size == 0)) {
			goto no_gnu;
		}
		p = linebuf;
	}

	if (strncmp(p, "domain", 6) == 0)
		goto loop;

	if (strncmp(p, "msgid", 5) != 0) {
		/* error */
		goto no_gnu;
	}

	p += 5;
	if ((*p != ' ') && (*p != '\t') &&
		(*p != '\n') && (*p != '\0')) {
		/* no space after msgid */
		goto no_gnu;
	}
	/* skip spaces */
	while ((*p == ' ') || (*p == '\t'))
		p++;

	/* check if this entry is an empty string */
	if ((*p != '\"') || (*(p + 1) != '\"')) {
		/* this is not an empty string */
		goto no_gnu;
	}
	p += 2;
	while (*p && ((*p == ' ') || (*p == '\t'))) {
		p++;
	}
	if ((*p != '\n') && (*p != '\0')) {
		/* other characters than '\n' and '\0' found */
		goto no_gnu;
	}

	for (; ; ) {
		ln_size = get_one_line(&linebuf, &mbuf, &size);
		if ((ln_size == (size_t)-1) ||
			(ln_size == 0)) {
			goto no_gnu;
		}
		p = linebuf;
		/* skip leading spaces */
		while ((*p == ' ') || (*p == '\t'))
			p++;

		if (*p != '\"') {
			if (strncmp(p, "msgstr", 6) == 0) {
				break;
			}
			/* not a valid entry */
			goto no_gnu;
		}
		if (*(p + 1) != '\"') {
			/* not an empty string */
			goto no_gnu;
		}
		p += 2;
		while ((*p == ' ') || (*p == '\t'))
			p++;

		if ((*p != '\n') && (*p != '\0')) {
			/* other characters than '\n' and '\0' found */
			goto no_gnu;
		}
	}

	/*
	 * msgid for the header entry found
	 * Now p points to "msgstr"
	 */
	p += 6;
	if ((*p != ' ') && (*p != '\t') &&
		(*p != '\n') && (*p != '\0')) {
		/* no space after msgid */
		goto no_gnu;
	}

	/* skip spaces */
	while ((*p == ' ') || (*p == '\t'))
		p++;

	if (*p != '\"') {
		/* no quote */
		goto no_gnu;
	}

	bufsize = ln_size + 1;
	index = 0;
	buf = (char *)Xmalloc(bufsize);

	for (; ; ) {
		if (*p != '\"') {
			/* msgstr entry ends */
			buf[index] = '\0';
			break;
		}

		if (*p++ != '\"') {
			/* no beginning quote */
			goto no_gnu;
		}
		while (*p) {
			switch (mc = *p++) {
			case '\n':
				if (!quotefound) {
					/* error */
					goto no_gnu;
				}
				break;
			case '\"':
				quotefound = 1;
				break;
			case '\\':
				if (!*p)
					break;
				switch (c = *p++) {
				case 'b':
					buf[index++] = '\b';
					break;
				case 'f':
					buf[index++] = '\f';
					break;
				case 'n':
					buf[index++] = '\n';
					break;
				case 'r':
					buf[index++] = '\r';
					break;
				case 't':
					buf[index++] = '\t';
					break;
				case 'v':
					buf[index++] = '\v';
					break;
				case 'a':
					buf[index++] = '\a';
					break;
				case '\"':
				case '\\':
				case '\'':
				case '?':
					buf[index++] = c;
					break;
				default:
					if (isdigit((unsigned char)c)) {
						unsigned int	x;
						unsigned char	*up =
							(unsigned char *)p;
						n = c - '0';
						if (isdigit(*up)) {
							x = *up++ - '0';
							n = 8 * n + x;
							if (isdigit(*up)) {
								x = *up++ - '0';
								n = 8 * n + x;
							}
						}
						p = (char *)up;
						buf[index++] = n;
					}
					break;
				}
				break;
			default:
				buf[index++] = mc;
				break;
			}
			if (quotefound) {
				while (*p && ((*p == ' ') || (*p == '\t'))) {
					p++;
				}
				if ((*p != '\n') && (*p != '\0')) {
					goto no_gnu;
				}
				quotefound = 0;
				break;
			}
		}
		ln_size = get_one_line(&linebuf, &mbuf, &size);
		if ((ln_size == (size_t)-1) ||
			(ln_size == 0)) {
			goto no_gnu;
		}
		p = linebuf;
		/* skip spaces */
		while ((*p == ' ') || (*p == '\t'))
			p++;
		bufsize += ln_size;
		buf = (char *)Xrealloc(buf, bufsize);
	}

	for (i = 0; (field = mandatory_fields[i]) != NULL; i++) {
		if (strstr(buf, field) == NULL)
			continue;
		/* one of mandatory fields found */
		free(linebuf);
		free(buf);
		(void) munmap(addr, fsize);
		if (verbose)
			diag(gettext(DIAG_GNU_FOUND));
		invoke_gnu_msgfmt();
		/* NOTREACHED */
	}
	for (i = 0; (field = mandatory_fields_new[i]) != NULL; i++) {
		if (strstr(buf, field) == NULL)
			continue;
		/* one of mandatory fields found */
		free(linebuf);
		free(buf);
		(void) munmap(addr, fsize);
		if (verbose)
			diag(gettext(DIAG_GNU_FOUND));
		invoke_gnu_msgfmt();
		/* NOTREACHED */
	}

no_gnu:
	free(linebuf);
	if (buf)
		free(buf);
}
Beispiel #2
0
int
main(int argc, char **argv)
{
	int	ret;
	static struct flags	flag;

	(void) setlocale(LC_ALL, "");
#if	!defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN	"SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	oargv = argv;
	ret = parse_option(&argc, &argv, &flag);
	if (ret == -1) {
		usage();
		/* NOTREACHED */
	}

	if (flag.sun_p) {
		/* never invoke gnu msgfmt */
		if (flag.gnu_p) {
			error(gettext(ERR_GNU_ON_SUN));
			/* NOTREACHED */
		}
		sun_p = flag.sun_p;
	}
	if (flag.idir) {
		inputdir = flag.idir;
	}
	if (flag.ofile) {
		oflag = 1;
		outfile = flag.ofile;
	}
	if (flag.verbose) {
		verbose = 1;
	}
	if (flag.version) {
		printf("illumos msgfmt version 5.11 (GNU compatible)\n");
		return (0);
	}

	if (flag.gnu_p) {
		/* invoke /usr/lib/gmsgfmt */
		invoke_gnu_msgfmt();
		/* NOTREACHED */
	}

	if (argc == 0) {
		usage();
		/* NOTREACHED */
	}

	/*
	 * read all portable object files specified in command arguments.
	 * Allocate initial size for msgid and msgstr. If it needs more
	 * spaces, realloc later.
	 */
	gmsgid = (char *)Xmalloc(MAX_VALUE_LEN);
	gmsgstr = (char *)Xmalloc(MAX_VALUE_LEN);

	gmsgid_size = gmsgstr_size = MAX_VALUE_LEN;
	(void) memset(gmsgid, 0, gmsgid_size);
	(void) memset(gmsgstr, 0, gmsgstr_size);

	mbcurmax = MB_CUR_MAX;

	while (argc-- > 0) {
		if (verbose) {
			diag(gettext(DIAG_START_PROC), *argv);
		}
		read_psffm(*argv++);
	}

	output_all_mo_files();

#ifdef DEBUG
	printlist();
#endif

	return (0);

} /* main */