1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 31 32 #pragma ident "%Z%%M% %I% %E% SMI" 33 34 #include <pwd.h> 35 #include <stdio.h> 36 #include <string.h> 37 #include <time.h> 38 #include <values.h> 39 #include <sys/types.h> 40 #include <sys/stat.h> 41 #include "wish.h" 42 #undef min 43 #undef max 44 #include "typetab.h" /* for ott masks ott_tab ott_entry() */ 45 #include "partabdefs.h" 46 #include "var_arrays.h" /* for array_len() */ 47 #include "sizes.h" 48 49 #ifndef TEST 50 51 #include "eval.h" 52 53 #else /* TEST */ 54 #define IOSTRUCT FILE 55 #define putac putc 56 #define putastr fputs 57 #define mess_temp puts 58 #endif /* TEST */ 59 60 #define DAY (24L * 60L * 60L) 61 62 extern struct ott_entry *Cur_entry; 63 extern struct opt_entry Partab[]; 64 extern char *Oasys; 65 66 static char any[] = "any"; 67 static char path_buf[PATHSIZ]; 68 static void traverse(); 69 static char *myregcmp(char *s); 70 static int range(char *s, int origin, int *mindays, int *maxdays); 71 72 #ifdef TEST 73 int 74 main(argc, argv) 75 int argc; 76 char *argv[]; 77 { 78 wish_init(argc, argv); 79 odftread(); 80 genfind(argc, argv, stdin, stdout); 81 return (0); 82 } 83 #endif /* TEST */ 84 85 /* 86 * usage: genfind path filename type owner age 87 */ 88 int 89 genfind(argc, argv, instr, outstr, errstr) 90 int argc; 91 char *argv[]; 92 IOSTRUCT *instr; 93 IOSTRUCT *outstr; 94 IOSTRUCT *errstr; 95 { 96 FILE *fp; 97 register pid_t uid; /* EFT abs k16 */ 98 int min_days; 99 int max_days; 100 int do_traverse; 101 int origin; 102 int pathpos; 103 int namepos; 104 char path[PATHSIZ]; 105 char buf[BUFSIZ]; 106 char *type; 107 char *dtype; 108 char allpath[PATHSIZ]; 109 char *Allfile="/info/OH/externals/allobjs"; 110 register int i; 111 register char *pattern; 112 register struct passwd *passwdptr; 113 struct passwd *getpwnam(); 114 115 if (argc < 6 && argc > 8) { 116 mess_temp("Arguments invalid"); 117 return FAIL; 118 } 119 i = 1; 120 origin = 0; 121 if (strcmp(argv[i], "-1") == 0) { 122 origin = 1; 123 i++; 124 } 125 else 126 do_traverse = TRUE; 127 if (strcmp(argv[i], "-n") == 0) { 128 do_traverse = FALSE; 129 i++; 130 } 131 else 132 do_traverse = TRUE; 133 pathpos = i; 134 /* traverse assumes at least 1 extra byte available in path */ 135 if ((int)strlen(argv[i]) > PATHSIZ - 2) { /* EFT k16 */ 136 mess_temp("Path too long"); 137 return FAIL; 138 } 139 strncpy(path, argv[i], PATHSIZ); 140 path[sizeof(path) - 1] = '\0'; 141 if ((pattern = myregcmp(argv[++i])) == NULL) { 142 mess_temp("Name invalid"); 143 return FAIL; 144 } 145 namepos = ++i; 146 if (strCcmp(argv[++i], any)) { 147 if ((passwdptr = getpwnam(argv[i])) == NULL) { 148 mess_temp("Owner invalid"); 149 return FAIL; 150 } 151 uid = passwdptr->pw_uid; 152 } 153 else 154 uid = -1; 155 if (strCcmp(argv[++i], any)) { 156 if (range(argv[i], origin, &min_days, &max_days) < 0) { 157 mess_temp("Age invalid"); 158 return FAIL; 159 } 160 } 161 else 162 min_days = -1; 163 164 (void) strcpy(allpath, Oasys); 165 (void) strcat(allpath, Allfile); 166 167 168 if ((fp = fopen(allpath, "r")) == NULL) 169 type=NULL; 170 else 171 while(fgets(buf,BUFSIZ,fp)) { 172 type=strtok(buf,"\t"); 173 dtype=strtok(NULL,"\n"); 174 if (strcmp(argv[namepos],dtype) == 0) 175 break; 176 type=NULL; 177 } 178 fclose(fp); 179 180 traverse(path, pattern, uid, strCcmp(argv[namepos], any) ? argv[namepos] : NULL, min_days, max_days, argv[pathpos], do_traverse, outstr, type ); 181 return SUCCESS; 182 } 183 184 static void 185 traverse(path, pattern, uid, objtype, min_days, max_days, prefix, do_traverse, outstr, type) 186 char *path; 187 char *pattern; 188 int uid; 189 char *objtype; 190 int min_days; 191 int max_days; 192 char *prefix; 193 int do_traverse; 194 IOSTRUCT *outstr; 195 char *type; 196 { 197 register int i; 198 register int length; 199 register int ott_len; 200 register int numdays; 201 char *basename; 202 char *objname; 203 char *typename; 204 char *intobj; 205 long mask; 206 time_t now; /* EFT abs k16 */ 207 struct stat filestat; 208 struct tm *t; 209 struct ott_tab *ott; 210 struct ott_tab *ott_get(); 211 struct ott_entry *entry; 212 char *bsd_path_to_title(); 213 char *regex(); 214 time_t time(); /* EFT abs k16 */ 215 struct tm *localtime(); 216 217 /* check to see if enough space to put file names */ 218 if ((length = strlen(path)) >= PATHSIZ - 2) 219 return; 220 if ((ott = ott_get(path, OTT_SALPHA, 0, 0, 0)) == NULL) 221 return; 222 entry = Cur_entry; 223 ott_len = array_len(ott->parents); 224 now = time(NULL); 225 t = localtime(&now); 226 now += (60 - t->tm_sec) + 60 * ((59 - t->tm_min) + 60 * (23 - t->tm_hour)); 227 for (i = 0; i < ott_len; ++i) { 228 /* shorter names */ 229 basename = entry[ott->parents[i]].name; 230 objname = entry[ott->parents[i]].dname; 231 typename = entry[ott->parents[i]].display; 232 intobj = entry[ott->parents[i]].objtype; 233 mask = entry[ott->parents[i]].objmask; 234 /* object's name not viewable or marked deleted */ 235 if (basename[0] == '\0' || (mask & M_WB) || (mask & M_DL)) 236 continue; 237 /* 238 * these tests are performed in order of increasing 239 * computational cost 240 */ 241 path[length] = '/'; 242 strncpy(&path[length + 1], basename, PATHSIZ - length - 2); 243 244 if ((!objtype || !strcmp(objtype, typename) || 245 !strcmp(intobj, type)) && regex(pattern, objname)) { 246 numdays = (int) ((now - entry[ott->parents[i]].mtime) / DAY); 247 if (min_days < 0 || (numdays >= min_days && numdays <= max_days)) { 248 if (uid >= 0 && stat(path, &filestat)) 249 continue; 250 if (uid < 0 || filestat.st_uid == uid) { 251 putastr(path, outstr); 252 putac(';', outstr); 253 putastr(entry[ott->parents[i]].objtype, outstr); 254 putac(';', outstr); 255 path[length] = '\0'; 256 if (do_traverse) { 257 258 strcpy(path_buf,path); 259 strcat(path_buf,"/"); 260 strcat(path_buf,objname); 261 putastr(bsd_path_to_title(&path_buf[strlen(prefix)+1], 262 COLS - 30), outstr); 263 } else 264 putastr(objname, outstr); 265 path[length] = '/'; 266 putac(';', outstr); 267 putastr(typename, outstr); 268 putac('\n', outstr); 269 } 270 } 271 } 272 if (mask & CL_DIR) { 273 /* object is a directory and not deleted, search */ 274 if (do_traverse) 275 traverse(path, pattern, uid, objtype, min_days, max_days, 276 prefix, do_traverse, outstr, type); 277 path[length] = '\0'; 278 if ((ott = ott_get(path, OTT_SALPHA, 0, 0, 0)) == NULL) 279 return; 280 entry = Cur_entry; 281 ott_len = array_len(ott->parents); 282 } 283 } /* end of for loop */ 284 } 285 286 static int 287 range(char *s, int origin, int *mindays, int *maxdays) 288 { 289 char *s1; 290 long strtol(); 291 292 switch (*s) { 293 case '<': 294 *mindays = 0; 295 *maxdays = (int) strtol(s + 1, &s1, 10); 296 break; 297 case '>': 298 *maxdays = MAXINT; 299 *mindays = (int) strtol(s + 1, &s1, 10); 300 break; 301 default: 302 *mindays = (int) strtol(s, &s1, 10); 303 if (s1 == s) 304 return FAIL; 305 if (*s1 == '-') 306 *maxdays = (int) strtol(s1 + 1, &s1, 10); 307 else if (*s1 == '.' && s1[1] == '.') 308 *maxdays = (int) strtol(s1 + 2, &s1, 10); 309 else 310 *maxdays = *mindays; 311 break; 312 } 313 if (origin && *mindays == 1) 314 *mindays = 0; 315 if (*mindays < 0 || *maxdays < 0) 316 return FAIL; 317 return (*s1 == '\0') ? SUCCESS : FAIL; 318 } 319 320 static char * 321 myregcmp(char *s) 322 { 323 register char *p; 324 register char *q; 325 register int len; 326 static char special[] = "+.${}()"; 327 char *regcmp(); 328 char *strnsave(); 329 char *_backslash(); 330 331 len = strlen(s) * 2 + 4; 332 p = strnsave("^", len); 333 (void) strcat(p, s); 334 (void) _backslash(p, len, special, special); 335 (void) strcat(p, "$"); 336 for (q = p; *q; q++) 337 switch (*q) { 338 case '*': 339 memshift(q + 1, q, strlen(q) + 1); 340 *q++ = '.'; 341 break; 342 case '?': 343 *q = '.'; 344 break; 345 case '\\': 346 if (!*++q) 347 q--; 348 break; 349 case '[': 350 if (q[1] == '!') 351 q[1] = '^'; 352 break; 353 default: 354 break; 355 } 356 q = regcmp(p, NULL); 357 free(p); 358 return q; 359 } 360