svn commit: r185850 - in projects/releng_7_xen: lib/libarchive lib/libc lib/libc/gen lib/libc/i386/sys lib/libc/string lib/libutil share/man/man4 share/man/man5 sys sys/amd64 sys/boot/forth sys/con...

Kip Macy kmacy at FreeBSD.org
Wed Dec 10 02:12:05 PST 2008


Author: kmacy
Date: Wed Dec 10 10:12:04 2008
New Revision: 185850
URL: http://svn.freebsd.org/changeset/base/185850

Log:
  IF_RELENG7 184527:185849

Added:
  projects/releng_7_xen/lib/libutil/kinfo_getfile.c
  projects/releng_7_xen/lib/libutil/kinfo_getvmmap.c
  projects/releng_7_xen/share/man/man5/nullfs.5
Modified:
  projects/releng_7_xen/lib/libarchive/   (props changed)
  projects/releng_7_xen/lib/libarchive/archive_read_support_format_iso9660.c
  projects/releng_7_xen/lib/libarchive/archive_string.c
  projects/releng_7_xen/lib/libarchive/archive_string.h
  projects/releng_7_xen/lib/libc/   (props changed)
  projects/releng_7_xen/lib/libc/gen/times.3
  projects/releng_7_xen/lib/libc/i386/sys/pipe.S
  projects/releng_7_xen/lib/libc/i386/sys/reboot.S
  projects/releng_7_xen/lib/libc/i386/sys/setlogin.S
  projects/releng_7_xen/lib/libc/string/ffsll.c   (props changed)
  projects/releng_7_xen/lib/libc/string/flsll.c   (props changed)
  projects/releng_7_xen/lib/libutil/   (props changed)
  projects/releng_7_xen/lib/libutil/Makefile
  projects/releng_7_xen/lib/libutil/libutil.h
  projects/releng_7_xen/share/man/man4/   (props changed)
  projects/releng_7_xen/share/man/man4/bce.4
  projects/releng_7_xen/share/man/man5/   (props changed)
  projects/releng_7_xen/share/man/man5/Makefile
  projects/releng_7_xen/share/man/man5/fstab.5
  projects/releng_7_xen/sys/   (props changed)
  projects/releng_7_xen/sys/amd64/Makefile
  projects/releng_7_xen/sys/boot/forth/loader.conf.5
  projects/releng_7_xen/sys/contrib/pf/   (props changed)
  projects/releng_7_xen/sys/dev/ale/if_ale.c
  projects/releng_7_xen/sys/dev/bce/if_bce.c
  projects/releng_7_xen/sys/dev/cxgb/   (props changed)
  projects/releng_7_xen/sys/dev/cxgb/common/cxgb_ael1002.c
  projects/releng_7_xen/sys/dev/cxgb/common/cxgb_t3_hw.c
  projects/releng_7_xen/sys/dev/cxgb/common/cxgb_xgmac.c
  projects/releng_7_xen/sys/dev/cxgb/cxgb_main.c
  projects/releng_7_xen/sys/dev/re/if_re.c
  projects/releng_7_xen/sys/kern/Make.tags.inc
  projects/releng_7_xen/sys/kern/kern_descrip.c
  projects/releng_7_xen/sys/kern/kern_proc.c
  projects/releng_7_xen/sys/kern/vfs_cache.c
  projects/releng_7_xen/sys/netinet/in_pcb.h
  projects/releng_7_xen/sys/pci/if_rlreg.h
  projects/releng_7_xen/sys/sys/sysctl.h
  projects/releng_7_xen/sys/sys/user.h
  projects/releng_7_xen/sys/ufs/ufs/ufs_quota.c
  projects/releng_7_xen/usr.bin/procstat/   (props changed)
  projects/releng_7_xen/usr.bin/procstat/Makefile
  projects/releng_7_xen/usr.bin/procstat/procstat_files.c
  projects/releng_7_xen/usr.bin/procstat/procstat_vm.c
  projects/releng_7_xen/usr.bin/xargs/   (props changed)
  projects/releng_7_xen/usr.bin/xargs/xargs.1
  projects/releng_7_xen/usr.sbin/   (props changed)
  projects/releng_7_xen/usr.sbin/mtree/   (props changed)
  projects/releng_7_xen/usr.sbin/mtree/mtree.c

Modified: projects/releng_7_xen/lib/libarchive/archive_read_support_format_iso9660.c
==============================================================================
--- projects/releng_7_xen/lib/libarchive/archive_read_support_format_iso9660.c	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libarchive/archive_read_support_format_iso9660.c	Wed Dec 10 10:12:04 2008	(r185850)
@@ -138,6 +138,15 @@ __FBSDID("$FreeBSD$");
 #define PVD_reserved4_size 1
 #define PVD_application_data_offset (PVD_reserved4_offset + PVD_reserved4_size)
 #define PVD_application_data_size 512
