Home | History | Annotate | Download | only in sys
      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