17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 56fec3625Sdduvall * Common Development and Distribution License (the "License"). 66fec3625Sdduvall * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 216fec3625Sdduvall 227c478bd9Sstevel@tonic-gate /* 236fec3625Sdduvall * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <stdio.h> 287c478bd9Sstevel@tonic-gate #include <sys/param.h> 297c478bd9Sstevel@tonic-gate #include <fcntl.h> 307c478bd9Sstevel@tonic-gate #include <stdlib.h> 317c478bd9Sstevel@tonic-gate #include <strings.h> 327c478bd9Sstevel@tonic-gate #include <errno.h> 337c478bd9Sstevel@tonic-gate #include <dirent.h> 347c478bd9Sstevel@tonic-gate #include <sys/stat.h> 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include "list.h" 377c478bd9Sstevel@tonic-gate #include "protodir.h" 387c478bd9Sstevel@tonic-gate #include "arch.h" 397c478bd9Sstevel@tonic-gate #include "exception_list.h" 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #define FS " \t\n" 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate static char * 447c478bd9Sstevel@tonic-gate resolve_relative(const char *source, const char *link) 457c478bd9Sstevel@tonic-gate { 467c478bd9Sstevel@tonic-gate char *p; 477c478bd9Sstevel@tonic-gate char *l_next; 487c478bd9Sstevel@tonic-gate char *l_pos; 497c478bd9Sstevel@tonic-gate static char curpath[MAXPATHLEN]; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* if absolute path - no relocation required */ 527c478bd9Sstevel@tonic-gate if (link[0] == '/') 537c478bd9Sstevel@tonic-gate return (strcpy(curpath, link)); 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate (void) strcpy(curpath, source); 567c478bd9Sstevel@tonic-gate p = rindex(curpath, '/'); 577c478bd9Sstevel@tonic-gate *p = '\0'; 587c478bd9Sstevel@tonic-gate l_pos = (char *)link; 597c478bd9Sstevel@tonic-gate do { 607c478bd9Sstevel@tonic-gate l_next = index(l_pos, '/'); 617c478bd9Sstevel@tonic-gate if (strncmp(l_pos, "../", 3) == 0) { 627c478bd9Sstevel@tonic-gate if ((p = rindex(curpath, '/')) != NULL) 637c478bd9Sstevel@tonic-gate *p = '\0'; 647c478bd9Sstevel@tonic-gate else 657c478bd9Sstevel@tonic-gate curpath[0] = '\0'; 667c478bd9Sstevel@tonic-gate } else if (strncmp(l_pos, "./", 2)) { 677c478bd9Sstevel@tonic-gate /* if not . then we process */ 687c478bd9Sstevel@tonic-gate if (curpath[0]) 697c478bd9Sstevel@tonic-gate (void) strcat(curpath, "/"); 707c478bd9Sstevel@tonic-gate if (l_next) { 717c478bd9Sstevel@tonic-gate (void) strncat(curpath, l_pos, 727c478bd9Sstevel@tonic-gate (l_next - l_pos)); 737c478bd9Sstevel@tonic-gate } else 747c478bd9Sstevel@tonic-gate (void) strcat(curpath, l_pos); 757c478bd9Sstevel@tonic-gate } 767c478bd9Sstevel@tonic-gate l_pos = l_next + 1; 777c478bd9Sstevel@tonic-gate } while (l_next); 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate return (curpath); 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate static int 847c478bd9Sstevel@tonic-gate parse_proto_line(const char *basedir, char *line, elem_list *list, short arch, 857c478bd9Sstevel@tonic-gate const char *pkgname) 867c478bd9Sstevel@tonic-gate { 877c478bd9Sstevel@tonic-gate char *type, *class, *file, *src, *maj, *min, *perm, *owner, *group; 887c478bd9Sstevel@tonic-gate char p_line[BUFSIZ]; 897c478bd9Sstevel@tonic-gate elem *dup; 907c478bd9Sstevel@tonic-gate static elem *e = NULL; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate (void) strcpy(p_line, line); 937c478bd9Sstevel@tonic-gate if (!e) 947c478bd9Sstevel@tonic-gate e = (elem *)calloc(1, sizeof (elem)); 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate e->flag = 0; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate if (!(type = strtok(p_line, FS))) { 997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "error: bad line(type) : %s\n", line); 1007c478bd9Sstevel@tonic-gate return (-1); 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate e->file_type = type[0]; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate if ((class = strtok(NULL, FS)) == NULL) { 1067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "error: bad line(class) : %s\n", line); 1077c478bd9Sstevel@tonic-gate return (-1); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate /* 1117c478bd9Sstevel@tonic-gate * Just ignore 'legacy' entries. These are not present in the proto 1127c478bd9Sstevel@tonic-gate * area at all. They're phantoms. 1137c478bd9Sstevel@tonic-gate */ 1147c478bd9Sstevel@tonic-gate if (strcmp(class, "legacy") == 0) 1157c478bd9Sstevel@tonic-gate return (0); 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate if (!(file = strtok(NULL, FS))) { 1187c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "error: bad line(file_name) : %s\n", 1197c478bd9Sstevel@tonic-gate line); 1207c478bd9Sstevel@tonic-gate return (-1); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate e->symsrc = NULL; 1247c478bd9Sstevel@tonic-gate if ((src = index(file, '=')) != NULL) { 1257c478bd9Sstevel@tonic-gate /* 1267c478bd9Sstevel@tonic-gate * The '=' operator is subtly different for link and non-link 1277c478bd9Sstevel@tonic-gate * entries. For the hard or soft link case, the left hand side 1286fec3625Sdduvall * exists in the proto area and is created by the package. 1296fec3625Sdduvall * 1306fec3625Sdduvall * When the file is an editable file, it's very likely that the 1316fec3625Sdduvall * right hand side is only a fragment of that file, which is 1326fec3625Sdduvall * delivered by multiple packages in the consolidation. Thus it 1336fec3625Sdduvall * can't exist in the proto area, and because we can't really 1346fec3625Sdduvall * know where the file's root directory is, we should skip the 1356fec3625Sdduvall * file. 1366fec3625Sdduvall * 1376fec3625Sdduvall * For all other filetypes, assume the right hand side is in the 1386fec3625Sdduvall * proto area. 1397c478bd9Sstevel@tonic-gate */ 1407c478bd9Sstevel@tonic-gate if (e->file_type == SYM_LINK_T || e->file_type == LINK_T) { 1417c478bd9Sstevel@tonic-gate *src++ = '\0'; 1427c478bd9Sstevel@tonic-gate e->symsrc = strdup(src); 1436fec3625Sdduvall } else if (e->file_type == EDIT_T) { 1446fec3625Sdduvall return (0); 1457c478bd9Sstevel@tonic-gate } else { 1467c478bd9Sstevel@tonic-gate file = src + 1; 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate /* 1517c478bd9Sstevel@tonic-gate * if a basedir has a value, prepend it to the filename 1527c478bd9Sstevel@tonic-gate */ 1537c478bd9Sstevel@tonic-gate if (basedir[0]) 1547c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(e->name, basedir), "/"), file); 1557c478bd9Sstevel@tonic-gate else 1567c478bd9Sstevel@tonic-gate (void) strcpy(e->name, file); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate if (e->file_type != SYM_LINK_T) { 1597c478bd9Sstevel@tonic-gate if ((e->file_type == CHAR_DEV_T) || 1607c478bd9Sstevel@tonic-gate (e->file_type == BLOCK_DEV_T)) { 1617c478bd9Sstevel@tonic-gate if (!(maj = strtok(NULL, FS))) { 1627c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1637c478bd9Sstevel@tonic-gate "error: bad line(major number) : %s\n", 1647c478bd9Sstevel@tonic-gate line); 1657c478bd9Sstevel@tonic-gate return (-1); 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate e->major = atoi(maj); 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate if (!(min = strtok(NULL, FS))) { 1707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1717c478bd9Sstevel@tonic-gate "error: bad line(minor number) : %s\n", 1727c478bd9Sstevel@tonic-gate line); 1737c478bd9Sstevel@tonic-gate return (-1); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate e->minor = atoi(min); 1767c478bd9Sstevel@tonic-gate } else { 1777c478bd9Sstevel@tonic-gate e->major = -1; 1787c478bd9Sstevel@tonic-gate e->minor = -1; 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate if (!(perm = strtok(NULL, FS))) { 1827c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1837c478bd9Sstevel@tonic-gate "error: bad line(permission) : %s\n", line); 1847c478bd9Sstevel@tonic-gate return (-1); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate e->perm = strtol(perm, NULL, 8); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate if (!(owner = strtok(NULL, FS))) { 1897c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1907c478bd9Sstevel@tonic-gate "error: bad line(owner) : %s\n", line); 1917c478bd9Sstevel@tonic-gate return (-1); 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate (void) strcpy(e->owner, owner); 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate if (!(group = strtok(NULL, FS))) { 1967c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1977c478bd9Sstevel@tonic-gate "error: bad line(group) : %s\n", line); 1987c478bd9Sstevel@tonic-gate return (-1); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate (void) strcpy(e->group, group); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate e->inode = 0; 2047c478bd9Sstevel@tonic-gate e->ref_cnt = 1; 2057c478bd9Sstevel@tonic-gate e->arch = arch; 2067c478bd9Sstevel@tonic-gate e->link_parent = NULL; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate if (!(dup = find_elem(list, e, FOLLOW_LINK))) { 2097c478bd9Sstevel@tonic-gate e->pkgs = add_pkg(NULL, pkgname); /* init pkgs list */ 2107c478bd9Sstevel@tonic-gate add_elem(list, e); 2117c478bd9Sstevel@tonic-gate e = NULL; 2127c478bd9Sstevel@tonic-gate return (1); 2137c478bd9Sstevel@tonic-gate } else if (dup->file_type == DIR_T) { 2147c478bd9Sstevel@tonic-gate if (!(dup->pkgs = add_pkg(dup->pkgs, pkgname))) { 2157c478bd9Sstevel@tonic-gate /* add entry to pkgs */ 2167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2177c478bd9Sstevel@tonic-gate "warning: %s: Duplicate entry for %s\n", 2187c478bd9Sstevel@tonic-gate pkgname, dup->name); 2197c478bd9Sstevel@tonic-gate return (-1); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate if (e->perm != dup->perm) { 2227c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2237c478bd9Sstevel@tonic-gate "warning: %s: permissions %#o of %s do not match " 2247c478bd9Sstevel@tonic-gate "previous permissions %#o\n", 2257c478bd9Sstevel@tonic-gate pkgname, e->perm, dup->name, dup->perm); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate if (strcmp(e->owner, dup->owner) != 0) { 2287c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2297c478bd9Sstevel@tonic-gate "warning: %s: owner \"%s\" of %s does not match " 2307c478bd9Sstevel@tonic-gate "previous owner \"%s\"\n", 2317c478bd9Sstevel@tonic-gate pkgname, e->owner, dup->name, dup->owner); 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate if (strcmp(e->group, dup->group) != 0) { 2347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2357c478bd9Sstevel@tonic-gate "warning: %s: group \"%s\" of %s does not match " 2367c478bd9Sstevel@tonic-gate "previous group \"%s\"\n", 2377c478bd9Sstevel@tonic-gate pkgname, e->group, dup->name, dup->group); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate } else { 2407c478bd9Sstevel@tonic-gate /* 2417c478bd9Sstevel@tonic-gate * Signal an error only if this is something that's not on the 2427c478bd9Sstevel@tonic-gate * exception list. 2437c478bd9Sstevel@tonic-gate */ 2447c478bd9Sstevel@tonic-gate (void) strcpy(e->name, file); 2457c478bd9Sstevel@tonic-gate if (find_elem(&exception_list, e, FOLLOW_LINK) == NULL) { 2467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2477c478bd9Sstevel@tonic-gate "warning: %s: duplicate entry for %s - ignored\n", 2487c478bd9Sstevel@tonic-gate pkgname, e->name); 2497c478bd9Sstevel@tonic-gate return (-1); 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate return (0); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate static int 2577c478bd9Sstevel@tonic-gate parse_proto_link(const char *basedir, char *line, elem_list *list, short arch, 2587c478bd9Sstevel@tonic-gate const char *pkgname) 2597c478bd9Sstevel@tonic-gate { 2607c478bd9Sstevel@tonic-gate char *type, *file, *src; 2617c478bd9Sstevel@tonic-gate char p_line[BUFSIZ]; 2627c478bd9Sstevel@tonic-gate elem *p, *dup; 2637c478bd9Sstevel@tonic-gate elem key; 2647c478bd9Sstevel@tonic-gate static elem *e = NULL; 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate (void) strcpy(p_line, line); 2687c478bd9Sstevel@tonic-gate if (!e) 2697c478bd9Sstevel@tonic-gate e = (elem *)calloc(1, sizeof (elem)); 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate e->flag = 0; 2727c478bd9Sstevel@tonic-gate type = strtok(p_line, FS); 2737c478bd9Sstevel@tonic-gate e->arch = arch; 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate e->file_type = type[0]; 2767c478bd9Sstevel@tonic-gate (void) strtok(NULL, FS); /* burn class */ 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate file = strtok(NULL, FS); 2797c478bd9Sstevel@tonic-gate if ((src = index(file, '=')) != NULL) { 2807c478bd9Sstevel@tonic-gate *src++ = '\0'; 2817c478bd9Sstevel@tonic-gate e->symsrc = strdup(src); 2827c478bd9Sstevel@tonic-gate } else { 2837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2847c478bd9Sstevel@tonic-gate "error: %s: hard link does not have destination (%s)\n", 2857c478bd9Sstevel@tonic-gate pkgname, file); 2867c478bd9Sstevel@tonic-gate return (0); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate /* 2907c478bd9Sstevel@tonic-gate * if a basedir has a value, prepend it to the filename 2917c478bd9Sstevel@tonic-gate */ 2927c478bd9Sstevel@tonic-gate if (basedir[0]) 2937c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(e->name, basedir), "/"), file); 2947c478bd9Sstevel@tonic-gate else 2957c478bd9Sstevel@tonic-gate (void) strcpy(e->name, file); 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate /* 2987c478bd9Sstevel@tonic-gate * now we need to find the file that we link to - to do this 2997c478bd9Sstevel@tonic-gate * we build a key. 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate src = resolve_relative(e->name, e->symsrc); 3037c478bd9Sstevel@tonic-gate (void) strcpy(key.name, src); 3047c478bd9Sstevel@tonic-gate key.arch = e->arch; 3057c478bd9Sstevel@tonic-gate if ((p = find_elem(list, &key, NO_FOLLOW_LINK)) == NULL) { 3067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3077c478bd9Sstevel@tonic-gate "error: %s: hardlink to non-existent file: %s=%s\n", 3087c478bd9Sstevel@tonic-gate pkgname, e->name, e->symsrc); 3097c478bd9Sstevel@tonic-gate return (0); 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate if ((p->file_type == SYM_LINK_T) || (p->file_type == LINK_T)) { 3127c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3137c478bd9Sstevel@tonic-gate "error: %s: hardlink must link to a file or directory " 3147c478bd9Sstevel@tonic-gate "(not other links): %s=%s\n", pkgname, e->name, p->name); 3157c478bd9Sstevel@tonic-gate return (0); 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate e->link_parent = p; 3187c478bd9Sstevel@tonic-gate e->link_sib = p->link_sib; 3197c478bd9Sstevel@tonic-gate p->link_sib = e; 3207c478bd9Sstevel@tonic-gate p->ref_cnt++; 3217c478bd9Sstevel@tonic-gate e->inode = p->inode; 3227c478bd9Sstevel@tonic-gate e->perm = p->perm; 3237c478bd9Sstevel@tonic-gate e->ref_cnt = p->ref_cnt; 3247c478bd9Sstevel@tonic-gate e->major = p->major; 3257c478bd9Sstevel@tonic-gate e->minor = p->minor; 3267c478bd9Sstevel@tonic-gate (void) strcpy(e->owner, p->owner); 3277c478bd9Sstevel@tonic-gate (void) strcpy(e->group, p->owner); 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate if (!(dup = find_elem(list, e, NO_FOLLOW_LINK))) { 3307c478bd9Sstevel@tonic-gate e->pkgs = add_pkg(NULL, pkgname); /* init pkgs list */ 3317c478bd9Sstevel@tonic-gate e->link_sib = NULL; 3327c478bd9Sstevel@tonic-gate add_elem(list, e); 3337c478bd9Sstevel@tonic-gate e = NULL; 3347c478bd9Sstevel@tonic-gate return (1); 3357c478bd9Sstevel@tonic-gate } else { 3367c478bd9Sstevel@tonic-gate /* 3377c478bd9Sstevel@tonic-gate * Signal an error only if this is something that's not on the 3387c478bd9Sstevel@tonic-gate * exception list. 3397c478bd9Sstevel@tonic-gate */ 3407c478bd9Sstevel@tonic-gate (void) strcpy(e->name, file); 3417c478bd9Sstevel@tonic-gate if (find_elem(&exception_list, e, FOLLOW_LINK) == NULL) { 3427c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3437c478bd9Sstevel@tonic-gate "warning: %s: duplicate entry for %s - ignored\n", 3447c478bd9Sstevel@tonic-gate pkgname, e->name); 3457c478bd9Sstevel@tonic-gate return (-1); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate return (0); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate /* 3547c478bd9Sstevel@tonic-gate * open up the pkginfo file and find the ARCH= and the BASEDIR= macros. 3557c478bd9Sstevel@tonic-gate * I will set the arch and basedir variables based on these fields. 3567c478bd9Sstevel@tonic-gate */ 3577c478bd9Sstevel@tonic-gate static void 3587c478bd9Sstevel@tonic-gate read_pkginfo(const char *protodir, short *arch, char *basedir) 3597c478bd9Sstevel@tonic-gate { 3607c478bd9Sstevel@tonic-gate char pkginfofile[MAXPATHLEN]; 3617c478bd9Sstevel@tonic-gate char architecture[MAXPATHLEN]; 3627c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 3637c478bd9Sstevel@tonic-gate FILE *pkginfo_fp; 3647c478bd9Sstevel@tonic-gate int hits = 0; 3657c478bd9Sstevel@tonic-gate int i; 3667c478bd9Sstevel@tonic-gate int index; 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate architecture[0] = '\0'; 3707c478bd9Sstevel@tonic-gate basedir[0] = '\0'; 3717c478bd9Sstevel@tonic-gate *arch = P_ISA; 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate /* 3747c478bd9Sstevel@tonic-gate * determine whether the pkginfo file is a pkginfo.tmpl or 3757c478bd9Sstevel@tonic-gate * a pkginfo file 3767c478bd9Sstevel@tonic-gate */ 3777c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(pkginfofile, protodir), "/"), 3787c478bd9Sstevel@tonic-gate "pkginfo.tmpl"); 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate if ((pkginfo_fp = fopen(pkginfofile, "r")) == NULL) { 3817c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(pkginfofile, protodir), "/"), 3827c478bd9Sstevel@tonic-gate "pkginfo"); 3837c478bd9Sstevel@tonic-gate if ((pkginfo_fp = fopen(pkginfofile, "r")) == NULL) { 3847c478bd9Sstevel@tonic-gate perror(pkginfofile); 3857c478bd9Sstevel@tonic-gate return; 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate while (fgets(buf, BUFSIZ, pkginfo_fp) && (hits != 3)) { 3917c478bd9Sstevel@tonic-gate if (strncmp(buf, "ARCH=", 5) == 0) { 3927c478bd9Sstevel@tonic-gate index = 0; 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * remove any '"' in the ARCH field. 3957c478bd9Sstevel@tonic-gate */ 3967c478bd9Sstevel@tonic-gate for (i = 5; buf[i]; i++) { 3977c478bd9Sstevel@tonic-gate if (buf[i] != '"') 3987c478bd9Sstevel@tonic-gate architecture[index++] = buf[i]; 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate /* -1 because above copy included '\n' */ 4017c478bd9Sstevel@tonic-gate architecture[index-1] = '\0'; 4027c478bd9Sstevel@tonic-gate hits += 1; 4037c478bd9Sstevel@tonic-gate } else if (strncmp(buf, "BASEDIR=", 8) == 0) { 4047c478bd9Sstevel@tonic-gate index = 0; 4057c478bd9Sstevel@tonic-gate /* 4067c478bd9Sstevel@tonic-gate * remove any '"' in the BASEDIR field, and 4077c478bd9Sstevel@tonic-gate * strip off a leading '/' if present. 4087c478bd9Sstevel@tonic-gate */ 4097c478bd9Sstevel@tonic-gate for (i = 8; buf[i]; i++) { 4107c478bd9Sstevel@tonic-gate if (buf[i] != '"' && 4117c478bd9Sstevel@tonic-gate (buf[i] != '/' || index != 0)) { 4127c478bd9Sstevel@tonic-gate buf[index++] = buf[i]; 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate /* -1 because above copy included '\n' */ 4167c478bd9Sstevel@tonic-gate buf[index-1] = '\0'; 4177c478bd9Sstevel@tonic-gate (void) strcpy(basedir, &buf[0]); 4187c478bd9Sstevel@tonic-gate hits += 2; 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate (void) fclose(pkginfo_fp); 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate if (architecture[0]) 424*ed159168SRichard PALO if ((*arch = assign_arch(architecture)) == 0) { 4257c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4267c478bd9Sstevel@tonic-gate "warning: Unknown architecture %s found in %s\n", 4277c478bd9Sstevel@tonic-gate architecture, pkginfofile); 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate } 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate /* 4327c478bd9Sstevel@tonic-gate * The first pass through the prototype file goes through and reads 4337c478bd9Sstevel@tonic-gate * in all the entries except 'hard links'. Those must be processed 4347c478bd9Sstevel@tonic-gate * in a second pass. 4357c478bd9Sstevel@tonic-gate * 4367c478bd9Sstevel@tonic-gate * If any !includes are found in the prototype file this routine 4377c478bd9Sstevel@tonic-gate * will be called recursively. 4387c478bd9Sstevel@tonic-gate * 4397c478bd9Sstevel@tonic-gate * Args: 4407c478bd9Sstevel@tonic-gate * protofile - full pathname to prototype file to be processed. 4417c478bd9Sstevel@tonic-gate * protodir - directory in which prototype file resides. 4427c478bd9Sstevel@tonic-gate * list - list to which elements will be added 4437c478bd9Sstevel@tonic-gate * arch - architecture of current prototype 4447c478bd9Sstevel@tonic-gate * basedir - basedir for package 4457c478bd9Sstevel@tonic-gate * pkgname - name of package 4467c478bd9Sstevel@tonic-gate * 4477c478bd9Sstevel@tonic-gate * Returns: 4487c478bd9Sstevel@tonic-gate * returns number of items added to list. 4497c478bd9Sstevel@tonic-gate * 4507c478bd9Sstevel@tonic-gate */ 4517c478bd9Sstevel@tonic-gate static int 4527c478bd9Sstevel@tonic-gate first_pass_prototype(const char *protofile, const char *protodir, 4537c478bd9Sstevel@tonic-gate elem_list *list, short arch, const char *basedir, const char *pkgname) 4547c478bd9Sstevel@tonic-gate { 4557c478bd9Sstevel@tonic-gate int elem_count = 0; 4567c478bd9Sstevel@tonic-gate FILE *proto_fp; 4577c478bd9Sstevel@tonic-gate char include_file[MAXPATHLEN]; 4587c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate if ((proto_fp = fopen(protofile, "r")) == NULL) { 4617c478bd9Sstevel@tonic-gate perror(protofile); 4627c478bd9Sstevel@tonic-gate return (0); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate /* 4667c478bd9Sstevel@tonic-gate * first pass through file - process everything but 4677c478bd9Sstevel@tonic-gate * hard links. 4687c478bd9Sstevel@tonic-gate */ 4697c478bd9Sstevel@tonic-gate while (fgets(buf, BUFSIZ, proto_fp)) { 4707c478bd9Sstevel@tonic-gate int rc; 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate switch (buf[0]) { 4737c478bd9Sstevel@tonic-gate case FILE_T: 4747c478bd9Sstevel@tonic-gate case EDIT_T: 4757c478bd9Sstevel@tonic-gate case VOLATILE_T: 4767c478bd9Sstevel@tonic-gate case DIR_T: 4777c478bd9Sstevel@tonic-gate case SYM_LINK_T: 4787c478bd9Sstevel@tonic-gate case CHAR_DEV_T: 4797c478bd9Sstevel@tonic-gate case BLOCK_DEV_T: 4807c478bd9Sstevel@tonic-gate if ((rc = parse_proto_line(basedir, buf, list, arch, 4817c478bd9Sstevel@tonic-gate pkgname)) >= 0) { 4827c478bd9Sstevel@tonic-gate elem_count += rc; 4837c478bd9Sstevel@tonic-gate } else { 4847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4857c478bd9Sstevel@tonic-gate "error: Errors found in %s\n", protofile); 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate break; 4887c478bd9Sstevel@tonic-gate case LINK_T: 4897c478bd9Sstevel@tonic-gate case 'i': 4907c478bd9Sstevel@tonic-gate case '#': 4917c478bd9Sstevel@tonic-gate case '\n': 4927c478bd9Sstevel@tonic-gate break; 4937c478bd9Sstevel@tonic-gate case '!': 4947c478bd9Sstevel@tonic-gate /* Is this an include statement - if so process */ 4957c478bd9Sstevel@tonic-gate if (strncmp(buf, "!include", 8) == 0) { 4967c478bd9Sstevel@tonic-gate char *inc_file = (char *)(buf + 9); 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate /* burn white space */ 4997c478bd9Sstevel@tonic-gate while ((*inc_file == ' ') || 5007c478bd9Sstevel@tonic-gate (*inc_file == '\t')) 5017c478bd9Sstevel@tonic-gate inc_file++; 5027c478bd9Sstevel@tonic-gate if (*inc_file) { 5037c478bd9Sstevel@tonic-gate /* remove trailing \n */ 5047c478bd9Sstevel@tonic-gate inc_file[strlen(inc_file) - 1] = '\0'; 5057c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy( 5067c478bd9Sstevel@tonic-gate include_file, protodir), "/"), 5077c478bd9Sstevel@tonic-gate inc_file); 5087c478bd9Sstevel@tonic-gate elem_count += 5097c478bd9Sstevel@tonic-gate first_pass_prototype(include_file, 5107c478bd9Sstevel@tonic-gate protodir, list, arch, basedir, 5117c478bd9Sstevel@tonic-gate pkgname); 5127c478bd9Sstevel@tonic-gate } else { 5137c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5147c478bd9Sstevel@tonic-gate "warning: bad !include statement " 5157c478bd9Sstevel@tonic-gate "in prototype %s : %s\n", 5167c478bd9Sstevel@tonic-gate protofile, buf); 5177c478bd9Sstevel@tonic-gate } 5187c478bd9Sstevel@tonic-gate } else { 5197c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5207c478bd9Sstevel@tonic-gate "warning: unexpected ! notation in " 5217c478bd9Sstevel@tonic-gate "prototype %s : %s\n", protofile, buf); 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate break; 5257c478bd9Sstevel@tonic-gate default: 5267c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5277c478bd9Sstevel@tonic-gate "warning: unexpected line in prototype %s : %s\n", 5287c478bd9Sstevel@tonic-gate protofile, buf); 5297c478bd9Sstevel@tonic-gate break; 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate (void) fclose(proto_fp); 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate return (elem_count); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate /* 5397c478bd9Sstevel@tonic-gate * The second pass through the prototype file goes through and reads 5407c478bd9Sstevel@tonic-gate * and processes only the 'hard links' in the prototype file. These 5417c478bd9Sstevel@tonic-gate * are resolved and added accordingly to the elements list(list). 5427c478bd9Sstevel@tonic-gate * 5437c478bd9Sstevel@tonic-gate * If any !includes are found in the prototype file this routine 5447c478bd9Sstevel@tonic-gate * will be called recursively. 5457c478bd9Sstevel@tonic-gate * 5467c478bd9Sstevel@tonic-gate * Args: 5477c478bd9Sstevel@tonic-gate * protofile - full pathname to prototype file to be processed. 5487c478bd9Sstevel@tonic-gate * protodir - directory in which prototype file resides. 5497c478bd9Sstevel@tonic-gate * list - list to which elements will be added 5507c478bd9Sstevel@tonic-gate * arch - architecture of current prototype 5517c478bd9Sstevel@tonic-gate * basedir - basedir for package 5527c478bd9Sstevel@tonic-gate * pkgname - package name 5537c478bd9Sstevel@tonic-gate * 5547c478bd9Sstevel@tonic-gate * Returns: 5557c478bd9Sstevel@tonic-gate * returns number of items added to list. 5567c478bd9Sstevel@tonic-gate * 5577c478bd9Sstevel@tonic-gate */ 5587c478bd9Sstevel@tonic-gate static int 5597c478bd9Sstevel@tonic-gate second_pass_prototype(const char *protofile, const char *protodir, 5607c478bd9Sstevel@tonic-gate elem_list *list, short arch, const char *basedir, const char *pkgname) 5617c478bd9Sstevel@tonic-gate { 5627c478bd9Sstevel@tonic-gate FILE *proto_fp; 5637c478bd9Sstevel@tonic-gate int elem_count = 0; 5647c478bd9Sstevel@tonic-gate char include_file[MAXPATHLEN]; 5657c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate if ((proto_fp = fopen(protofile, "r")) == NULL) { 5687c478bd9Sstevel@tonic-gate perror(protofile); 5697c478bd9Sstevel@tonic-gate return (0); 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate /* 5737c478bd9Sstevel@tonic-gate * second pass through prototype file - process the hard links 5747c478bd9Sstevel@tonic-gate * now. 5757c478bd9Sstevel@tonic-gate */ 5767c478bd9Sstevel@tonic-gate while (fgets(buf, BUFSIZ, proto_fp)) 5777c478bd9Sstevel@tonic-gate if (buf[0] == LINK_T) { 5787c478bd9Sstevel@tonic-gate int rc; 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate if ((rc = parse_proto_link(basedir, buf, list, arch, 5817c478bd9Sstevel@tonic-gate pkgname)) >= 0) { 5827c478bd9Sstevel@tonic-gate elem_count += rc; 5837c478bd9Sstevel@tonic-gate } else { 5847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 5857c478bd9Sstevel@tonic-gate "error: Errors found in %s\n", protofile); 5867c478bd9Sstevel@tonic-gate } 5877c478bd9Sstevel@tonic-gate } else if (strncmp(buf, "!include", 8) == 0) { 5887c478bd9Sstevel@tonic-gate /* 5897c478bd9Sstevel@tonic-gate * This is a file to include 5907c478bd9Sstevel@tonic-gate */ 5917c478bd9Sstevel@tonic-gate char *inc_file = (char *)(buf + 9); 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate /* burn white space */ 5947c478bd9Sstevel@tonic-gate while ((*inc_file == ' ') || (*inc_file == '\t')) 5957c478bd9Sstevel@tonic-gate inc_file++; 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate if (*inc_file) { 5987c478bd9Sstevel@tonic-gate /* remove trailing \n */ 5997c478bd9Sstevel@tonic-gate inc_file[strlen(inc_file) - 1] = '\0'; 6007c478bd9Sstevel@tonic-gate /* build up include file name to be opened. */ 6017c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(include_file, 6027c478bd9Sstevel@tonic-gate protodir), "/"), inc_file); 6037c478bd9Sstevel@tonic-gate /* 6047c478bd9Sstevel@tonic-gate * recursively call this routine to process the 6057c478bd9Sstevel@tonic-gate * !include file. 6067c478bd9Sstevel@tonic-gate */ 6077c478bd9Sstevel@tonic-gate elem_count += 6087c478bd9Sstevel@tonic-gate second_pass_prototype(include_file, 6097c478bd9Sstevel@tonic-gate protodir, list, arch, basedir, pkgname); 6107c478bd9Sstevel@tonic-gate } else { 6117c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 6127c478bd9Sstevel@tonic-gate "warning: Bad !include statement in " 6137c478bd9Sstevel@tonic-gate "prototype %s : %s\n", protofile, buf); 6147c478bd9Sstevel@tonic-gate } 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate (void) fclose(proto_fp); 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate return (elem_count); 6207c478bd9Sstevel@tonic-gate } 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate /* 6237c478bd9Sstevel@tonic-gate * Args: 6247c478bd9Sstevel@tonic-gate * pkgname - name of package being processed 6257c478bd9Sstevel@tonic-gate * protodir - pathname to package defs directory 6267c478bd9Sstevel@tonic-gate * list - List of elements read in, elements are added to this 6277c478bd9Sstevel@tonic-gate * as they are read in. 6287c478bd9Sstevel@tonic-gate * verbose - verbose output 6297c478bd9Sstevel@tonic-gate * 6307c478bd9Sstevel@tonic-gate * Returns: 6317c478bd9Sstevel@tonic-gate * number of elements added to list 6327c478bd9Sstevel@tonic-gate */ 6337c478bd9Sstevel@tonic-gate int 6347c478bd9Sstevel@tonic-gate process_package_dir(const char *pkgname, const char *protodir, 6357c478bd9Sstevel@tonic-gate elem_list *list, int verbose) 6367c478bd9Sstevel@tonic-gate { 6377c478bd9Sstevel@tonic-gate struct stat st_buf; 6387c478bd9Sstevel@tonic-gate char protofile[MAXPATHLEN]; 6397c478bd9Sstevel@tonic-gate char basedir[MAXPATHLEN]; 6407c478bd9Sstevel@tonic-gate short arch; 6417c478bd9Sstevel@tonic-gate int count = 0; 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate /* 6457c478bd9Sstevel@tonic-gate * skip any packages we've already handled (because of 6467c478bd9Sstevel@tonic-gate * dependencies) 6477c478bd9Sstevel@tonic-gate */ 6487c478bd9Sstevel@tonic-gate if (processed_package(pkgname)) { 6497c478bd9Sstevel@tonic-gate return (0); 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate /* 6537c478bd9Sstevel@tonic-gate * find the prototype file. Legal forms of the name are: 6547c478bd9Sstevel@tonic-gate * prototype 6557c478bd9Sstevel@tonic-gate * prototype_<mach> (where mach == (sparc || i386 || ppc) 6567c478bd9Sstevel@tonic-gate */ 6577c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(protofile, protodir), "/"), "prototype"); 6587c478bd9Sstevel@tonic-gate if (stat(protofile, &st_buf) < 0) { 6597c478bd9Sstevel@tonic-gate if (errno == ENOENT) { 6607c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcat(strcpy(protofile, 6617c478bd9Sstevel@tonic-gate protodir), "/"), "prototype"), PROTO_EXT); 6627c478bd9Sstevel@tonic-gate if (stat(protofile, &st_buf) < 0) { 6637c478bd9Sstevel@tonic-gate if (errno == ENOENT) { 6647c478bd9Sstevel@tonic-gate if (verbose) { 6657c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 6667c478bd9Sstevel@tonic-gate "warning: no prototype " 6677c478bd9Sstevel@tonic-gate "file found in %s, " 6687c478bd9Sstevel@tonic-gate "skipping...\n", 6697c478bd9Sstevel@tonic-gate protodir); 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate } else 6727c478bd9Sstevel@tonic-gate perror(protofile); 6737c478bd9Sstevel@tonic-gate return (0); 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate } else { 6767c478bd9Sstevel@tonic-gate perror(protofile); 6777c478bd9Sstevel@tonic-gate return (0); 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate mark_processed(pkgname); 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate read_pkginfo(protodir, &arch, basedir); 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate count += first_pass_prototype(protofile, protodir, list, arch, 6867c478bd9Sstevel@tonic-gate basedir, pkgname); 6877c478bd9Sstevel@tonic-gate count += second_pass_prototype(protofile, protodir, list, arch, 6887c478bd9Sstevel@tonic-gate basedir, pkgname); 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate /* print_list(list); */ 6917c478bd9Sstevel@tonic-gate return (count); 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate int 6957c478bd9Sstevel@tonic-gate read_in_protodir(const char *dir_name, elem_list *list, int verbose) 6967c478bd9Sstevel@tonic-gate { 6977c478bd9Sstevel@tonic-gate DIR *p_dir; 6987c478bd9Sstevel@tonic-gate struct dirent *dp; 6997c478bd9Sstevel@tonic-gate char protodir[MAXPATHLEN]; 7007c478bd9Sstevel@tonic-gate struct stat st_buf; 7017c478bd9Sstevel@tonic-gate int count = 0; 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate if ((p_dir = opendir(dir_name)) == NULL) { 7047c478bd9Sstevel@tonic-gate perror(dir_name); 7057c478bd9Sstevel@tonic-gate exit(1); 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate list->type = PROTODIR_LIST; 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate while ((dp = readdir(p_dir)) != NULL) { 7117c478bd9Sstevel@tonic-gate /* 7127c478bd9Sstevel@tonic-gate * let's not check "." and ".." - I don't really like this 7137c478bd9Sstevel@tonic-gate * but I wasn't really sure you could be sure that they 7147c478bd9Sstevel@tonic-gate * are always the first two entries in the directory 7157c478bd9Sstevel@tonic-gate * structure - so I put it in the loop. 7167c478bd9Sstevel@tonic-gate * 7177c478bd9Sstevel@tonic-gate * Also - we skip all directories that are names .del-*. 7187c478bd9Sstevel@tonic-gate * and any SCCS directories too. 7197c478bd9Sstevel@tonic-gate */ 7207c478bd9Sstevel@tonic-gate if ((strcmp(dp->d_name, ".") == 0) || 7217c478bd9Sstevel@tonic-gate (strcmp(dp->d_name, "..") == 0) || 7227c478bd9Sstevel@tonic-gate (strncmp(dp->d_name, ".del-", 5) == 0) || 7237c478bd9Sstevel@tonic-gate (strcmp(dp->d_name, "SCCS") == 0)) 7247c478bd9Sstevel@tonic-gate continue; 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(protodir, dir_name), "/"), 7277c478bd9Sstevel@tonic-gate dp->d_name); 7287c478bd9Sstevel@tonic-gate if (stat(protodir, &st_buf) < 0) { 7297c478bd9Sstevel@tonic-gate perror(protodir); 7307c478bd9Sstevel@tonic-gate continue; 7317c478bd9Sstevel@tonic-gate } 7327c478bd9Sstevel@tonic-gate if (!S_ISDIR(st_buf.st_mode)) { 7337c478bd9Sstevel@tonic-gate if (verbose) { 7347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 7357c478bd9Sstevel@tonic-gate "warning: %s not a directory\n", protodir); 7367c478bd9Sstevel@tonic-gate } 7377c478bd9Sstevel@tonic-gate continue; 7387c478bd9Sstevel@tonic-gate } 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate count += process_dependencies(dp->d_name, dir_name, list, 7417c478bd9Sstevel@tonic-gate verbose); 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate count += process_package_dir(dp->d_name, protodir, list, 7447c478bd9Sstevel@tonic-gate verbose); 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate if (verbose) 7487c478bd9Sstevel@tonic-gate (void) printf("read in %d lines\n", count); 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate (void) closedir(p_dir); 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate return (count); 7537c478bd9Sstevel@tonic-gate } 754