/* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern, glob_t *pglob, size_t *limit) { __gl_stat_t sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; if (g_lstat(pathbuf, &sb, pglob)) return(0); if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)))) { if (pathend >= pathlim) return (GLOB_ABORTED); *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return(globextend(pathbuf, pglob, limit)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && *p != SEP) { if (ismeta(*p)) anymeta = 1; if (q >= pathlim) return GLOB_ABORTED; *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (*pattern == SEP) { if (pathend >= pathlim) return GLOB_ABORTED; *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathend, pathlim, pattern, p, pglob, limit)); } /* NOTREACHED */ }
static void qprintf(const char *str, char *s) { char *p; printf("%s:\n", str); for (p = s; *p; p++) printf("%c", CHAR(*p)); printf("\n"); for (p = s; *p; p++) printf("%c", *p & M_PROTECT ? '"' : ' '); printf("\n"); for (p = s; *p; p++) printf("%c", ismeta(*p) ? '_' : ' '); printf("\n"); }
// // The functions glob2 and glob3 are mutually recursive; there is one level // of recursion for each segment in the pattern that contains one or more // meta characters. // static int glob2(char *pathbuf, char *pathend, char *pathend_last, char *pattern, glob_t *pglob, size_t *limit) { struct stat sb; char *p, *q; int anymeta; // // Loop over pattern segments until end of pattern or until // segment with meta character found. // for (anymeta = 0;;) { if (*pattern == EOS) { // End of pattern? *pathend = EOS; if (lstat(pathbuf, &sb)) return 0; if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && (stat(pathbuf, &sb) == 0) && S_ISDIR(sb.st_mode)))) { if (pathend + 1 > pathend_last) return GLOB_ABORTED; *pathend++ = SEP; *pathend = EOS; } pglob->gl_matchc++; return globextend(pathbuf, pglob, limit); } // Find end of next segment, copy tentatively to pathend. q = pathend; p = pattern; while (*p != EOS && *p != SEP) { if (ismeta(*p)) anymeta = 1; if (q + 1 > pathend_last) return GLOB_ABORTED; *q++ = *p++; } if (!anymeta) { // No expansion, do next segment. pathend = q; pattern = p; while (*pattern == SEP) { if (pathend + 1 > pathend_last) return GLOB_ABORTED; *pathend++ = *pattern++; } } else { // Need expansion, recurse return glob3(pathbuf, pathend, pathend_last, pattern, p, pglob, limit); } } }
afs_int32 util_GetInt64(char *as, afs_int64 * aval) { afs_int64 total; int tc; int base; int negative; total = 0; /* initialize things */ negative = 0; /* skip over leading spaces */ while ((tc = *as)) { if (tc != ' ' && tc != '\t') break; } /* compute sign */ if (*as == '-') { negative = 1; as++; /* skip over character */ } /* compute the base */ if (*as == '0') { as++; if (*as == 'x' || *as == 'X') { base = 16; as++; } else base = 8; } else base = 10; /* compute the # itself */ while ((tc = *as)) { if (!ismeta(tc, base)) return -1; total *= base; total += getmeta(tc); as++; } if (negative) *aval = -total; else *aval = total; return 0; }
int glob2 (Char *pathbuf, Char *pathend, Char *pathlim, Char *pattern) { int i; int anymeta; Char tmp; for (anymeta = 0;;) { /* Copies a single string from pattern into pathend, checking for * the presence of meta-characters. */ i = 0; while (pattern[i] != EOS && pattern[i] != SEP) { if (ismeta(pattern[i])) anymeta = 1; if (pathend + i >= pathlim) return 1; tmp = pattern[i]; /* BAD */ pathend[i] = tmp; i++; } if (!anymeta) { pathend = pathend + i; pattern = pattern + i; while (*pattern == SEP) { // bounds check if (pathend >= pathlim) return 1; tmp = *pattern; /* BAD */ *pathend = tmp; pathend++; pattern++; } } else { // stand-in for glob3 (which is recursive) return 0; } } /* NOT REACHED */ }
afs_uint32 util_GetUInt64(char *as, afs_uint64 * aval) { afs_uint64 total; int tc; int base; total = 0; /* initialize things */ /* skip over leading spaces */ while ((tc = *as)) { if (tc != ' ' && tc != '\t') break; } /* compute the base */ if (*as == '0') { as++; if (*as == 'x' || *as == 'X') { base = 16; as++; } else base = 8; } else base = 10; /* compute the # itself */ while ((tc = *as)) { if (!ismeta(tc, base)) return -1; total *= base; total += getmeta(tc); as++; } *aval = total; return 0; }
/* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp, int recursion) { struct stat sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; if (limitp->glim_stat++ >= pglob->gl_maxfiles) { errno = 0; *pathend++ = SEP; *pathend = EOS; return GLOB_NOSPACE; } if (g_lstat(pathbuf, &sb, pglob)) { return 0; } if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)))) { if (pathend + 1 > pathend_last) { return 1; } *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return globextend(pathbuf, pglob, limitp, &sb); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && *p != SEP) { if (ismeta(*p)) { anymeta = 1; } if (q + 1 > pathend_last) { return 1; } *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (*pattern == SEP) { if (pathend + 1 > pathend_last) { return 1; } *pathend++ = *pattern++; } } else { /* Need expansion, recurse. */ return glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, p, pattern_last, pglob, limitp, recursion + 1); } } /* NOTREACHED */ }
/* * returns pointer to beginning of expansion and sets type of expansion */ static char *find_begin(char outbuff[], char *last, int endchar, int *type) { register char *cp=outbuff, *bp, *xp; register int c,inquote = 0, inassign=0; int mode=*type; bp = outbuff; *type = 0; while(cp < last) { xp = cp; switch(c= mbchar(cp)) { case '\'': case '"': if(!inquote) { inquote = c; bp = xp; break; } if(inquote==c) inquote = 0; break; case '\\': if(inquote != '\'') mbchar(cp); break; case '$': if(inquote == '\'') break; c = *(unsigned char*)cp; if(mode!='*' && (isaletter(c) || c=='{')) { int dot = '.'; if(c=='{') { xp = cp; mbchar(cp); c = *(unsigned char*)cp; if(c!='.' && !isaletter(c)) break; } else dot = 'a'; while(cp < last) { if((c= mbchar(cp)) , c!=dot && !isaname(c)) break; } if(cp>=last) { if(c==dot || isaname(c)) { *type='$'; return(++xp); } if(c!='}') bp = cp; } } else if(c=='(') { *type = mode; xp = find_begin(cp,last,')',type); if(*(cp=xp)!=')') bp = xp; else cp++; } break; case '=': if(!inquote) { bp = cp; inassign = 1; } break; case ':': if(!inquote && inassign) bp = cp; break; case '~': if(*cp=='(') break; /* fall through */ default: if(c && c==endchar) return(xp); if(!inquote && ismeta(c)) { bp = cp; inassign = 0; } break; } } if(inquote && *bp==inquote) *type = *bp++; return(bp); }
/* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) { Stat_t sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == BG_EOS) { /* End of pattern? */ *pathend = BG_EOS; if (g_lstat(pathbuf, &sb, pglob)) return(0); if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != BG_SEP #ifdef DOSISH && pathend[-1] != BG_SEP2 #endif ) && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)))) { if (pathend+1 > pathend_last) return (1); *pathend++ = BG_SEP; *pathend = BG_EOS; } ++pglob->gl_matchc; #ifdef GLOB_DEBUG printf("calling globextend from glob2\n"); #endif /* GLOB_DEBUG */ return(globextend(pathbuf, pglob, limitp)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != BG_EOS && *p != BG_SEP #ifdef DOSISH && *p != BG_SEP2 #endif ) { if (ismeta(*p)) anymeta = 1; if (q+1 > pathend_last) return (1); *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (*pattern == BG_SEP #ifdef DOSISH || *pattern == BG_SEP2 #endif ) { if (pathend+1 > pathend_last) return (1); *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, p, pattern_last, pglob, limitp)); } /* NOTREACHED */ }
// // Returns pointer to beginning of expansion and sets type of expansion. // static char *find_begin(char outbuff[], char *last, int endchar, int *type) { char *cp = outbuff, *bp, *xp; int c, inquote = 0, inassign = 0; int mode = *type; bp = outbuff; *type = 0; while (cp < last) { xp = cp; switch (c = mb1char(&cp)) { case '\'': case '"': { if (!inquote) { inquote = c; bp = xp; break; } if (inquote == c) inquote = 0; break; } case '\\': { if (inquote != '\'') (void)mb1char(&cp); break; } case '$': { if (inquote == '\'') break; c = *(unsigned char *)cp; if (mode != '*' && (isaletter(c) || c == '{')) { int dot = '.'; if (c == '{') { xp = cp; (void)mb1char(&cp); c = *(unsigned char *)cp; if (c != '.' && !isaletter(c)) break; } else { dot = 'a'; } while (cp < last) { if ((c = mb1char(&cp)), c != dot && !isaname(c)) break; } if (cp >= last) { if (c == dot || isaname(c)) { *type = '$'; return ++xp; } if (c != '}') bp = cp; } } else if (c == '(') { *type = mode; xp = find_begin(cp, last, ')', type); if (*(cp = xp) != ')') { bp = xp; } else { cp++; } } break; } case '=': { if (!inquote) { bp = cp; inassign = 1; } break; } case ':': { if (!inquote && inassign) bp = cp; break; } case '~': { if (*cp == '(') break; } // FALLTHRU default: { if (c && c == endchar) return xp; if (!inquote && ismeta(c)) { bp = cp; inassign = 0; } break; } } } if (inquote && *bp == inquote) { *type = *bp++; } else { if (*cp == 0 && cp[-1] == ' ') return cp; } return bp; }
/** * dbop_first: get first record. * * @param[in] dbop dbop descripter * @param[in] name key value or prefix, * !=NULL: indexed read by key, * ==NULL: sequential read * @param[in] preg compiled regular expression if any. * @param[in] flags following dbop_next call take over this. * DBOP_KEY: read key part, * DBOP_PREFIX: prefix read; only valid when sequential read * @return data or NULL */ const char * dbop_first(DBOP *dbop, const char *name, regex_t *preg, int flags) { DB *db = dbop->db; DBT key, dat; int status; int len; dbop->preg = preg; dbop->ioflags = flags; if (flags & DBOP_PREFIX && !name) flags &= ~DBOP_PREFIX; #ifdef USE_SQLITE3 if (dbop->openflags & DBOP_SQLITE3) return dbop3_first(dbop, name, preg, flags); #endif if (name) { if ((len = strlen(name)) > MAXKEYLEN) die("primary key too long."); strlimcpy(dbop->key, name, sizeof(dbop->key)); key.data = (char *)name; key.size = len; /* * includes NULL character unless prefix read. */ if (!(flags & DBOP_PREFIX)) key.size++; dbop->keylen = key.size; for (status = (*db->seq)(db, &key, &dat, R_CURSOR); status == RET_SUCCESS; status = (*db->seq)(db, &key, &dat, R_NEXT)) { dbop->readcount++; if (flags & DBOP_PREFIX) { if (strncmp((char *)key.data, dbop->key, dbop->keylen)) return NULL; } else { if (strcmp((char *)key.data, dbop->key)) return NULL; } if (preg && regexec(preg, (char *)key.data, 0, 0, 0) != 0) continue; break; } } else { dbop->keylen = dbop->key[0] = 0; for (status = (*db->seq)(db, &key, &dat, R_FIRST); status == RET_SUCCESS; status = (*db->seq)(db, &key, &dat, R_NEXT)) { dbop->readcount++; /* skip meta records */ if (ismeta(key.data) && !(dbop->openflags & DBOP_RAW)) continue; if (preg && regexec(preg, (char *)key.data, 0, 0, 0) != 0) continue; break; } } dbop->lastdat = (char *)dat.data; dbop->lastsize = dat.size; dbop->lastkey = (char *)key.data; dbop->lastkeysize = key.size; switch (status) { case RET_SUCCESS: break; case RET_ERROR: die("dbop_first failed."); case RET_SPECIAL: return (NULL); } if (flags & DBOP_KEY) { strlimcpy(dbop->prev, (char *)key.data, sizeof(dbop->prev)); return (char *)key.data; } return ((char *)dat.data); }
const char * dbop3_next(DBOP *dbop) { int rc; char *key, *dat; /* * 0: rowid * 1: key * 2: dat * 3: flags */ for (;;) { /* Once it receives SQLITE_DONE, do not never return value */ if (dbop->done) return NULL; rc = sqlite3_step(dbop->stmt); if (rc == SQLITE_DONE) goto finish; else if (rc == SQLITE_ROW) { dbop->readcount++; dbop->lastrowid = sqlite3_column_int64(dbop->stmt, 0); key = (char *)sqlite3_column_text(dbop->stmt, 1); dat = (char *)sqlite3_column_text(dbop->stmt, 2); /* skip meta records */ if (!(dbop->openflags & DBOP_RAW)) { if (dbop->ioflags & DBOP_KEY && ismeta(key)) continue; else if (ismeta(dat)) continue; } if (dbop->ioflags & DBOP_KEY) { if (!strcmp(dbop->prev, key)) continue; if (strlen(key) > MAXKEYLEN) die("primary key too long."); strlimcpy(dbop->prev, key, sizeof(dbop->prev)); } if (dbop->ioflags & DBOP_PREFIX) { if (strncmp(key, dbop->key, dbop->keylen)) goto finish; } else if (dbop->keylen) { if (strcmp(key, dbop->key)) goto finish; } if (dbop->preg && regexec(dbop->preg, key, 0, 0, 0) != 0) continue; break; } else { die("dbop3_next: something is wrong (rc = %d).", rc); } } strbuf_clear(dbop->sb); strbuf_puts0(dbop->sb, (char *)sqlite3_column_text(dbop->stmt, 2)); dbop->lastsize = strbuf_getlen(dbop->sb) - 1; dbop->lastflag = (char *)sqlite3_column_text(dbop->stmt, 3); if (dbop->lastflag) strbuf_puts(dbop->sb, dbop->lastflag); dbop->lastdat = strbuf_value(dbop->sb); if (dbop->lastflag) dbop->lastflag = dbop->lastdat + dbop->lastsize + 1; dbop->lastkey = key; dbop->lastkeysize = strlen(dbop->lastkey); if (dbop->ioflags & DBOP_KEY) { strlimcpy(dbop->prev, key, sizeof(dbop->prev)); return key; } return dbop->lastdat; finish: dbop->done = 1; dbop->lastdat = NULL; dbop->lastsize = 0; return dbop->lastdat; }
const char * dbop3_first(DBOP *dbop, const char *name, regex_t *preg, int flags) { int rc; char *key; STRBUF *sql = strbuf_open_tempbuf(); dbop->done = 0; /* This is turned on when it receives SQLITE_DONE. */ strbuf_puts(sql, "select rowid, * from "); strbuf_puts(sql, dbop->tblname); if (name) { strbuf_puts(sql, " where key "); if (dbop->ioflags & DBOP_PREFIX) { /* * In sqlite3, 'like' ignores case. 'glob' does not ignore case. */ strbuf_puts(sql, "glob '"); strbuf_puts(sql, name); strbuf_puts(sql, "*'"); } else { strbuf_puts(sql, "= '"); strbuf_puts(sql, name); strbuf_puts(sql, "'"); } strlimcpy(dbop->key, name, sizeof(dbop->key)); dbop->keylen = strlen(name); } strbuf_puts(sql, " order by key"); if (dbop->stmt) { rc = sqlite3_finalize(dbop->stmt); if (rc != SQLITE_OK) die("dbop3_finalize failed. (rc = %d)", rc); dbop->stmt = NULL; } rc = sqlite3_prepare_v2(dbop->db3, strbuf_value(sql), -1, &dbop->stmt, NULL); if (rc != SQLITE_OK) die("dbop3_first: sqlite3_prepare_v2 failed. (rc = %d)", rc); /* * 0: rowid * 1: key * 2: dat * 3: flags */ for (;;) { /* Once it receives SQLITE_DONE, do not never return value */ if (dbop->done) return NULL; rc = sqlite3_step(dbop->stmt); if (rc == SQLITE_DONE) goto finish; else if (rc == SQLITE_ROW) { dbop->readcount++; dbop->lastrowid = sqlite3_column_int64(dbop->stmt, 0); key = (char *)sqlite3_column_text(dbop->stmt, 1); if (name) { if (dbop->ioflags & DBOP_PREFIX) { if (strncmp(key, dbop->key, dbop->keylen)) goto finish; } else { if (strcmp(key, dbop->key)) goto finish; } if (dbop->preg && regexec(dbop->preg, key, 0, 0, 0) != 0) continue; } else { /* skip meta records */ if (ismeta(key) && !(dbop->openflags & DBOP_RAW)) continue; if (dbop->preg && regexec(dbop->preg, key, 0, 0, 0) != 0) continue; } break; } else { die("dbop3_first: something is wrong (rc = %d).", rc); } } strbuf_clear(dbop->sb); strbuf_puts0(dbop->sb, (char *)sqlite3_column_text(dbop->stmt, 2)); dbop->lastsize = strbuf_getlen(dbop->sb) - 1; dbop->lastflag = (char *)sqlite3_column_text(dbop->stmt, 3); if (dbop->lastflag) strbuf_puts(dbop->sb, dbop->lastflag); dbop->lastdat = strbuf_value(dbop->sb); if (dbop->lastflag) dbop->lastflag = dbop->lastdat + dbop->lastsize + 1; dbop->lastkey = key; dbop->lastkeysize = strlen(dbop->lastkey); strbuf_release_tempbuf(sql); if (flags & DBOP_KEY) { strlimcpy(dbop->prev, key, sizeof(dbop->prev)); return key; } return dbop->lastdat; finish: strbuf_release_tempbuf(sql); dbop->done = 1; dbop->lastdat = NULL; dbop->lastsize = 0; dbop->lastflag = NULL; return dbop->lastdat; }