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