+#define PVD_reserved5_offset (PVD_application_data_offset + PVD_application_data_size)
+#define PVD_reserved5_size (2048 - PVD_reserved5_offset)
+
+/* TODO: It would make future maintenance easier to just hardcode the
+ * above values.  In particular, ECMA119 states the offsets as part of
+ * the standard.  That would eliminate the need for the following check.*/
+#if PVD_reserved5_offset != 1395
+#error PVD offset and size definitions are wrong.
+#endif
 
 /* Structure of an on-disk directory record. */
 /* Note:  ISO9660 stores each multi-byte integer twice, once in
@@ -178,17 +187,20 @@ struct file_info {
 	uint64_t	 size;	/* File size in bytes. */
 	uint64_t	 ce_offset; /* Offset of CE */
 	uint64_t	 ce_size; /* Size of CE */
+	time_t		 birthtime; /* File created time. */
 	time_t		 mtime;	/* File last modified time. */
 	time_t		 atime;	/* File last accessed time. */
-	time_t		 ctime;	/* File creation time. */
+	time_t		 ctime;	/* File attribute change time. */
 	uint64_t	 rdev; /* Device number */
 	mode_t		 mode;
 	uid_t		 uid;
 	gid_t		 gid;
 	ino_t		 inode;
 	int		 nlinks;
-	char		*name; /* Null-terminated filename. */
+	struct archive_string name; /* Pathname */
+	char		 name_continues; /* Non-zero if name continues */
 	struct archive_string symlink;
+	char		 symlink_continues; /* Non-zero if link continues */
 };
 
 
