1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #include <stdio.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 32*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 33*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 34*7c478bd9Sstevel@tonic-gate #include <strings.h> 35*7c478bd9Sstevel@tonic-gate #include <errno.h> 36*7c478bd9Sstevel@tonic-gate #include <dirent.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #include "list.h" 40*7c478bd9Sstevel@tonic-gate #include "protodir.h" 41*7c478bd9Sstevel@tonic-gate #include "arch.h" 42*7c478bd9Sstevel@tonic-gate #include "exception_list.h" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate #define FS " \t\n" 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate static char * 47*7c478bd9Sstevel@tonic-gate resolve_relative(const char *source, const char *link) 48*7c478bd9Sstevel@tonic-gate { 49*7c478bd9Sstevel@tonic-gate char *p; 50*7c478bd9Sstevel@tonic-gate char *l_next; 51*7c478bd9Sstevel@tonic-gate char *l_pos; 52*7c478bd9Sstevel@tonic-gate static char curpath[MAXPATHLEN]; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate /* if absolute path - no relocation required */ 55*7c478bd9Sstevel@tonic-gate if (link[0] == '/') 56*7c478bd9Sstevel@tonic-gate return (strcpy(curpath, link)); 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate (void) strcpy(curpath, source); 59*7c478bd9Sstevel@tonic-gate p = rindex(curpath, '/'); 60*7c478bd9Sstevel@tonic-gate *p = '\0'; 61*7c478bd9Sstevel@tonic-gate l_pos = (char *)link; 62*7c478bd9Sstevel@tonic-gate do { 63*7c478bd9Sstevel@tonic-gate l_next = index(l_pos, '/'); 64*7c478bd9Sstevel@tonic-gate if (strncmp(l_pos, "../", 3) == 0) { 65*7c478bd9Sstevel@tonic-gate if ((p = rindex(curpath, '/')) != NULL) 66*7c478bd9Sstevel@tonic-gate *p = '\0'; 67*7c478bd9Sstevel@tonic-gate else 68*7c478bd9Sstevel@tonic-gate curpath[0] = '\0'; 69*7c478bd9Sstevel@tonic-gate } else if (strncmp(l_pos, "./", 2)) { 70*7c478bd9Sstevel@tonic-gate /* if not . then we process */ 71*7c478bd9Sstevel@tonic-gate if (curpath[0]) 72*7c478bd9Sstevel@tonic-gate (void) strcat(curpath, "/"); 73*7c478bd9Sstevel@tonic-gate if (l_next) { 74*7c478bd9Sstevel@tonic-gate (void) strncat(curpath, l_pos, 75*7c478bd9Sstevel@tonic-gate (l_next - l_pos)); 76*7c478bd9Sstevel@tonic-gate } else 77*7c478bd9Sstevel@tonic-gate (void) strcat(curpath, l_pos); 78*7c478bd9Sstevel@tonic-gate } 79*7c478bd9Sstevel@tonic-gate l_pos = l_next + 1; 80*7c478bd9Sstevel@tonic-gate } while (l_next); 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate return (curpath); 83*7c478bd9Sstevel@tonic-gate } 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate static int 87*7c478bd9Sstevel@tonic-gate parse_proto_line(const char *basedir, char *line, elem_list *list, short arch, 88*7c478bd9Sstevel@tonic-gate const char *pkgname) 89*7c478bd9Sstevel@tonic-gate { 90*7c478bd9Sstevel@tonic-gate char *type, *class, *file, *src, *maj, *min, *perm, *owner, *group; 91*7c478bd9Sstevel@tonic-gate char p_line[BUFSIZ]; 92*7c478bd9Sstevel@tonic-gate elem *dup; 93*7c478bd9Sstevel@tonic-gate static elem *e = NULL; 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate (void) strcpy(p_line, line); 96*7c478bd9Sstevel@tonic-gate if (!e) 97*7c478bd9Sstevel@tonic-gate e = (elem *)calloc(1, sizeof (elem)); 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate e->flag = 0; 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate if (!(type = strtok(p_line, FS))) { 102*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "error: bad line(type) : %s\n", line); 103*7c478bd9Sstevel@tonic-gate return (-1); 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate e->file_type = type[0]; 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate if ((class = strtok(NULL, FS)) == NULL) { 109*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "error: bad line(class) : %s\n", line); 110*7c478bd9Sstevel@tonic-gate return (-1); 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate /* 114*7c478bd9Sstevel@tonic-gate * Just ignore 'legacy' entries. These are not present in the proto 115*7c478bd9Sstevel@tonic-gate * area at all. They're phantoms. 116*7c478bd9Sstevel@tonic-gate */ 117*7c478bd9Sstevel@tonic-gate if (strcmp(class, "legacy") == 0) 118*7c478bd9Sstevel@tonic-gate return (0); 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate if (!(file = strtok(NULL, FS))) { 121*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "error: bad line(file_name) : %s\n", 122*7c478bd9Sstevel@tonic-gate line); 123*7c478bd9Sstevel@tonic-gate return (-1); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate e->symsrc = NULL; 127*7c478bd9Sstevel@tonic-gate if ((src = index(file, '=')) != NULL) { 128*7c478bd9Sstevel@tonic-gate /* 129*7c478bd9Sstevel@tonic-gate * The '=' operator is subtly different for link and non-link 130*7c478bd9Sstevel@tonic-gate * entries. For the hard or soft link case, the left hand side 131*7c478bd9Sstevel@tonic-gate * exists in the proto area and is created by the package. For 132*7c478bd9Sstevel@tonic-gate * the other cases, the right hand side is in the proto area. 133*7c478bd9Sstevel@tonic-gate */ 134*7c478bd9Sstevel@tonic-gate if (e->file_type == SYM_LINK_T || e->file_type == LINK_T) { 135*7c478bd9Sstevel@tonic-gate *src++ = '\0'; 136*7c478bd9Sstevel@tonic-gate e->symsrc = strdup(src); 137*7c478bd9Sstevel@tonic-gate } else { 138*7c478bd9Sstevel@tonic-gate file = src + 1; 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate /* 143*7c478bd9Sstevel@tonic-gate * if a basedir has a value, prepend it to the filename 144*7c478bd9Sstevel@tonic-gate */ 145*7c478bd9Sstevel@tonic-gate if (basedir[0]) 146*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(e->name, basedir), "/"), file); 147*7c478bd9Sstevel@tonic-gate else 148*7c478bd9Sstevel@tonic-gate (void) strcpy(e->name, file); 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate if (e->file_type != SYM_LINK_T) { 151*7c478bd9Sstevel@tonic-gate if ((e->file_type == CHAR_DEV_T) || 152*7c478bd9Sstevel@tonic-gate (e->file_type == BLOCK_DEV_T)) { 153*7c478bd9Sstevel@tonic-gate if (!(maj = strtok(NULL, FS))) { 154*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 155*7c478bd9Sstevel@tonic-gate "error: bad line(major number) : %s\n", 156*7c478bd9Sstevel@tonic-gate line); 157*7c478bd9Sstevel@tonic-gate return (-1); 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate e->major = atoi(maj); 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate if (!(min = strtok(NULL, FS))) { 162*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 163*7c478bd9Sstevel@tonic-gate "error: bad line(minor number) : %s\n", 164*7c478bd9Sstevel@tonic-gate line); 165*7c478bd9Sstevel@tonic-gate return (-1); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate e->minor = atoi(min); 168*7c478bd9Sstevel@tonic-gate } else { 169*7c478bd9Sstevel@tonic-gate e->major = -1; 170*7c478bd9Sstevel@tonic-gate e->minor = -1; 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate if (!(perm = strtok(NULL, FS))) { 174*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 175*7c478bd9Sstevel@tonic-gate "error: bad line(permission) : %s\n", line); 176*7c478bd9Sstevel@tonic-gate return (-1); 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate e->perm = strtol(perm, NULL, 8); 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate if (!(owner = strtok(NULL, FS))) { 181*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 182*7c478bd9Sstevel@tonic-gate "error: bad line(owner) : %s\n", line); 183*7c478bd9Sstevel@tonic-gate return (-1); 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate (void) strcpy(e->owner, owner); 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate if (!(group = strtok(NULL, FS))) { 188*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 189*7c478bd9Sstevel@tonic-gate "error: bad line(group) : %s\n", line); 190*7c478bd9Sstevel@tonic-gate return (-1); 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate (void) strcpy(e->group, group); 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate e->inode = 0; 196*7c478bd9Sstevel@tonic-gate e->ref_cnt = 1; 197*7c478bd9Sstevel@tonic-gate e->arch = arch; 198*7c478bd9Sstevel@tonic-gate e->link_parent = NULL; 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate if (!(dup = find_elem(list, e, FOLLOW_LINK))) { 201*7c478bd9Sstevel@tonic-gate e->pkgs = add_pkg(NULL, pkgname); /* init pkgs list */ 202*7c478bd9Sstevel@tonic-gate add_elem(list, e); 203*7c478bd9Sstevel@tonic-gate e = NULL; 204*7c478bd9Sstevel@tonic-gate return (1); 205*7c478bd9Sstevel@tonic-gate } else if (dup->file_type == DIR_T) { 206*7c478bd9Sstevel@tonic-gate if (!(dup->pkgs = add_pkg(dup->pkgs, pkgname))) { 207*7c478bd9Sstevel@tonic-gate /* add entry to pkgs */ 208*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 209*7c478bd9Sstevel@tonic-gate "warning: %s: Duplicate entry for %s\n", 210*7c478bd9Sstevel@tonic-gate pkgname, dup->name); 211*7c478bd9Sstevel@tonic-gate return (-1); 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate if (e->perm != dup->perm) { 214*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 215*7c478bd9Sstevel@tonic-gate "warning: %s: permissions %#o of %s do not match " 216*7c478bd9Sstevel@tonic-gate "previous permissions %#o\n", 217*7c478bd9Sstevel@tonic-gate pkgname, e->perm, dup->name, dup->perm); 218*7c478bd9Sstevel@tonic-gate } 219*7c478bd9Sstevel@tonic-gate if (strcmp(e->owner, dup->owner) != 0) { 220*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 221*7c478bd9Sstevel@tonic-gate "warning: %s: owner \"%s\" of %s does not match " 222*7c478bd9Sstevel@tonic-gate "previous owner \"%s\"\n", 223*7c478bd9Sstevel@tonic-gate pkgname, e->owner, dup->name, dup->owner); 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate if (strcmp(e->group, dup->group) != 0) { 226*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 227*7c478bd9Sstevel@tonic-gate "warning: %s: group \"%s\" of %s does not match " 228*7c478bd9Sstevel@tonic-gate "previous group \"%s\"\n", 229*7c478bd9Sstevel@tonic-gate pkgname, e->group, dup->name, dup->group); 230*7c478bd9Sstevel@tonic-gate } 231*7c478bd9Sstevel@tonic-gate } else { 232*7c478bd9Sstevel@tonic-gate /* 233*7c478bd9Sstevel@tonic-gate * Signal an error only if this is something that's not on the 234*7c478bd9Sstevel@tonic-gate * exception list. 235*7c478bd9Sstevel@tonic-gate */ 236*7c478bd9Sstevel@tonic-gate (void) strcpy(e->name, file); 237*7c478bd9Sstevel@tonic-gate if (find_elem(&exception_list, e, FOLLOW_LINK) == NULL) { 238*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 239*7c478bd9Sstevel@tonic-gate "warning: %s: duplicate entry for %s - ignored\n", 240*7c478bd9Sstevel@tonic-gate pkgname, e->name); 241*7c478bd9Sstevel@tonic-gate return (-1); 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate } 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate return (0); 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate static int 249*7c478bd9Sstevel@tonic-gate parse_proto_link(const char *basedir, char *line, elem_list *list, short arch, 250*7c478bd9Sstevel@tonic-gate const char *pkgname) 251*7c478bd9Sstevel@tonic-gate { 252*7c478bd9Sstevel@tonic-gate char *type, *file, *src; 253*7c478bd9Sstevel@tonic-gate char p_line[BUFSIZ]; 254*7c478bd9Sstevel@tonic-gate elem *p, *dup; 255*7c478bd9Sstevel@tonic-gate elem key; 256*7c478bd9Sstevel@tonic-gate static elem *e = NULL; 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate (void) strcpy(p_line, line); 260*7c478bd9Sstevel@tonic-gate if (!e) 261*7c478bd9Sstevel@tonic-gate e = (elem *)calloc(1, sizeof (elem)); 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate e->flag = 0; 264*7c478bd9Sstevel@tonic-gate type = strtok(p_line, FS); 265*7c478bd9Sstevel@tonic-gate e->arch = arch; 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate e->file_type = type[0]; 268*7c478bd9Sstevel@tonic-gate (void) strtok(NULL, FS); /* burn class */ 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate file = strtok(NULL, FS); 271*7c478bd9Sstevel@tonic-gate if ((src = index(file, '=')) != NULL) { 272*7c478bd9Sstevel@tonic-gate *src++ = '\0'; 273*7c478bd9Sstevel@tonic-gate e->symsrc = strdup(src); 274*7c478bd9Sstevel@tonic-gate } else { 275*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 276*7c478bd9Sstevel@tonic-gate "error: %s: hard link does not have destination (%s)\n", 277*7c478bd9Sstevel@tonic-gate pkgname, file); 278*7c478bd9Sstevel@tonic-gate return (0); 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* 282*7c478bd9Sstevel@tonic-gate * if a basedir has a value, prepend it to the filename 283*7c478bd9Sstevel@tonic-gate */ 284*7c478bd9Sstevel@tonic-gate if (basedir[0]) 285*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(e->name, basedir), "/"), file); 286*7c478bd9Sstevel@tonic-gate else 287*7c478bd9Sstevel@tonic-gate (void) strcpy(e->name, file); 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate /* 290*7c478bd9Sstevel@tonic-gate * now we need to find the file that we link to - to do this 291*7c478bd9Sstevel@tonic-gate * we build a key. 292*7c478bd9Sstevel@tonic-gate */ 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate src = resolve_relative(e->name, e->symsrc); 295*7c478bd9Sstevel@tonic-gate (void) strcpy(key.name, src); 296*7c478bd9Sstevel@tonic-gate key.arch = e->arch; 297*7c478bd9Sstevel@tonic-gate if ((p = find_elem(list, &key, NO_FOLLOW_LINK)) == NULL) { 298*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 299*7c478bd9Sstevel@tonic-gate "error: %s: hardlink to non-existent file: %s=%s\n", 300*7c478bd9Sstevel@tonic-gate pkgname, e->name, e->symsrc); 301*7c478bd9Sstevel@tonic-gate return (0); 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate if ((p->file_type == SYM_LINK_T) || (p->file_type == LINK_T)) { 304*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 305*7c478bd9Sstevel@tonic-gate "error: %s: hardlink must link to a file or directory " 306*7c478bd9Sstevel@tonic-gate "(not other links): %s=%s\n", pkgname, e->name, p->name); 307*7c478bd9Sstevel@tonic-gate return (0); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate e->link_parent = p; 310*7c478bd9Sstevel@tonic-gate e->link_sib = p->link_sib; 311*7c478bd9Sstevel@tonic-gate p->link_sib = e; 312*7c478bd9Sstevel@tonic-gate p->ref_cnt++; 313*7c478bd9Sstevel@tonic-gate e->inode = p->inode; 314*7c478bd9Sstevel@tonic-gate e->perm = p->perm; 315*7c478bd9Sstevel@tonic-gate e->ref_cnt = p->ref_cnt; 316*7c478bd9Sstevel@tonic-gate e->major = p->major; 317*7c478bd9Sstevel@tonic-gate e->minor = p->minor; 318*7c478bd9Sstevel@tonic-gate (void) strcpy(e->owner, p->owner); 319*7c478bd9Sstevel@tonic-gate (void) strcpy(e->group, p->owner); 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate if (!(dup = find_elem(list, e, NO_FOLLOW_LINK))) { 322*7c478bd9Sstevel@tonic-gate e->pkgs = add_pkg(NULL, pkgname); /* init pkgs list */ 323*7c478bd9Sstevel@tonic-gate e->link_sib = NULL; 324*7c478bd9Sstevel@tonic-gate add_elem(list, e); 325*7c478bd9Sstevel@tonic-gate e = NULL; 326*7c478bd9Sstevel@tonic-gate return (1); 327*7c478bd9Sstevel@tonic-gate } else { 328*7c478bd9Sstevel@tonic-gate /* 329*7c478bd9Sstevel@tonic-gate * Signal an error only if this is something that's not on the 330*7c478bd9Sstevel@tonic-gate * exception list. 331*7c478bd9Sstevel@tonic-gate */ 332*7c478bd9Sstevel@tonic-gate (void) strcpy(e->name, file); 333*7c478bd9Sstevel@tonic-gate if (find_elem(&exception_list, e, FOLLOW_LINK) == NULL) { 334*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 335*7c478bd9Sstevel@tonic-gate "warning: %s: duplicate entry for %s - ignored\n", 336*7c478bd9Sstevel@tonic-gate pkgname, e->name); 337*7c478bd9Sstevel@tonic-gate return (-1); 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate return (0); 342*7c478bd9Sstevel@tonic-gate } 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate /* 346*7c478bd9Sstevel@tonic-gate * open up the pkginfo file and find the ARCH= and the BASEDIR= macros. 347*7c478bd9Sstevel@tonic-gate * I will set the arch and basedir variables based on these fields. 348*7c478bd9Sstevel@tonic-gate */ 349*7c478bd9Sstevel@tonic-gate static void 350*7c478bd9Sstevel@tonic-gate read_pkginfo(const char *protodir, short *arch, char *basedir) 351*7c478bd9Sstevel@tonic-gate { 352*7c478bd9Sstevel@tonic-gate char pkginfofile[MAXPATHLEN]; 353*7c478bd9Sstevel@tonic-gate char architecture[MAXPATHLEN]; 354*7c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 355*7c478bd9Sstevel@tonic-gate FILE *pkginfo_fp; 356*7c478bd9Sstevel@tonic-gate int hits = 0; 357*7c478bd9Sstevel@tonic-gate int i; 358*7c478bd9Sstevel@tonic-gate int index; 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate architecture[0] = '\0'; 362*7c478bd9Sstevel@tonic-gate basedir[0] = '\0'; 363*7c478bd9Sstevel@tonic-gate *arch = P_ISA; 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate /* 366*7c478bd9Sstevel@tonic-gate * determine whether the pkginfo file is a pkginfo.tmpl or 367*7c478bd9Sstevel@tonic-gate * a pkginfo file 368*7c478bd9Sstevel@tonic-gate */ 369*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(pkginfofile, protodir), "/"), 370*7c478bd9Sstevel@tonic-gate "pkginfo.tmpl"); 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate if ((pkginfo_fp = fopen(pkginfofile, "r")) == NULL) { 373*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(pkginfofile, protodir), "/"), 374*7c478bd9Sstevel@tonic-gate "pkginfo"); 375*7c478bd9Sstevel@tonic-gate if ((pkginfo_fp = fopen(pkginfofile, "r")) == NULL) { 376*7c478bd9Sstevel@tonic-gate perror(pkginfofile); 377*7c478bd9Sstevel@tonic-gate return; 378*7c478bd9Sstevel@tonic-gate } 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate while (fgets(buf, BUFSIZ, pkginfo_fp) && (hits != 3)) { 383*7c478bd9Sstevel@tonic-gate if (strncmp(buf, "ARCH=", 5) == 0) { 384*7c478bd9Sstevel@tonic-gate index = 0; 385*7c478bd9Sstevel@tonic-gate /* 386*7c478bd9Sstevel@tonic-gate * remove any '"' in the ARCH field. 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate for (i = 5; buf[i]; i++) { 389*7c478bd9Sstevel@tonic-gate if (buf[i] != '"') 390*7c478bd9Sstevel@tonic-gate architecture[index++] = buf[i]; 391*7c478bd9Sstevel@tonic-gate } 392*7c478bd9Sstevel@tonic-gate /* -1 because above copy included '\n' */ 393*7c478bd9Sstevel@tonic-gate architecture[index-1] = '\0'; 394*7c478bd9Sstevel@tonic-gate hits += 1; 395*7c478bd9Sstevel@tonic-gate } else if (strncmp(buf, "BASEDIR=", 8) == 0) { 396*7c478bd9Sstevel@tonic-gate index = 0; 397*7c478bd9Sstevel@tonic-gate /* 398*7c478bd9Sstevel@tonic-gate * remove any '"' in the BASEDIR field, and 399*7c478bd9Sstevel@tonic-gate * strip off a leading '/' if present. 400*7c478bd9Sstevel@tonic-gate */ 401*7c478bd9Sstevel@tonic-gate for (i = 8; buf[i]; i++) { 402*7c478bd9Sstevel@tonic-gate if (buf[i] != '"' && 403*7c478bd9Sstevel@tonic-gate (buf[i] != '/' || index != 0)) { 404*7c478bd9Sstevel@tonic-gate buf[index++] = buf[i]; 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate /* -1 because above copy included '\n' */ 408*7c478bd9Sstevel@tonic-gate buf[index-1] = '\0'; 409*7c478bd9Sstevel@tonic-gate (void) strcpy(basedir, &buf[0]); 410*7c478bd9Sstevel@tonic-gate hits += 2; 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate (void) fclose(pkginfo_fp); 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate if (architecture[0]) 416*7c478bd9Sstevel@tonic-gate if ((*arch = assign_arch(architecture)) == NULL) { 417*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 418*7c478bd9Sstevel@tonic-gate "warning: Unknown architecture %s found in %s\n", 419*7c478bd9Sstevel@tonic-gate architecture, pkginfofile); 420*7c478bd9Sstevel@tonic-gate } 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate /* 424*7c478bd9Sstevel@tonic-gate * The first pass through the prototype file goes through and reads 425*7c478bd9Sstevel@tonic-gate * in all the entries except 'hard links'. Those must be processed 426*7c478bd9Sstevel@tonic-gate * in a second pass. 427*7c478bd9Sstevel@tonic-gate * 428*7c478bd9Sstevel@tonic-gate * If any !includes are found in the prototype file this routine 429*7c478bd9Sstevel@tonic-gate * will be called recursively. 430*7c478bd9Sstevel@tonic-gate * 431*7c478bd9Sstevel@tonic-gate * Args: 432*7c478bd9Sstevel@tonic-gate * protofile - full pathname to prototype file to be processed. 433*7c478bd9Sstevel@tonic-gate * protodir - directory in which prototype file resides. 434*7c478bd9Sstevel@tonic-gate * list - list to which elements will be added 435*7c478bd9Sstevel@tonic-gate * arch - architecture of current prototype 436*7c478bd9Sstevel@tonic-gate * basedir - basedir for package 437*7c478bd9Sstevel@tonic-gate * pkgname - name of package 438*7c478bd9Sstevel@tonic-gate * 439*7c478bd9Sstevel@tonic-gate * Returns: 440*7c478bd9Sstevel@tonic-gate * returns number of items added to list. 441*7c478bd9Sstevel@tonic-gate * 442*7c478bd9Sstevel@tonic-gate */ 443*7c478bd9Sstevel@tonic-gate static int 444*7c478bd9Sstevel@tonic-gate first_pass_prototype(const char *protofile, const char *protodir, 445*7c478bd9Sstevel@tonic-gate elem_list *list, short arch, const char *basedir, const char *pkgname) 446*7c478bd9Sstevel@tonic-gate { 447*7c478bd9Sstevel@tonic-gate int elem_count = 0; 448*7c478bd9Sstevel@tonic-gate FILE *proto_fp; 449*7c478bd9Sstevel@tonic-gate char include_file[MAXPATHLEN]; 450*7c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate if ((proto_fp = fopen(protofile, "r")) == NULL) { 453*7c478bd9Sstevel@tonic-gate perror(protofile); 454*7c478bd9Sstevel@tonic-gate return (0); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate /* 458*7c478bd9Sstevel@tonic-gate * first pass through file - process everything but 459*7c478bd9Sstevel@tonic-gate * hard links. 460*7c478bd9Sstevel@tonic-gate */ 461*7c478bd9Sstevel@tonic-gate while (fgets(buf, BUFSIZ, proto_fp)) { 462*7c478bd9Sstevel@tonic-gate int rc; 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate switch (buf[0]) { 465*7c478bd9Sstevel@tonic-gate case FILE_T: 466*7c478bd9Sstevel@tonic-gate case EDIT_T: 467*7c478bd9Sstevel@tonic-gate case VOLATILE_T: 468*7c478bd9Sstevel@tonic-gate case DIR_T: 469*7c478bd9Sstevel@tonic-gate case SYM_LINK_T: 470*7c478bd9Sstevel@tonic-gate case CHAR_DEV_T: 471*7c478bd9Sstevel@tonic-gate case BLOCK_DEV_T: 472*7c478bd9Sstevel@tonic-gate if ((rc = parse_proto_line(basedir, buf, list, arch, 473*7c478bd9Sstevel@tonic-gate pkgname)) >= 0) { 474*7c478bd9Sstevel@tonic-gate elem_count += rc; 475*7c478bd9Sstevel@tonic-gate } else { 476*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 477*7c478bd9Sstevel@tonic-gate "error: Errors found in %s\n", protofile); 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate break; 480*7c478bd9Sstevel@tonic-gate case LINK_T: 481*7c478bd9Sstevel@tonic-gate case 'i': 482*7c478bd9Sstevel@tonic-gate case '#': 483*7c478bd9Sstevel@tonic-gate case '\n': 484*7c478bd9Sstevel@tonic-gate break; 485*7c478bd9Sstevel@tonic-gate case '!': 486*7c478bd9Sstevel@tonic-gate /* Is this an include statement - if so process */ 487*7c478bd9Sstevel@tonic-gate if (strncmp(buf, "!include", 8) == 0) { 488*7c478bd9Sstevel@tonic-gate char *inc_file = (char *)(buf + 9); 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate /* burn white space */ 491*7c478bd9Sstevel@tonic-gate while ((*inc_file == ' ') || 492*7c478bd9Sstevel@tonic-gate (*inc_file == '\t')) 493*7c478bd9Sstevel@tonic-gate inc_file++; 494*7c478bd9Sstevel@tonic-gate if (*inc_file) { 495*7c478bd9Sstevel@tonic-gate /* remove trailing \n */ 496*7c478bd9Sstevel@tonic-gate inc_file[strlen(inc_file) - 1] = '\0'; 497*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy( 498*7c478bd9Sstevel@tonic-gate include_file, protodir), "/"), 499*7c478bd9Sstevel@tonic-gate inc_file); 500*7c478bd9Sstevel@tonic-gate elem_count += 501*7c478bd9Sstevel@tonic-gate first_pass_prototype(include_file, 502*7c478bd9Sstevel@tonic-gate protodir, list, arch, basedir, 503*7c478bd9Sstevel@tonic-gate pkgname); 504*7c478bd9Sstevel@tonic-gate } else { 505*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 506*7c478bd9Sstevel@tonic-gate "warning: bad !include statement " 507*7c478bd9Sstevel@tonic-gate "in prototype %s : %s\n", 508*7c478bd9Sstevel@tonic-gate protofile, buf); 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate } else { 511*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 512*7c478bd9Sstevel@tonic-gate "warning: unexpected ! notation in " 513*7c478bd9Sstevel@tonic-gate "prototype %s : %s\n", protofile, buf); 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate } 516*7c478bd9Sstevel@tonic-gate break; 517*7c478bd9Sstevel@tonic-gate default: 518*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 519*7c478bd9Sstevel@tonic-gate "warning: unexpected line in prototype %s : %s\n", 520*7c478bd9Sstevel@tonic-gate protofile, buf); 521*7c478bd9Sstevel@tonic-gate break; 522*7c478bd9Sstevel@tonic-gate } 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate (void) fclose(proto_fp); 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate return (elem_count); 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate /* 531*7c478bd9Sstevel@tonic-gate * The second pass through the prototype file goes through and reads 532*7c478bd9Sstevel@tonic-gate * and processes only the 'hard links' in the prototype file. These 533*7c478bd9Sstevel@tonic-gate * are resolved and added accordingly to the elements list(list). 534*7c478bd9Sstevel@tonic-gate * 535*7c478bd9Sstevel@tonic-gate * If any !includes are found in the prototype file this routine 536*7c478bd9Sstevel@tonic-gate * will be called recursively. 537*7c478bd9Sstevel@tonic-gate * 538*7c478bd9Sstevel@tonic-gate * Args: 539*7c478bd9Sstevel@tonic-gate * protofile - full pathname to prototype file to be processed. 540*7c478bd9Sstevel@tonic-gate * protodir - directory in which prototype file resides. 541*7c478bd9Sstevel@tonic-gate * list - list to which elements will be added 542*7c478bd9Sstevel@tonic-gate * arch - architecture of current prototype 543*7c478bd9Sstevel@tonic-gate * basedir - basedir for package 544*7c478bd9Sstevel@tonic-gate * pkgname - package name 545*7c478bd9Sstevel@tonic-gate * 546*7c478bd9Sstevel@tonic-gate * Returns: 547*7c478bd9Sstevel@tonic-gate * returns number of items added to list. 548*7c478bd9Sstevel@tonic-gate * 549*7c478bd9Sstevel@tonic-gate */ 550*7c478bd9Sstevel@tonic-gate static int 551*7c478bd9Sstevel@tonic-gate second_pass_prototype(const char *protofile, const char *protodir, 552*7c478bd9Sstevel@tonic-gate elem_list *list, short arch, const char *basedir, const char *pkgname) 553*7c478bd9Sstevel@tonic-gate { 554*7c478bd9Sstevel@tonic-gate FILE *proto_fp; 555*7c478bd9Sstevel@tonic-gate int elem_count = 0; 556*7c478bd9Sstevel@tonic-gate char include_file[MAXPATHLEN]; 557*7c478bd9Sstevel@tonic-gate char buf[BUFSIZ]; 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate if ((proto_fp = fopen(protofile, "r")) == NULL) { 560*7c478bd9Sstevel@tonic-gate perror(protofile); 561*7c478bd9Sstevel@tonic-gate return (0); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate /* 565*7c478bd9Sstevel@tonic-gate * second pass through prototype file - process the hard links 566*7c478bd9Sstevel@tonic-gate * now. 567*7c478bd9Sstevel@tonic-gate */ 568*7c478bd9Sstevel@tonic-gate while (fgets(buf, BUFSIZ, proto_fp)) 569*7c478bd9Sstevel@tonic-gate if (buf[0] == LINK_T) { 570*7c478bd9Sstevel@tonic-gate int rc; 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate if ((rc = parse_proto_link(basedir, buf, list, arch, 573*7c478bd9Sstevel@tonic-gate pkgname)) >= 0) { 574*7c478bd9Sstevel@tonic-gate elem_count += rc; 575*7c478bd9Sstevel@tonic-gate } else { 576*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 577*7c478bd9Sstevel@tonic-gate "error: Errors found in %s\n", protofile); 578*7c478bd9Sstevel@tonic-gate } 579*7c478bd9Sstevel@tonic-gate } else if (strncmp(buf, "!include", 8) == 0) { 580*7c478bd9Sstevel@tonic-gate /* 581*7c478bd9Sstevel@tonic-gate * This is a file to include 582*7c478bd9Sstevel@tonic-gate */ 583*7c478bd9Sstevel@tonic-gate char *inc_file = (char *)(buf + 9); 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate /* burn white space */ 586*7c478bd9Sstevel@tonic-gate while ((*inc_file == ' ') || (*inc_file == '\t')) 587*7c478bd9Sstevel@tonic-gate inc_file++; 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate if (*inc_file) { 590*7c478bd9Sstevel@tonic-gate /* remove trailing \n */ 591*7c478bd9Sstevel@tonic-gate inc_file[strlen(inc_file) - 1] = '\0'; 592*7c478bd9Sstevel@tonic-gate /* build up include file name to be opened. */ 593*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(include_file, 594*7c478bd9Sstevel@tonic-gate protodir), "/"), inc_file); 595*7c478bd9Sstevel@tonic-gate /* 596*7c478bd9Sstevel@tonic-gate * recursively call this routine to process the 597*7c478bd9Sstevel@tonic-gate * !include file. 598*7c478bd9Sstevel@tonic-gate */ 599*7c478bd9Sstevel@tonic-gate elem_count += 600*7c478bd9Sstevel@tonic-gate second_pass_prototype(include_file, 601*7c478bd9Sstevel@tonic-gate protodir, list, arch, basedir, pkgname); 602*7c478bd9Sstevel@tonic-gate } else { 603*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 604*7c478bd9Sstevel@tonic-gate "warning: Bad !include statement in " 605*7c478bd9Sstevel@tonic-gate "prototype %s : %s\n", protofile, buf); 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate (void) fclose(proto_fp); 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate return (elem_count); 612*7c478bd9Sstevel@tonic-gate } 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate /* 615*7c478bd9Sstevel@tonic-gate * Args: 616*7c478bd9Sstevel@tonic-gate * pkgname - name of package being processed 617*7c478bd9Sstevel@tonic-gate * protodir - pathname to package defs directory 618*7c478bd9Sstevel@tonic-gate * list - List of elements read in, elements are added to this 619*7c478bd9Sstevel@tonic-gate * as they are read in. 620*7c478bd9Sstevel@tonic-gate * verbose - verbose output 621*7c478bd9Sstevel@tonic-gate * 622*7c478bd9Sstevel@tonic-gate * Returns: 623*7c478bd9Sstevel@tonic-gate * number of elements added to list 624*7c478bd9Sstevel@tonic-gate */ 625*7c478bd9Sstevel@tonic-gate int 626*7c478bd9Sstevel@tonic-gate process_package_dir(const char *pkgname, const char *protodir, 627*7c478bd9Sstevel@tonic-gate elem_list *list, int verbose) 628*7c478bd9Sstevel@tonic-gate { 629*7c478bd9Sstevel@tonic-gate struct stat st_buf; 630*7c478bd9Sstevel@tonic-gate char protofile[MAXPATHLEN]; 631*7c478bd9Sstevel@tonic-gate char basedir[MAXPATHLEN]; 632*7c478bd9Sstevel@tonic-gate short arch; 633*7c478bd9Sstevel@tonic-gate int count = 0; 634*7c478bd9Sstevel@tonic-gate 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate /* 637*7c478bd9Sstevel@tonic-gate * skip any packages we've already handled (because of 638*7c478bd9Sstevel@tonic-gate * dependencies) 639*7c478bd9Sstevel@tonic-gate */ 640*7c478bd9Sstevel@tonic-gate if (processed_package(pkgname)) { 641*7c478bd9Sstevel@tonic-gate return (0); 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate /* 645*7c478bd9Sstevel@tonic-gate * find the prototype file. Legal forms of the name are: 646*7c478bd9Sstevel@tonic-gate * prototype 647*7c478bd9Sstevel@tonic-gate * prototype_<mach> (where mach == (sparc || i386 || ppc) 648*7c478bd9Sstevel@tonic-gate */ 649*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(protofile, protodir), "/"), "prototype"); 650*7c478bd9Sstevel@tonic-gate if (stat(protofile, &st_buf) < 0) { 651*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) { 652*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcat(strcpy(protofile, 653*7c478bd9Sstevel@tonic-gate protodir), "/"), "prototype"), PROTO_EXT); 654*7c478bd9Sstevel@tonic-gate if (stat(protofile, &st_buf) < 0) { 655*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) { 656*7c478bd9Sstevel@tonic-gate if (verbose) { 657*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 658*7c478bd9Sstevel@tonic-gate "warning: no prototype " 659*7c478bd9Sstevel@tonic-gate "file found in %s, " 660*7c478bd9Sstevel@tonic-gate "skipping...\n", 661*7c478bd9Sstevel@tonic-gate protodir); 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate } else 664*7c478bd9Sstevel@tonic-gate perror(protofile); 665*7c478bd9Sstevel@tonic-gate return (0); 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate } else { 668*7c478bd9Sstevel@tonic-gate perror(protofile); 669*7c478bd9Sstevel@tonic-gate return (0); 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate 673*7c478bd9Sstevel@tonic-gate mark_processed(pkgname); 674*7c478bd9Sstevel@tonic-gate 675*7c478bd9Sstevel@tonic-gate read_pkginfo(protodir, &arch, basedir); 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate count += first_pass_prototype(protofile, protodir, list, arch, 678*7c478bd9Sstevel@tonic-gate basedir, pkgname); 679*7c478bd9Sstevel@tonic-gate count += second_pass_prototype(protofile, protodir, list, arch, 680*7c478bd9Sstevel@tonic-gate basedir, pkgname); 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate /* print_list(list); */ 683*7c478bd9Sstevel@tonic-gate return (count); 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate int 687*7c478bd9Sstevel@tonic-gate read_in_protodir(const char *dir_name, elem_list *list, int verbose) 688*7c478bd9Sstevel@tonic-gate { 689*7c478bd9Sstevel@tonic-gate DIR *p_dir; 690*7c478bd9Sstevel@tonic-gate struct dirent *dp; 691*7c478bd9Sstevel@tonic-gate char protodir[MAXPATHLEN]; 692*7c478bd9Sstevel@tonic-gate struct stat st_buf; 693*7c478bd9Sstevel@tonic-gate int count = 0; 694*7c478bd9Sstevel@tonic-gate 695*7c478bd9Sstevel@tonic-gate if ((p_dir = opendir(dir_name)) == NULL) { 696*7c478bd9Sstevel@tonic-gate perror(dir_name); 697*7c478bd9Sstevel@tonic-gate exit(1); 698*7c478bd9Sstevel@tonic-gate } 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate list->type = PROTODIR_LIST; 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate while ((dp = readdir(p_dir)) != NULL) { 703*7c478bd9Sstevel@tonic-gate /* 704*7c478bd9Sstevel@tonic-gate * let's not check "." and ".." - I don't really like this 705*7c478bd9Sstevel@tonic-gate * but I wasn't really sure you could be sure that they 706*7c478bd9Sstevel@tonic-gate * are always the first two entries in the directory 707*7c478bd9Sstevel@tonic-gate * structure - so I put it in the loop. 708*7c478bd9Sstevel@tonic-gate * 709*7c478bd9Sstevel@tonic-gate * Also - we skip all directories that are names .del-*. 710*7c478bd9Sstevel@tonic-gate * and any SCCS directories too. 711*7c478bd9Sstevel@tonic-gate */ 712*7c478bd9Sstevel@tonic-gate if ((strcmp(dp->d_name, ".") == 0) || 713*7c478bd9Sstevel@tonic-gate (strcmp(dp->d_name, "..") == 0) || 714*7c478bd9Sstevel@tonic-gate (strncmp(dp->d_name, ".del-", 5) == 0) || 715*7c478bd9Sstevel@tonic-gate (strcmp(dp->d_name, "SCCS") == 0)) 716*7c478bd9Sstevel@tonic-gate continue; 717*7c478bd9Sstevel@tonic-gate 718*7c478bd9Sstevel@tonic-gate (void) strcat(strcat(strcpy(protodir, dir_name), "/"), 719*7c478bd9Sstevel@tonic-gate dp->d_name); 720*7c478bd9Sstevel@tonic-gate if (stat(protodir, &st_buf) < 0) { 721*7c478bd9Sstevel@tonic-gate perror(protodir); 722*7c478bd9Sstevel@tonic-gate continue; 723*7c478bd9Sstevel@tonic-gate } 724*7c478bd9Sstevel@tonic-gate if (!S_ISDIR(st_buf.st_mode)) { 725*7c478bd9Sstevel@tonic-gate if (verbose) { 726*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 727*7c478bd9Sstevel@tonic-gate "warning: %s not a directory\n", protodir); 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate continue; 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate count += process_dependencies(dp->d_name, dir_name, list, 733*7c478bd9Sstevel@tonic-gate verbose); 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate count += process_package_dir(dp->d_name, protodir, list, 736*7c478bd9Sstevel@tonic-gate verbose); 737*7c478bd9Sstevel@tonic-gate } 738*7c478bd9Sstevel@tonic-gate 739*7c478bd9Sstevel@tonic-gate if (verbose) 740*7c478bd9Sstevel@tonic-gate (void) printf("read in %d lines\n", count); 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate (void) closedir(p_dir); 743*7c478bd9Sstevel@tonic-gate 744*7c478bd9Sstevel@tonic-gate return (count); 745*7c478bd9Sstevel@tonic-gate } 746