From owner-p4-projects@FreeBSD.ORG Thu May 27 08:59:33 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DE0901065673; Thu, 27 May 2010 08:59:32 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A224C106564A for ; Thu, 27 May 2010 08:59:32 +0000 (UTC) (envelope-from gcooper@FreeBSD.org) Received: from repoman.freebsd.org (unknown [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 8F1CA8FC1B for ; Thu, 27 May 2010 08:59:32 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o4R8xWBu016610 for ; Thu, 27 May 2010 08:59:32 GMT (envelope-from gcooper@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o4R8xWSC016608 for perforce@freebsd.org; Thu, 27 May 2010 08:59:32 GMT (envelope-from gcooper@FreeBSD.org) Date: Thu, 27 May 2010 08:59:32 GMT Message-Id: <201005270859.o4R8xWSC016608@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gcooper@FreeBSD.org using -f From: Garrett Cooper To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 178862 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 May 2010 08:59:33 -0000 http://p4web.freebsd.org/@@178862?ac=10 Change 178862 by gcooper@gcooper-bayonetta on 2010/05/27 08:58:57 Partially fix the linereading mechanism in read_plist I broke in @178293 when I removed the fgets invocation. Affected files ... .. //depot/projects/soc2007/gcooper-pkg_install-enhancements-simplified/lib/libpkg/plist.c#5 edit Differences ... ==== //depot/projects/soc2007/gcooper-pkg_install-enhancements-simplified/lib/libpkg/plist.c#5 (text+ko) ==== @@ -22,10 +22,14 @@ __FBSDID("$FreeBSD: src/lib/libpkg/plist.c,v 1.1 2010/04/23 11:07:43 flz Exp $"); #include +#include +#include #include +#include #include #include #include +#include #include #include "pkg.h" @@ -196,7 +200,7 @@ char *cp; const char *sp; - strcpy(cmd, s); + strlcpy(cmd, s, sizeof(cmd)); str_lowercase(cmd); cp = cmd; sp = s; @@ -264,72 +268,163 @@ int read_plist(Package *pkg, int fd) { - char *cp, pline[FILENAME_MAX]; - int cmd, major, minor, rc = 0; + struct stat sb; + char *cmd_buf = NULL; + char *contents_map = NULL; + char *cp; + char *end; + char *start; + int cmd; + int serrno; + int major; + int minor; + int rc = -1; + off_t off; size_t len; pkg->fmtver_maj = 1; pkg->fmtver_mnr = 0; pkg->origin = NULL; - /* - * XXX (gcooper): BAD BAD BAD -- this can be longer than - * FILENAME_MAX - */ - while (rc == 0 && 0 < read(fd, pline, FILENAME_MAX)) { - len = strlen(pline); + errno = 0; + + if (fstat(fd, &sb) == 0 && + (contents_map = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, + 0)) != NULL) { + + off = sb.st_size; + rc = 0; + start = contents_map; + + /* + * XXX (gcooper): BAD BAD BAD -- this can be longer than + * FILENAME_MAX + */ + while (rc == 0 && 0 < off) { + + end = strchr(start, '\n'); + /* No trailing newlines -- look for '\0'. */ + if (end == NULL) + end = strchr(start, '\0'); + /* Don't forget we're eating newlines.. om nom nom... */ + else + off--; + /* + * This is bad if this fails -- a non-NUL terminated + * string is in our midst! + */ + assert (end != NULL); + + cmd_buf = malloc(end-start+1); + + if (cmd_buf == NULL) + rc = -1; + else { + + strlcpy(cmd_buf, start, end-start+1); + + warnx("cmd_buf: %s", cmd_buf); + + len = strlen(cmd_buf); + off -= len; + + /* Trim off trailing whitespace. */ + while (0 < len && isspace(cmd_buf[len])) + cmd_buf[len--] = '\0'; + + /* Empty line. */ + if (len == 0) { + errno = EINVAL; + rc = -1; + } else + cp = cmd_buf; - while (len && isspace(pline[len - 1])) - pline[--len] = '\0'; - if (!len) - continue; - cp = pline; - if (pline[0] != CMD_CHAR) { - cmd = PLIST_FILE; - goto bottom; - } - cmd = plist_cmd(pline + 1, &cp); - if (cmd == -1) { - warnx("%s: unknown command '%s' (package tools out of " - "date?)", __func__, pline); - goto bottom; - } - if (*cp == '\0') { - cp = NULL; - if (cmd == PLIST_PKGDEP) { - warnx("corrupted record (pkgdep line without " - "argument), ignoring"); - cmd = -1; } - goto bottom; - } - if (cmd == PLIST_COMMENT && - sscanf(cp, "PKG_FORMAT_REVISION:%d.%d\n", &major, &minor) == - 2) { + + /* A plist command directive */ + if (rc == 0 && *start == CMD_CHAR) { + + cmd = plist_cmd(start+1, &cp); + + if (cmd == -1) { + warnx("%s: unknown command '%s' " + "(package tools out of date?)", + __func__, start); + rc = -1; + } else if (*cp == '\0') { + + cp = NULL; + if (cmd == PLIST_PKGDEP) { + warnx("corrupted record (pkgdep line " + "without argument), ignoring"); + cmd = rc = -1; + } + + } + if (cp != NULL && cmd == PLIST_COMMENT && + sscanf(cp, "PKG_FORMAT_REVISION:%d.%d\n", + &major, &minor) == 2) { + + pkg->fmtver_maj = major; + pkg->fmtver_mnr = minor; + + if (verscmp(pkg, PLIST_FMT_VER_MAJOR, + PLIST_FMT_VER_MINOR) > 0) { + + warnx("plist format revision " + "(%d.%d) is higher than " + "supported format " + "reversion (%d.%d)", + pkg->fmtver_maj, + pkg->fmtver_mnr, + PLIST_FMT_VER_MAJOR, + PLIST_FMT_VER_MINOR); + + if (pkg->fmtver_maj > + PLIST_FMT_VER_MAJOR) { + errno = EINVAL; + rc = -1; + } + + } + + } - pkg->fmtver_maj = major; - pkg->fmtver_mnr = minor; + } + /* A file manifest item */ + else if (rc == 0) + cmd = PLIST_FILE; + if (rc == 0) { - if (verscmp(pkg, PLIST_FMT_VER_MAJOR, - PLIST_FMT_VER_MINOR) <= 0) - goto bottom; + add_plist(pkg, cmd, cp); + start = end; + /* We aren't at the end of the line, yet.. */ + if (start != '\0') + start++; - warnx("plist format revision (%d.%d) is higher than " - "supported (%d.%d)", - pkg->fmtver_maj, pkg->fmtver_mnr, - PLIST_FMT_VER_MAJOR, PLIST_FMT_VER_MINOR); + } - if (pkg->fmtver_maj > PLIST_FMT_VER_MAJOR) { - errno = EINVAL; - rc = -1; + if (cmd_buf != NULL) { + free (cmd_buf); + cmd_buf = NULL; } } -bottom: - if (rc == 0) - add_plist(pkg, cmd, cp); + } + + if (contents_map != NULL) { + serrno = errno; + munmap(contents_map, sb.st_size); + if (serrno == 0) + errno = serrno; + } + if (rc == -1 && cmd_buf != NULL) { + serrno = errno; + free(cmd_buf); + if (serrno == 0) + errno = serrno; } return rc; @@ -476,8 +571,9 @@ break; case PLIST_CWD: - if (!prefix) + if (prefix == NULL) prefix = p->name; + warnx("prefix: %s", prefix); Where = (p->name == NULL) ? prefix : p->name; if (Verbose) printf("Change working directory to %s\n", Where);