@@ -210,6 +222,7 @@ struct iso9660 {
 
 	uint64_t current_position;
 	ssize_t	logical_block_size;
+	uint64_t volume_size; /* Total size of volume in bytes. */
 
 	off_t	entry_sparse_offset;
 	int64_t	entry_bytes_remaining;
@@ -224,7 +237,9 @@ static int	archive_read_format_iso9660_r
 static int	archive_read_format_iso9660_read_header(struct archive_read *,
 		    struct archive_entry *);
 static const char *build_pathname(struct archive_string *, struct file_info *);
+#if DEBUG
 static void	dump_isodirrec(FILE *, const unsigned char *isodirrec);
+#endif
 static time_t	time_from_tm(struct tm *);
 static time_t	isodate17(const unsigned char *);
 static time_t	isodate7(const unsigned char *);
@@ -238,6 +253,12 @@ static struct file_info *
 static void	parse_rockridge(struct iso9660 *iso9660,
 		    struct file_info *file, const unsigned char *start,
 		    const unsigned char *end);
+static void	parse_rockridge_NM1(struct file_info *,
+		    const unsigned char *, int);
+static void	parse_rockridge_SL1(struct file_info *,
+		    const unsigned char *, int);
+static void	parse_rockridge_TF1(struct file_info *,
+		    const unsigned char *, int);
 static void	release_file(struct iso9660 *, struct file_info *);
 static unsigned	toi(const void *p, int n);
 
@@ -314,13 +335,61 @@ static int
 isPVD(struct iso9660 *iso9660, const unsigned char *h)
 {
 	struct file_info *file;
+	int i;
 
-	if (h[0] != 1)
+	/* Type of the Primary Volume Descriptor must be 1. */
+	if (h[PVD_type_offset] != 1)
 		return (0);
-	if (memcmp(h+1, "CD001", 5) != 0)
+
+	/* ID must be "CD001" */
+	if (memcmp(h + PVD_id_offset, "CD001", 5) != 0)
+		return (0);
+
+	/* PVD version must be 1. */
+	if (h[PVD_version_offset] != 1)
 		return (0);
 
+	/* Reserved field must be 0. */
+	if (h[PVD_reserved1_offset] != 0)
+		return (0);
+
+	/* Reserved field must be 0. */
+	for (i = 0; i < PVD_reserved2_size; ++i)
+		if (h[PVD_reserved2_offset + i] != 0)
+			return (0);
+
+	/* Reserved field must be 0. */
+	for (i = 0; i < PVD_reserved3_size; ++i)
+		if (h[PVD_reserved3_offset + i] != 0)
+			return (0);
+
+	/* Logical block size must be > 0. */
+	/* I've looked at Ecma 119 and can't find any stronger
+	 * restriction on this field. */
 	iso9660->logical_block_size = toi(h + PVD_logical_block_size_offset, 2);
+	if (iso9660->logical_block_size <= 0)
+		return (0);
+
+	iso9660->volume_size = iso9660->logical_block_size
+	    * (uint64_t)toi(h + PVD_volume_space_size_offset, 4);
+
+	/* File structure version must be 1 for ISO9660/ECMA119. */
+	if (h[PVD_file_structure_version_offset] != 1)
+		return (0);
+
+
+	/* Reserved field must be 0. */
+	for (i = 0; i < PVD_reserved4_size; ++i)
+		if (h[PVD_reserved4_offset + i] != 0)
+			return (0);
+
+	/* Reserved field must be 0. */
+	for (i = 0; i < PVD_reserved5_size; ++i)
+		if (h[PVD_reserved5_offset + i] != 0)
+			return (0);
+
+	/* XXX TODO: Check other values for sanity; reject more
+	 * malformed PVDs. XXX */
 
 	/* Store the root directory in the pending list. */
 	file = parse_file_info(iso9660, NULL, h + PVD_root_directory_record_offset);
@@ -352,12 +421,22 @@ archive_read_format_iso9660_read_header(
 	iso9660->entry_bytes_remaining = file->size;
 	iso9660->entry_sparse_offset = 0; /* Offset for sparse-file-aware clients. */
 
+	if (file->offset + file->size > iso9660->volume_size) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "File is beyond end-of-media: %s", file->name);
+		iso9660->entry_bytes_remaining = 0;
+		iso9660->entry_sparse_offset = 0;
+		release_file(iso9660, file);
+		return (ARCHIVE_WARN);
+	}
+
 	/* Set up the entry structure with information about this entry. */
 	archive_entry_set_mode(entry, file->mode);
 	archive_entry_set_uid(entry, file->uid);
 	archive_entry_set_gid(entry, file->gid);
 	archive_entry_set_nlink(entry, file->nlinks);
 	archive_entry_set_ino(entry, file->inode);
+	/* archive_entry_set_birthtime(entry, file->birthtime, 0); */
 	archive_entry_set_mtime(entry, file->mtime, 0);
 	archive_entry_set_ctime(entry, file->ctime, 0);
 	archive_entry_set_atime(entry, file->atime, 0);
@@ -535,13 +614,7 @@ parse_file_info(struct iso9660 *iso9660,
 	file->mtime = isodate7(isodirrec + DR_date_offset);
 	file->ctime = file->atime = file->mtime;
 	name_len = (size_t)*(const unsigned char *)(isodirrec + DR_name_len_offset);
-	file->name = (char *)malloc(name_len + 1);
-	if (file->name == NULL) {
-		free(file);
-		return (NULL);
-	}
-	memcpy(file->name, isodirrec + DR_name_offset, name_len);
-	file->name[name_len] = '\0';
+	archive_strncpy(&file->name, isodirrec + DR_name_offset, name_len);
 	flags = *(isodirrec + DR_flags_offset);
 	if (flags & 0x02)
 		file->mode = AE_IFDIR | 0700;
@@ -561,6 +634,7 @@ parse_file_info(struct iso9660 *iso9660,
 		parse_rockridge(iso9660, file, rr_start, rr_end);
 	}
 
+#if DEBUG
 	/* DEBUGGING: Warn about attributes I don't yet fully support. */
 	if ((flags & ~0x02) != 0) {
 		fprintf(stderr, "\n ** Unrecognized flag: ");
@@ -583,7 +657,7 @@ parse_file_info(struct iso9660 *iso9660,
 		dump_isodirrec(stderr, isodirrec);
 		fprintf(stderr, "\n");
 	}
-
+#endif
 	return (file);
 }
 
@@ -623,6 +697,7 @@ parse_rockridge(struct iso9660 *iso9660,
 	while (p + 4 < end  /* Enough space for another entry. */
 	    && p[0] >= 'A' && p[0] <= 'Z' /* Sanity-check 1st char of name. */
 	    && p[1] >= 'A' && p[1] <= 'Z' /* Sanity-check 2nd char of name. */
+	    && p[2] >= 4 /* Sanity-check length. */
 	    && p + p[2] <= end) { /* Sanity-check length. */
 		const unsigned char *data = p + 4;
 		int data_length = p[2] - 4;
@@ -635,61 +710,54 @@ parse_rockridge(struct iso9660 *iso9660,
 		 */
 		switch(p[0]) {
 		case 'C':
-			if (p[0] == 'C' && p[1] == 'E' && version == 1) {
-				/*
-				 * CE extension comprises:
-				 *   8 byte sector containing extension
-				 *   8 byte offset w/in above sector
-				 *   8 byte length of continuation
-				 */
-				file->ce_offset = toi(data, 4)
-				    * iso9660->logical_block_size
-				    + toi(data + 8, 4);
-				file->ce_size = toi(data + 16, 4);
+			if (p[0] == 'C' && p[1] == 'E') {
+				if (version == 1 && data_length == 24) {
+					/*
+					 * CE extension comprises:
+					 *   8 byte sector containing extension
+					 *   8 byte offset w/in above sector
+					 *   8 byte length of continuation
+					 */
+					file->ce_offset = (uint64_t)toi(data, 4)
+					    * iso9660->logical_block_size
+					    + toi(data + 8, 4);
+					file->ce_size = toi(data + 16, 4);
+					/* If the result is rediculous,
+					 * ignore it. */
+					if (file->ce_offset + file->ce_size
+					    > iso9660->volume_size) {
+						file->ce_offset = 0;
+						file->ce_size = 0;
+					}
+				}
 				break;
 			}
 			/* FALLTHROUGH */
 		case 'N':
-			if (p[0] == 'N' && p[1] == 'M' && version == 1
-				&& *data == 0) {
-				/* NM extension with flag byte == 0 */
-				/*
-				 * NM extension comprises:
-				 *   one byte flag
-				 *   rest is long name
-				 */
-				/* TODO: Obey flags. */
-				char *old_name = file->name;
-
-				data++;  /* Skip flag byte. */
-				data_length--;
-				file->name = (char *)malloc(data_length + 1);
-				if (file->name != NULL) {
-					free(old_name);
-					memcpy(file->name, data, data_length);
-					file->name[data_length] = '\0';
-				} else
-					file->name = old_name;
+			if (p[0] == 'N' && p[1] == 'M') {
+				if (version == 1)
+					parse_rockridge_NM1(file,
+					    data, data_length);
 				break;
 			}
 			/* FALLTHROUGH */
 		case 'P':
-			if (p[0] == 'P' && p[1] == 'D' && version == 1) {
+			if (p[0] == 'P' && p[1] == 'D') {
 				/*
 				 * PD extension is padding;
 				 * contents are always ignored.
 				 */
 				break;
 			}
-			if (p[0] == 'P' && p[1] == 'N' && version == 1) {
-				if (data_length == 16) {
+			if (p[0] == 'P' && p[1] == 'N') {
+				if (version == 1 && data_length == 16) {
 					file->rdev = toi(data,4);
 					file->rdev <<= 32;
 					file->rdev |= toi(data + 8, 4);
 				}
 				break;
 			}
-			if (p[0] == 'P' && p[1] == 'X' && version == 1) {
+			if (p[0] == 'P' && p[1] == 'X') {
 				/*
 				 * PX extension comprises:
 				 *   8 bytes for mode,
@@ -698,12 +766,22 @@ parse_rockridge(struct iso9660 *iso9660,
 				 *   8 bytes for gid,
 				 *   8 bytes for inode.
 				 */
-				if (data_length == 32) {
-					file->mode = toi(data, 4);
-					file->nlinks = toi(data + 8, 4);
-					file->uid = toi(data + 16, 4);
-					file->gid = toi(data + 24, 4);
-					file->inode = toi(data + 32, 4);
+				if (version == 1) {
+					if (data_length >= 8)
+						file->mode
+						    = toi(data, 4);
+					if (data_length >= 16)
+						file->nlinks
+						    = toi(data + 8, 4);
+					if (data_length >= 24)
+						file->uid
+						    = toi(data + 16, 4);
+					if (data_length >= 32)
+						file->gid
+						    = toi(data + 24, 4);
+					if (data_length >= 40)
+						file->inode
+						    = toi(data + 32, 4);
 				}
 				break;
 			}
@@ -720,56 +798,14 @@ parse_rockridge(struct iso9660 *iso9660,
 			}
 			/* FALLTHROUGH */
 		case 'S':
-			if (p[0] == 'S' && p[1] == 'L' && version == 1
-			    && *data == 0) {
-				int cont = 1;
-				/* SL extension with flags == 0 */
-				/* TODO: handle non-zero flag values. */
-				data++;  /* Skip flag byte. */
-				data_length--;
-				while (data_length > 0) {
-					unsigned char flag = *data++;
-					unsigned char nlen = *data++;
-					data_length -= 2;
-
-					if (cont == 0)
-						archive_strcat(&file->symlink, "/");
-					cont = 0;
-
-					switch(flag) {
-					case 0x01: /* Continue */
-						archive_strncat(&file->symlink,
-						    (const char *)data, nlen);
-						cont = 1;
-						break;
-					case 0x02: /* Current */
-						archive_strcat(&file->symlink, ".");
-						break;
-					case 0x04: /* Parent */
-						archive_strcat(&file->symlink, "..");
-						break;
-					case 0x08: /* Root */
-					case 0x10: /* Volume root */
-						archive_string_empty(&file->symlink);
-						break;
-					case 0x20: /* Hostname */
-						archive_strcat(&file->symlink, "hostname");
-						break;
-					case 0:
-						archive_strncat(&file->symlink,
-						    (const char *)data, nlen);
-						break;
-					default:
-						/* TODO: issue a warning ? */
-						break;
-					}
-					data += nlen;
-					data_length -= nlen;
-				}
+			if (p[0] == 'S' && p[1] == 'L') {
+				if (version == 1)
+					parse_rockridge_SL1(file,
+					    data, data_length);
 				break;
 			}
 			if (p[0] == 'S' && p[1] == 'P'
-			    && version == 1 && data_length == 7
+			    && version == 1 && data_length == 3
 			    && data[0] == (unsigned char)'\xbe'
 			    && data[1] == (unsigned char)'\xef') {
 				/*
@@ -805,66 +841,27 @@ parse_rockridge(struct iso9660 *iso9660,
 				return;
 			}
 		case 'T':
-			if (p[0] == 'T' && p[1] == 'F' && version == 1) {
-				char flag = data[0];
-				/*
-				 * TF extension comprises:
-				 *   one byte flag
-				 *   create time (optional)
-				 *   modify time (optional)
-				 *   access time (optional)
-				 *   attribute time (optional)
-				 *  Time format and presence of fields
-				 *  is controlled by flag bits.
-				 */
-				data++;
-				if (flag & 0x80) {
-					/* Use 17-byte time format. */
-					if (flag & 1) /* Create time. */
-						data += 17;
-					if (flag & 2) { /* Modify time. */
-						file->mtime = isodate17(data);
-						data += 17;
-					}
-					if (flag & 4) { /* Access time. */
-						file->atime = isodate17(data);
-						data += 17;
-					}
-					if (flag & 8) { /* Attribute time. */
-						file->ctime = isodate17(data);
-						data += 17;
-					}
-				} else {
-					/* Use 7-byte time format. */
-					if (flag & 1) /* Create time. */
-						data += 7;
-					if (flag & 2) { /* Modify time. */
-						file->mtime = isodate7(data);
-						data += 7;
-					}
-					if (flag & 4) { /* Access time. */
-						file->atime = isodate7(data);
-						data += 7;
-					}
-					if (flag & 8) { /* Attribute time. */
-						file->ctime = isodate7(data);
-						data += 7;
-					}
-				}
+			if (p[0] == 'T' && p[1] == 'F') {
+				if (version == 1)
+					parse_rockridge_TF1(file,
+					    data, data_length);
 				break;
 			}
 			/* FALLTHROUGH */
 		default:
 			/* The FALLTHROUGHs above leave us here for
 			 * any unsupported extension. */
+#if DEBUG
 			{
 				const unsigned char *t;
-				fprintf(stderr, "\nUnsupported RRIP extension for %s\n", file->name);
+				fprintf(stderr, "\nUnsupported RRIP extension for %s\n", file->name.s);
 				fprintf(stderr, " %c%c(%d):", p[0], p[1], data_length);
 				for (t = data; t < data + data_length && t < data + 16; t++)
 					fprintf(stderr, " %02x", *t);
 				fprintf(stderr, "\n");
 			}
+#endif
+			break;
 		}
 
 
@@ -874,14 +871,222 @@ parse_rockridge(struct iso9660 *iso9660,
 }
 
 static void
+parse_rockridge_NM1(struct file_info *file, const unsigned char *data,
+    int data_length)
+{
+	if (!file->name_continues)
+		archive_string_empty(&file->name);
+	file->name_continues = 0;
+	if (data_length < 1)
+		return;
+	/*
+	 * NM version 1 extension comprises:
+	 *   1 byte flag, value is one of:
+	 *     = 0: remainder is name
+	 *     = 1: remainder is name, next NM entry continues name
+	 *     = 2: "."
+	 *     = 4: ".."
+	 *     = 32: Implementation specific
+	 *     All other values are reserved.
+	 */
+	switch(data[0]) {
+	case 0:
+		if (data_length < 2)
+			return;
+		archive_strncat(&file->name, data + 1, data_length - 1);
+		break;
+	case 1:
+		if (data_length < 2)
+			return;
+		archive_strncat(&file->name, data + 1, data_length - 1);
+		file->name_continues = 1;
+		break;
+	case 2:
+		archive_strcat(&file->name, ".");
+		break;
+	case 4:
+		archive_strcat(&file->name, "..");
+		break;
+	default:
+		return;
+	}
+
+}
+
+static void
+parse_rockridge_TF1(struct file_info *file, const unsigned char *data,
+    int data_length)
+{
+	char flag;
+	/*
+	 * TF extension comprises:
+	 *   one byte flag
+	 *   create time (optional)
+	 *   modify time (optional)
+	 *   access time (optional)
+	 *   attribute time (optional)
+	 *  Time format and presence of fields
+	 *  is controlled by flag bits.
+	 */
+	if (data_length < 1)
+		return;
+	flag = data[0];
+	++data;
+	--data_length;
+	if (flag & 0x80) {
+		/* Use 17-byte time format. */
+		if ((flag & 1) && data_length >= 17) {
+			/* Create time. */
+			file->birthtime = isodate17(data);
+			data += 17;
+			data_length -= 17;
+		}
+		if ((flag & 2) && data_length >= 17) {
+			/* Modify time. */
+			file->mtime = isodate17(data);
+			data += 17;
+			data_length -= 17;
+		}
+		if ((flag & 4) && data_length >= 17) {
+			/* Access time. */
+			file->atime = isodate17(data);
+			data += 17;
+			data_length -= 17;
+		}
+		if ((flag & 8) && data_length >= 17) {
+			/* Attribute change time. */
+			file->ctime = isodate17(data);
+			data += 17;
+			data_length -= 17;
+		}
+	} else {
+		/* Use 7-byte time format. */
+		if ((flag & 1) && data_length >= 7) {
+			/* Create time. */
+			file->birthtime = isodate17(data);
+			data += 7;
+			data_length -= 7;
+		}
+		if ((flag & 2) && data_length >= 7) {
+			/* Modify time. */
+			file->mtime = isodate7(data);
+			data += 7;
+			data_length -= 7;
+		}
+		if ((flag & 4) && data_length >= 7) {
+			/* Access time. */
+			file->atime = isodate7(data);
+			data += 7;
+			data_length -= 7;
+		}
+		if ((flag & 8) && data_length >= 7) {
+			/* Attribute change time. */
+			file->ctime = isodate7(data);
+			data += 7;
+			data_length -= 7;
+		}
+	}
+}
+
+static void
+parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
+    int data_length)
+{
+	int component_continues = 1;
+
+	if (!file->symlink_continues)
+		archive_string_empty(&file->symlink);
+	else
+		archive_strcat(&file->symlink, "/");
+	file->symlink_continues = 0;
+
+	/*
+	 * Defined flag values:
+	 *  0: This is the last SL record for this symbolic link
+	 *  1: this symbolic link field continues in next SL entry
+	 *  All other values are reserved.
+	 */
+	if (data_length < 1)
+		return;
+	switch(*data) {
+	case 0:
+		break;
+	case 1:
+		file->symlink_continues = 1;
+		break;
+	default:
+		return;
+	}
+	++data;  /* Skip flag byte. */
+	--data_length;
+
+	/*
+	 * SL extension body stores "components".
+	 * Basically, this is a complicated way of storing
+	 * a POSIX path.  It also interferes with using
+	 * symlinks for storing non-path data. <sigh>
+	 *
+	 * Each component is 2 bytes (flag and length)
+	 * possibly followed by name data.
+	 */
+	while (data_length >= 2) {
+		unsigned char flag = *data++;
+		unsigned char nlen = *data++;
+		data_length -= 2;
+
+		if (!component_continues)
+			archive_strcat(&file->symlink, "/");
+		component_continues = 0;
+
+		switch(flag) {
+		case 0: /* Usual case, this is text. */
+			if (data_length < nlen)
+				return;
+			archive_strncat(&file->symlink,
+			    (const char *)data, nlen);
+			break;
+		case 0x01: /* Text continues in next component. */
+			if (data_length < nlen)
+				return;
+			archive_strncat(&file->symlink,
+			    (const char *)data, nlen);
+			component_continues = 1;
+			break;
+		case 0x02: /* Current dir. */
+			archive_strcat(&file->symlink, ".");
+			break;
+		case 0x04: /* Parent dir. */
+			archive_strcat(&file->symlink, "..");
+			break;
+		case 0x08: /* Root of filesystem. */
+			archive_string_empty(&file->symlink);
+			archive_strcat(&file->symlink, "/");
+			break;
+		case 0x10: /* Undefined (historically "volume root" */
+			archive_string_empty(&file->symlink);
+			archive_strcat(&file->symlink, "ROOT");
+			break;
+		case 0x20: /* Undefined (historically "hostname") */
+			archive_strcat(&file->symlink, "hostname");
+			break;
+		default:
+			/* TODO: issue a warning ? */
+			return;
+		}
+		data += nlen;
+		data_length -= nlen;
+	}
+}
+
+
+static void
 release_file(struct iso9660 *iso9660, struct file_info *file)
 {
 	struct file_info *parent;
 
 	if (file->refcount == 0) {
 		parent = file->parent;
-		if (file->name)
-			free(file->name);
+		archive_string_free(&file->name);
 		archive_string_free(&file->symlink);
 		free(file);
 		if (parent != NULL) {
@@ -906,7 +1111,9 @@ next_entry_seek(struct archive_read *a, 
 
 		/* CE area precedes actual file data? Ignore it. */
 		if (file->ce_offset > file->offset) {
-fprintf(stderr, " *** Discarding CE data.\n");
+#if DEBUG
+			fprintf(stderr, " *** Discarding CE data.\n");
+#endif
 			file->ce_offset = 0;
 			file->ce_size = 0;
 		}
@@ -1071,17 +1278,18 @@ time_from_tm(struct tm *t)
 static const char *
 build_pathname(struct archive_string *as, struct file_info *file)
 {
-	if (file->parent != NULL && file->parent->name[0] != '\0') {
+	if (file->parent != NULL && archive_strlen(&file->parent->name) > 0) {
 		build_pathname(as, file->parent);
 		archive_strcat(as, "/");
 	}
-	if (file->name[0] == '\0')
+	if (archive_strlen(&file->name) == 0)
 		archive_strcat(as, ".");
 	else
-		archive_strcat(as, file->name);
+		archive_string_concat(as, &file->name);
 	return (as->s);
 }
 
+#if DEBUG
 static void
 dump_isodirrec(FILE *out, const unsigned char *isodirrec)
 {
@@ -1106,3 +1314,4 @@ dump_isodirrec(FILE *out, const unsigned
 	fprintf(out, " `%.*s'",
 	    toi(isodirrec + DR_name_len_offset, DR_name_len_size), isodirrec + DR_name_offset);
 }
+#endif

Modified: projects/releng_7_xen/lib/libarchive/archive_string.c
==============================================================================
--- projects/releng_7_xen/lib/libarchive/archive_string.c	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libarchive/archive_string.c	Wed Dec 10 10:12:04 2008	(r185850)
@@ -70,6 +70,18 @@ __archive_string_copy(struct archive_str
 }
 
 void
+__archive_string_concat(struct archive_string *dest, struct archive_string *src)
+{
+	if (src->length > 0) {
+		if (__archive_string_ensure(dest, dest->length + src->length + 1) == NULL)
+			__archive_errx(1, "Out of memory");
+		memcpy(dest->s + dest->length, src->s, src->length);
+		dest->length += src->length;
+		dest->s[dest->length] = 0;
+	}
+}
+
+void
 __archive_string_free(struct archive_string *as)
 {
 	as->length = 0;

Modified: projects/releng_7_xen/lib/libarchive/archive_string.h
==============================================================================
--- projects/releng_7_xen/lib/libarchive/archive_string.h	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libarchive/archive_string.h	Wed Dec 10 10:12:04 2008	(r185850)
@@ -92,6 +92,12 @@ __archive_string_copy(struct archive_str
 #define archive_string_copy(dest, src) \
 	__archive_string_copy(dest, src)
 
+/* Concatenate one archive_string to another */
+void
+__archive_string_concat(struct archive_string *dest, struct archive_string *src);
+#define archive_string_concat(dest, src) \
+	__archive_string_concat(dest, src)
+
 /* Ensure that the underlying buffer is at least as large as the request. */
 struct archive_string *
 __archive_string_ensure(struct archive_string *, size_t);

Modified: projects/releng_7_xen/lib/libc/gen/times.3
==============================================================================
--- projects/releng_7_xen/lib/libc/gen/times.3	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libc/gen/times.3	Wed Dec 10 10:12:04 2008	(r185850)
@@ -28,7 +28,7 @@
 .\"     @(#)times.3	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD$
 .\"
-.Dd June 4, 1993
+.Dd December 1, 2008
 .Dt TIMES 3
 .Os
 .Sh NAME
@@ -52,9 +52,13 @@ The
 .Fn times
 function returns the value of time in
 .Dv CLK_TCK Ns 's
-of a second since
-0 hours, 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal
-Time.
+of a second since the system startup time.
+The current value of
+.Dv CLK_TCK ,
+the frequency of the statistics clock in ticks per second, may be
+obtained through the
+.Xr sysconf 3
+interface.
 .Pp
 It also fills in the structure pointed to by
 .Fa tp
@@ -131,6 +135,7 @@ and
 .Xr getrusage 2 ,
 .Xr gettimeofday 2 ,
 .Xr wait 2 ,
+.Xr sysconf 3 ,
 .Xr clocks 7
 .Sh STANDARDS
 The

Modified: projects/releng_7_xen/lib/libc/i386/sys/pipe.S
==============================================================================
--- projects/releng_7_xen/lib/libc/i386/sys/pipe.S	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libc/i386/sys/pipe.S	Wed Dec 10 10:12:04 2008	(r185850)
@@ -44,4 +44,5 @@ SYSCALL(pipe)
 	movl	%edx,4(%ecx)
 	movl	$0,%eax
 	ret
-END(pipe)
+END(__sys_pipe)
+

Modified: projects/releng_7_xen/lib/libc/i386/sys/reboot.S
==============================================================================
--- projects/releng_7_xen/lib/libc/i386/sys/reboot.S	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libc/i386/sys/reboot.S	Wed Dec 10 10:12:04 2008	(r185850)
@@ -40,4 +40,5 @@ __FBSDID("$FreeBSD$");
 
 SYSCALL(reboot)
 	iret
-END(reboot)
+END(__sys_reboot)
+

Modified: projects/releng_7_xen/lib/libc/i386/sys/setlogin.S
==============================================================================
--- projects/releng_7_xen/lib/libc/i386/sys/setlogin.S	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libc/i386/sys/setlogin.S	Wed Dec 10 10:12:04 2008	(r185850)
@@ -52,4 +52,4 @@ SYSCALL(setlogin)
 	movl	$0,CNAME(_logname_valid)
 #endif
 	ret				/* setlogin(name) */
-END(setlogin)
+END(__sys_setlogin)

Modified: projects/releng_7_xen/lib/libutil/Makefile
==============================================================================
--- projects/releng_7_xen/lib/libutil/Makefile	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libutil/Makefile	Wed Dec 10 10:12:04 2008	(r185850)
@@ -9,7 +9,8 @@ LIB=	util
 SHLIB_MAJOR= 7
 
 SRCS=	_secure_path.c auth.c gr_util.c expand_number.c flopen.c fparseln.c \
-	humanize_number.c kld.c login.c login_auth.c login_cap.c login_class.c \
+	humanize_number.c kinfo_getfile.c kinfo_getvmmap.c kld.c \
+	login.c login_auth.c login_cap.c login_class.c \
 	login_crypt.c login_ok.c login_times.c login_tty.c logout.c \
 	logwtmp.c pidfile.c property.c pty.c pw_util.c realhostname.c \
 	stub.c trimdomain.c uucplock.c

Added: projects/releng_7_xen/lib/libutil/kinfo_getfile.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/releng_7_xen/lib/libutil/kinfo_getfile.c	Wed Dec 10 10:12:04 2008	(r185850)
@@ -0,0 +1,72 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libutil.h"
+
+struct kinfo_file *
+kinfo_getfile(pid_t pid, int *cntp)
+{
+	int mib[4];
+	int error;
+	int cnt;
+	size_t len;
+	char *buf, *bp, *eb;
+	struct kinfo_file *kif, *kp, *kf;
+
+	len = 0;
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_PROC;
+	mib[2] = KERN_PROC_FILEDESC;
+	mib[3] = pid;
+
+	error = sysctl(mib, 4, NULL, &len, NULL, 0);
+	if (error)
+		return (0);
+	len = len * 4 / 3;
+	buf = malloc(len);
+	if (buf == NULL)
+		return (0);
+	error = sysctl(mib, 4, buf, &len, NULL, 0);
+	if (error) {
+		free(buf);
+		return (0);
+	}
+	/* Pass 1: count items */
+	cnt = 0;
+	bp = buf;
+	eb = buf + len;
+	while (bp < eb) {
+		kf = (struct kinfo_file *)(uintptr_t)bp;
+		bp += kf->kf_structsize;
+		cnt++;
+	}
+
+	kif = calloc(cnt, sizeof(*kif));
+	if (kif == NULL) {
+		free(buf);
+		return (0);
+	}
+	bp = buf;
+	eb = buf + len;
+	kp = kif;
+	/* Pass 2: unpack */
+	while (bp < eb) {
+		kf = (struct kinfo_file *)(uintptr_t)bp;
+		/* Copy/expand into pre-zeroed buffer */
+		memcpy(kp, kf, kf->kf_structsize);
+		/* Advance to next packed record */
+		bp += kf->kf_structsize;
+		/* Set field size to fixed length, advance */
+		kp->kf_structsize = sizeof(*kp);
+		kp++;
+	}
+	free(buf);
+	*cntp = cnt;
+	return (kif);	/* Caller must free() return value */
+}

Added: projects/releng_7_xen/lib/libutil/kinfo_getvmmap.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/releng_7_xen/lib/libutil/kinfo_getvmmap.c	Wed Dec 10 10:12:04 2008	(r185850)
@@ -0,0 +1,72 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libutil.h"
+
+struct kinfo_vmentry *
+kinfo_getvmmap(pid_t pid, int *cntp)
+{
+	int mib[4];
+	int error;
+	int cnt;
+	size_t len;
+	char *buf, *bp, *eb;
+	struct kinfo_vmentry *kiv, *kp, *kv;
+
+	len = 0;
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_PROC;
+	mib[2] = KERN_PROC_VMMAP;
+	mib[3] = pid;
+
+	error = sysctl(mib, 4, NULL, &len, NULL, 0);
+	if (error)
+		return (0);
+	len = len * 4 / 3;
+	buf = malloc(len);
+	if (buf == NULL)
+		return (0);
+	error = sysctl(mib, 4, buf, &len, NULL, 0);
+	if (error) {
+		free(buf);
+		return (0);
+	}
+	/* Pass 1: count items */
+	cnt = 0;
+	bp = buf;
+	eb = buf + len;
+	while (bp < eb) {
+		kv = (struct kinfo_vmentry *)(uintptr_t)bp;
+		bp += kv->kve_structsize;
+		cnt++;
+	}
+
+	kiv = calloc(cnt, sizeof(*kiv));
+	if (kiv == NULL) {
+		free(buf);
+		return (0);
+	}
+	bp = buf;
+	eb = buf + len;
+	kp = kiv;
+	/* Pass 2: unpack */
+	while (bp < eb) {
+		kv = (struct kinfo_vmentry *)(uintptr_t)bp;
+		/* Copy/expand into pre-zeroed buffer */
+		memcpy(kp, kv, kv->kve_structsize);
+		/* Advance to next packed record */
+		bp += kv->kve_structsize;
+		/* Set field size to fixed length, advance */
+		kp->kve_structsize = sizeof(*kp);
+		kp++;
+	}
+	free(buf);
+	*cntp = cnt;
+	return (kiv);	/* Caller must free() return value */
+}

Modified: projects/releng_7_xen/lib/libutil/libutil.h
==============================================================================
--- projects/releng_7_xen/lib/libutil/libutil.h	Wed Dec 10 09:21:52 2008	(r185849)
+++ projects/releng_7_xen/lib/libutil/libutil.h	Wed Dec 10 10:12:04 2008	(r185850)
@@ -64,6 +64,8 @@ struct termios;
 struct winsize;
 struct utmp;
 struct in_addr;
+struct kinfo_file;
+struct kinfo_vmentry;
 
 __BEGIN_DECLS
 void	clean_environment(const char * const *_white,
@@ -99,6 +101,10 @@ int	realhostname_sa(char *host, size_t h
 
 int	kld_isloaded(const char *name);
 int	kld_load(const char *name);
+struct kinfo_file *
+	kinfo_getfile(pid_t _pid, int *_cntp);
+struct kinfo_vmentry *
+	kinfo_getvmmap(pid_t _pid, int *_cntp);
 
 #ifdef _STDIO_H_	/* avoid adding new includes */
 char   *fparseln(FILE *, size_t *, size_t *, const char[3], int);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list