From owner-p4-projects@FreeBSD.ORG Thu Jun 3 02:37:23 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 87E0F1065678; Thu, 3 Jun 2010 02:37:23 +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 4C64B106566C for ; Thu, 3 Jun 2010 02:37:23 +0000 (UTC) (envelope-from jlaffaye@FreeBSD.org) Received: from repoman.freebsd.org (unknown [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 3963D8FC14 for ; Thu, 3 Jun 2010 02:37:23 +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 o532bMvA089466 for ; Thu, 3 Jun 2010 02:37:22 GMT (envelope-from jlaffaye@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o532bM70089464 for perforce@freebsd.org; Thu, 3 Jun 2010 02:37:22 GMT (envelope-from jlaffaye@FreeBSD.org) Date: Thu, 3 Jun 2010 02:37:22 GMT Message-Id: <201006030237.o532bM70089464@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jlaffaye@FreeBSD.org using -f From: Julien Laffaye To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 179127 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, 03 Jun 2010 02:37:24 -0000 http://p4web.freebsd.org/@@179127?ac=10 Change 179127 by jlaffaye@jlaffaye-chulak on 2010/06/03 02:37:12 Layered read_plist() API to be able to read a plist from a buffer. read_plist() still takes a fd but uses read_plist_from_buffer() to do the real job. Affected files ... .. //depot/projects/soc2010/pkg_complete/lib/libpkg/pkg.h#4 edit .. //depot/projects/soc2010/pkg_complete/lib/libpkg/plist.c#4 edit Differences ... ==== //depot/projects/soc2010/pkg_complete/lib/libpkg/pkg.h#4 (text+ko) ==== @@ -199,6 +199,7 @@ const char *name); int write_plist(Package *, FILE *); int read_plist(Package *, int); +int read_plist_from_buffer(Package *, char *, off_t); int plist_cmd(const char *, char **); int delete_package(Boolean, Boolean, Package *); Boolean make_preserve_name(char *, int, const char *, const char *); ==== //depot/projects/soc2010/pkg_complete/lib/libpkg/plist.c#4 (text+ko) ==== @@ -316,13 +316,14 @@ return (-1); } -/* Read a packing list from a file */ +/* + * Read a packing list from a buffer of specified size + * The buffer is not modified nor is free'ed + */ int -read_plist(Package *pkg, int fd) +read_plist_from_buffer(Package *pkg, char *plist_buf, off_t plist_size) { - struct stat sb; char *cmd_buf = NULL; - char *contents_map = NULL; char *cp; char *end; char *start; @@ -331,165 +332,184 @@ int major; int minor; int retcode = -1; - off_t end_off; size_t len; + assert(pkg != NULL); + assert(plist_buf != NULL); + assert(plist_size > 0); + pkg->fmtver_maj = 1; pkg->fmtver_mnr = 0; pkg->origin = NULL; errno = 0; - if (fstat(fd, &sb) == 0 && - (contents_map = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, - 0)) != NULL) { + retcode = 0; + start = plist_buf; - end_off = sb.st_size; - retcode = 0; - start = contents_map; + while (retcode == 0 && 0 < plist_size) { - while (retcode == 0 && 0 < end_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 + plist_size--; + /* + * This is bad if this fails -- a non-NUL terminated + * string is in our midst! + */ + assert (end != NULL); - 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 - end_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); - cmd_buf = malloc(end-start+1); + if (cmd_buf == NULL) + retcode = -1; + else { - if (cmd_buf == NULL) - retcode = -1; - else { + strlcpy(cmd_buf, start, end-start+1); - strlcpy(cmd_buf, start, end-start+1); + len = strlen(cmd_buf); + plist_size -= len; + + /* Trim plist_size trailing whitespace. */ + while (0 < len && isspace(cmd_buf[len])) + cmd_buf[len--] = '\0'; - len = strlen(cmd_buf); - end_off -= len; - - /* Trim end_off trailing whitespace. */ - while (0 < len && isspace(cmd_buf[len])) - cmd_buf[len--] = '\0'; + /* Empty line. */ + if (len == 0) { + errno = EINVAL; + retcode = -1; + } else + cp = cmd_buf; - /* Empty line. */ - if (len == 0) { - errno = EINVAL; - retcode = -1; - } else - cp = cmd_buf; + } - } + /* A plist command directive */ + if (retcode == 0 && *start == CMD_CHAR) { - /* A plist command directive */ - if (retcode == 0 && *start == CMD_CHAR) { + cmd = plist_cmd(cmd_buf+1, &cp); - cmd = plist_cmd(cmd_buf+1, &cp); + if (cmd == -1) { + warnx("%s: unknown command '%s' " + "(package tools out of date?)", + __func__, start); + retcode = -1; + } else if (*cp == '\0') { - if (cmd == -1) { - warnx("%s: unknown command '%s' " - "(package tools out of date?)", - __func__, start); - retcode = -1; - } else if (*cp == '\0') { - - cp = NULL; - if (cmd == PLIST_PKGDEP) { - warnx("corrupted record " - "(pkgdep line without " - "argument), ignoring"); - errno = EINVAL; - cmd = retcode = -1; - } - + cp = NULL; + if (cmd == PLIST_PKGDEP) { + warnx("corrupted record " + "(pkgdep line without " + "argument), ignoring"); + errno = EINVAL; + cmd = retcode = -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 (cp != NULL && cmd == PLIST_COMMENT && + sscanf(cp, "PKG_FORMAT_REVISION:%d.%d\n", + &major, &minor) == 2) { - if (verscmp(pkg, PLIST_FMT_VER_MAJOR, - PLIST_FMT_VER_MINOR) > 0) { + pkg->fmtver_maj = major; + pkg->fmtver_mnr = minor; - 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 (verscmp(pkg, PLIST_FMT_VER_MAJOR, + PLIST_FMT_VER_MINOR) > 0) { - if (pkg->fmtver_maj > - PLIST_FMT_VER_MAJOR) { - errno = EINVAL; - retcode = -1; - } + 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; + retcode = -1; } } } - /* A file manifest item */ - else if (retcode == 0) - cmd = PLIST_FILE; - /* - * Winner, winner, chicken dinner.. we have a working - * command! - */ - if (retcode == 0) { + } + /* A file manifest item */ + else if (retcode == 0) + cmd = PLIST_FILE; - if (add_plist(pkg, cmd, cp) == -1) - retcode = -1; - else { + /* + * Winner, winner, chicken dinner.. we have a working + * command! + */ + if (retcode == 0) { - start = end; - /* - * We aren't at the end of the line, - * yet.. - */ - if (start != '\0') - start++; + if (add_plist(pkg, cmd, cp) == -1) + retcode = -1; + else { - } + start = end; + /* + * We aren't at the end of the line, + * yet.. + */ + if (start != '\0') + start++; } - /* - * XXX (gcooper): using more intelligent pointer - * arithmetic and proper NUL termination, there's no - * reason why this needs to be freed automatically in - * each iteration. - */ - if (cmd_buf != NULL) { - free (cmd_buf); - cmd_buf = NULL; - } + } + /* + * XXX (gcooper): using more intelligent pointer + * arithmetic and proper NUL termination, there's no + * reason why this needs to be freed automatically in + * each iteration. + */ + if (cmd_buf != NULL) { + free (cmd_buf); + cmd_buf = NULL; } } - if (contents_map != NULL) { + if (retcode == -1 && cmd_buf != NULL) { serrno = errno; - munmap(contents_map, sb.st_size); + free(cmd_buf); if (serrno == 0) errno = serrno; } - if (retcode == -1 && cmd_buf != NULL) { + return (retcode); + +} + +/* Read a packing list from a file */ +int +read_plist(Package *pkg, int fd) +{ + struct stat sb; + char *contents_map = NULL; + int serrno; + int retcode; + + retcode = 0; + errno = 0; + + if (fstat(fd, &sb) == 0 && + (contents_map = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, + 0)) != NULL) + retcode = read_plist_from_buffer(pkg, contents_map, sb.st_size); + else + retcode = -1; + + if (contents_map != NULL) { serrno = errno; - free(cmd_buf); + munmap(contents_map, sb.st_size); if (serrno == 0) errno = serrno; }