#include "ufk.h" #include #include #include /* * Get next file in a file group */ get_file_spec(firsttime) char firsttime; { char *wild_file_spec(), *status; static char my_firsttime; if (firsttime) { filenum = 1; /* First time initial values */ filecount = numprm - 1; my_firsttime = TRUE; } do { if (rflg != 2) { status = wild_file_spec(params[filenum], my_firsttime); my_firsttime = FALSE; } else { status = params[filenum++]; /* Don't parse for 'GET' */ if (filecount-- == 0) break; } if (status == ERROR) { prterr(ER_DIROPN); break; } else if (status) /* Got valid spec */ { filnam = status; /* Setup pointer to spec */ return TRUE; } filenum++; /* Next parameter */ my_firsttime = TRUE; /* Start new directory search */ } while (--filecount > 0); /* More to do */ return FALSE; /* done */ } char *wild_file_spec(mask,first) char mask[], first; { static struct direct *ptr; struct direct *diropen(); static char filename[128]; char status; if (first) if ((ptr = diropen(mask)) == ERROR) return (ERROR); /* Failed to open directory */ while(TRUE) { status = dirread(ptr,filename); if (status == ERROR) /* Check for end */ break; if (status != TYPERROR) if (mskcmp(filename,mask)) /* Check match if not a directory */ return(filename); /* or device type file */ } free(ptr); /* Release allocated memory */ return (FALSE); /* No more files */ } /* *** Compare against a mask * * This function compares a given string against a mask and returns * a 1 for 'compares' or a 0 for 'does not compare'. * * A mask is a concatenation of the following elements: * * c literal character * ? any character match except endstring null * [..] character class (all of these characters) * [^..] negated character class (all but these characters) * ^c negated character (all but this character) * * zone (match zero or more occurences) * * A character class consists of zero or more of the following * surrounded by [ and ]: * * c1-c2 range of ascii characters * c1-c2..c1-c3 multiple ranges * */ mskcmp(string,m) char *string,*m; { int k; char *sp,*sav,string2[128]; char *n,msk[128]; strcpy(sp = string2,string); strcpy(n = msk,m); while (*n) { if (*n == '*') { sav = sp; if (!*++n) return (1); while (*sp && !mskcmp(sp,n)) ++sp; if (*sp) continue; sp = sav; } else if (!(k = onecmp(*sp,n))) return (0); else n += k; if (*sp) ++sp; } return (!*sp); } /* *** Compare only one character (for mskcmp) */ onecmp(s,m) char s,*m; { char c,setfind,setflag; char *mp; if ((c = *(mp = m)) == '?' && s); /* Okay as it is */ else if (c == '[') { setfind = setflag = 0; if (*++mp == '^') { setflag = 1; ++mp; } for (;(c = *mp) && c != ']'; ++mp) if (*mp == '-' && s >= *(mp - 1) && s <= *(mp + 1) && *(mp - 1) <= *(mp + 1)) { /* skip to trailing ']' */ while ((c = *(mp + 1)) && c != ']') ++mp; setfind = 1; } if (setfind == setflag) return (0); else return (mp - m + 1); } else if (c == '^' && *(mp + 1) != s) return (2); else if (c != s) return (0); return (1); } /* *** Open disk directory */ int *dirptr; char dirspec[128]; struct direct *diropen(name) char *name; { static struct direct ptr; int i, j; for (i = strlen(name) - 1; i >= 0; --i) /* Find filename */ if (name[i] == '/') break; for (j = 0; j <= i; j++) /* Save directory path */ dirspec[j] = name[j]; dirspec[j++] = '.'; /* Append "." */ dirspec[j] = '\0'; if ((dirptr = open(dirspec,0)) == ERROR) /* Open directory */ return (ERROR); else return (&ptr); } dirread(ptr,filename) struct direct *ptr; char *filename; { int i, j, status; struct stat statptr; while (TRUE) { status = read(dirptr,ptr,sizeof(struct direct)); /* Get dir entry */ if (status == ERROR || status == NULL) /* Stop on EOF or error */ break; if (ptr->d_ino) /* If not a deleted file */ { strcpy(filename,dirspec); /* Copy directory spec */ strncpy(&filename[strlen(filename)-1],ptr->d_name,DIRSIZ); /* +fnam */ stat(filename,&statptr); /* Get file status */ statptr.st_mode &= S_IFMT; /* Mask file type bits */ if ((statptr.st_mode == S_IFDIR) || /* Check if directory */ (statptr.st_mode == S_IFCHR) || /* or if character device */ (statptr.st_mode == S_IFBLK)) /* or if block device */ return(TYPERROR); file_size = statptr.st_size; /* Fill in file size */ transmit_chr_count = 0; /* Start new sequence */ return (TRUE); } } close(dirptr); return (ERROR); }