/* --------------- disks_refresh ----------------------*/ void procinf(GPtrArray * pdisks) { FILE *partitions; char dev[256]; char bdev[256]; char *s; char *w; char *z; char *r; char *b; int i; int j; int ia = pdisks->len; t_disk * pdisk; t_disk * ddisk; r = g_strno(rtdisk(pdisks)); b = g_strno(rbdisk(pdisks)); partitions = fopen ("/proc/partitions", "r"); if (partitions == NULL) {return;} while (getc (partitions) != '\n'); /* skip header */ while (fscanf (partitions, "%s%s%s%s\n", dev, dev, bdev, dev) != EOF) { s = g_strdup(dev); w = g_strdup(bdev); z = g_strconcat("/dev/", s, NULL); if ((g_strlen(w) == 1) && ((g_strchr(w, '1') != NULL) || (g_strchr(w, '0') != NULL))) continue; pdisk = disk_new(z, s); pdisk->is_new = TRUE; g_ptr_array_add( pdisks , pdisk ); } fclose (partitions); for(i=ia;i < pdisks->len;i++) { pdisk = g_ptr_array_index(pdisks,i); if (g_strcmp(g_strno(pdisk->device), r) == 1){ pdisk->is_hide = TRUE; } if (g_strcmp(g_strno(pdisk->device), b) == 1){ pdisk->is_hide = TRUE; } for(j=ia;j < pdisks->len;j++) { if (i == j) continue; ddisk = g_ptr_array_index(pdisks, j); if (g_strcmp(g_strno(pdisk->device), ddisk->device) == 1){ ddisk->mount_point = NULL; ddisk->is_hide = TRUE; // g_print("found! %s %s\n", ddisk->device ,ddisk->mount_point); } } for(j=0;j < ia;j++) { if (i == j) continue; ddisk = g_ptr_array_index(pdisks, j); if (g_strcmp(pdisk->device, ddisk->device) == 1){ pdisk->mount_point = NULL; pdisk->is_hide = TRUE; // g_print("found! %s %s\n", pdisk->device ,pdisk->mount_point); } } } }
/* return exit status of the mount command*/ void disk_umount (t_disk * pdisk, char* umount_command) { if (pdisk != NULL) { char * cmd ; char *a; char *b; char *str = g_strdup(umount_command); if (!g_strchr(str,'$')) { g_free(str); cmd = g_strconcat ("bash -c '", umount_command, " ", pdisk->mount_point, "'", NULL); } else { int i; i = g_strlen(str) - g_strlen(g_strchr(str,'$')); str[i]='\0'; a=g_strdup(str); str[i]='$'; b=g_strdup(g_strchr(str,'$')+1); g_free(str); cmd = g_strconcat ("bash -c '", a, pdisk->mount_point, b, "'", NULL); g_free(a); g_free(b); } /* #ifdef DEBUG g_printf("umount command: %s \n", umount_command); #endif */ /* changed from pdisk->device to pdisk->mount_point */ /* cmd = g_strconcat (umount_command, " ", pdisk->mount_point, NULL); */ /*bresult = g_spawn_command_line_sync(cmd,&standard_output,&standard_error,&exit_status,&error); if (bresult) { if (exit_status) { mount_info_free(&(pdisk->mount_info)); } return exit_status ; } */ /* exec_cmd_silent (cmd, FALSE, FALSE); */ /* ERR("exec-um-cmd %s \n", cmd);*/ g_spawn_command_line_async(cmd, NULL); g_free(cmd); } //return -1 ; }
static int g_charclass(const Char **patternp, Char **bufnextp) { const Char *pattern = *patternp + 1; Char *bufnext = *bufnextp; const Char *colon; struct cclass *cc; size_t len; if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']') return 1; /* not a character class */ len = (size_t)(colon - pattern); for (cc = cclasses; cc->name != NULL; cc++) { if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0') break; } if (cc->name == NULL) return -1; /* invalid character class */ *bufnext++ = M_CLASS; *bufnext++ = (Char)(cc - &cclasses[0]); *bufnextp = bufnext; *patternp += len + 3; return 0; }
int APP_CC process_preamble_packet(struct xrdp_wm *self) { char* line_end; char* t; char* q; char* r; DEBUG(("Preamble %s", self->session->client_info->osirium_preamble_buffer)) line_end = g_strchr(self->session->client_info->osirium_preamble_buffer, '\n'); while (line_end != 0) { q = line_end+1; // locate start of name while ( isspace(*q) ) { q++; } DEBUG(("Preamble still needing processing %s", q)); // locate separator t = r = g_strchr(q,'='); if ( r == 0 ) break; // handle broken preamble by assuming at end of pre *r = 0; // ensure name terminated // strip possible trailing spaces from name while ( isspace(*--t) ) { *t = 0; // nulls to terminate name }; // locate start of value while ( isspace(*++r) ) { // pre increment } line_end = g_strchr(r, '\n'); //locate end of value if (line_end) // may be last value in preamble and have no LF at end. { *line_end = 0; // null terminate value } DEBUG(("Name '%s' Value '%s'", q, r)); list_add_item(self->mm->login_names, (long)g_strdup(q)); list_add_item(self->mm->login_values, (long)g_strdup(r)); } g_free(self->session->client_info->osirium_preamble_buffer); self->session->client_info->osirium_preamble_buffer = 0; xrdp_wm_set_login_mode(self, 2); }
/* return exit status of the mount command*/ void disk_mount (t_disk * pdisk, char* mount_command) { if (pdisk != NULL) { char * cmd ; char *a; char *b; char *str = g_strdup(mount_command); if (!g_strchr(str,'$')) { g_free(str); cmd = g_strconcat ("bash -c '", mount_command, " ", pdisk->mount_point, "'", NULL); } else { int i; i = g_strlen(str) - g_strlen(g_strchr(str,'$')); str[i]='\0'; a=g_strdup(str); str[i]='$'; b=g_strdup(g_strchr(str,'$')+1); g_free(str); cmd = g_strconcat ("bash -c '", a, pdisk->mount_point, b, "'", NULL); g_free(a); g_free(b); } /* cmd = g_strconcat ("bash -c '", mount_command, " ", pdisk->mount_point, NULL); if (on_mount_cmd != NULL) cmd = g_strconcat(cmd," && ",on_mount_cmd," ", pdisk->mount_point, " ' ", NULL); else cmd = g_strconcat(cmd," ' ",NULL); DBG("cmd :%s",cmd); */ /* exec_cmd_silent(cmd,FALSE,FALSE); */ /* ERR("exec-mo-cmd %s \n", cmd); */ g_spawn_command_line_async(cmd, NULL); g_free(cmd); } }
char * rtdisk(GPtrArray * pdisks){ int i;t_disk * pdisk; for(i=0;i < pdisks->len;i++) { pdisk = g_ptr_array_index(pdisks,i); if ((g_strlen(pdisk->mount_point) == 1) && (g_strchr(pdisk->mount_point, '/') != NULL)) {// || (g_strcmp(pdisk->mount_point, "/boot")))) { //g_print("lol %s \n", pdisk->mount_point); pdisk->is_hide = TRUE; return pdisk->device; } } return NULL; }
/* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { const Char* ptr = pattern; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) return glob0(pattern, pglob, limitp); if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) return globexp2(ptr, pattern, pglob, limitp); return glob0(pattern, pglob, limitp); }
/* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob) { const Char* ptr = pattern; int rv; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == CHAR_LBRACE && pattern[1] == CHAR_RBRACE && pattern[2] == CHAR_EOS) return glob0(pattern, pglob); while ((ptr = (const Char *) g_strchr(ptr, CHAR_LBRACE)) != NULL) if (!globexp2(ptr, pattern, pglob, &rv)) return rv; return glob0(pattern, pglob); }
/* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob, size_t *limit) { const Char* ptr = pattern; int rv; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) return glob0(pattern, pglob, limit); while ((ptr = g_strchr(ptr, LBRACE)) != NULL) if (!globexp2(ptr, pattern, pglob, &rv, limit)) return rv; return glob0(pattern, pglob, limit); }
/* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp, int recursion) { const Char* ptr = pattern; if (pglob->gl_maxdepth > 0 && recursion > pglob->gl_maxdepth) { errno = 0; return 0; } /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) { return glob0(pattern, pglob, limitp); } if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) { return globexp2(ptr, pattern, pglob, limitp, recursion + 1); } return glob0(pattern, pglob, limitp); }
/* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1 ( const Char *pattern, glob_t *pglob ) { const Char* ptr = pattern; int rv; ssize_t span; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) return glob0(pattern, pglob); while ((span = g_strchr(ptr, LBRACE)) >= 0) { ptr += span; if (!globexp2(ptr, pattern, pglob, &rv)) return rv; } return glob0(pattern, pglob); }
int bsd_glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) { const U8 *patnext; int c; Char *bufnext, *bufend, patbuf[MAXPATHLEN]; #ifdef MACOS_TRADITIONAL char *new_pat, *p, *np; int err; size_t len; #endif #ifndef MACOS_TRADITIONAL patnext = (U8 *) pattern; #endif /* TODO: GLOB_APPEND / GLOB_DOOFFS aren't supported yet */ #if 0 if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } #else pglob->gl_pathc = 0; pglob->gl_pathv = NULL; pglob->gl_offs = 0; #endif pglob->gl_flags = flags & ~GLOB_MAGCHAR; pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; bufnext = patbuf; bufend = bufnext + MAXPATHLEN - 1; #ifdef DOSISH /* Nasty hack to treat patterns like "C:*" correctly. In this * case, the * should match any file in the current directory * on the C: drive. However, the glob code does not treat the * colon specially, so it looks for files beginning "C:" in * the current directory. To fix this, change the pattern to * add an explicit "./" at the start (just after the drive * letter and colon - ie change to "C:./"). */ if (isalpha(pattern[0]) && pattern[1] == ':' && pattern[2] != BG_SEP && pattern[2] != BG_SEP2 && bufend - bufnext > 4) { *bufnext++ = pattern[0]; *bufnext++ = ':'; *bufnext++ = '.'; *bufnext++ = BG_SEP; patnext += 2; } #endif #ifdef MACOS_TRADITIONAL /* Check if we need to match a volume name (e.g. '*HD:*') */ g_matchVol = false; p = (char *) pattern; if (*p != BG_SEP) { p++; while (*p != BG_EOS) { if (*p == BG_SEP) { g_matchVol = true; break; } p++; } } /* Transform the pattern: * (a) Resolve updirs, e.g. * '*:t*p::' -> '*:' * ':a*:tmp::::' -> '::' * ':base::t*p:::' -> '::' * '*HD::' -> return 0 (error, quit silently) * * (b) Remove a single trailing ':', unless it's a "match volume only" * pattern like '*HD:'; e.g. * '*:tmp:' -> '*:tmp' but * '*HD:' -> '*HD:' * (If we don't do that, even filenames will have a trailing ':' in * the result.) */ /* We operate on a copy of the pattern */ len = strlen(pattern); Newx(new_pat, len + 1, char); if (new_pat == NULL) return (GLOB_NOSPACE); p = (char *) pattern; np = new_pat; while (*np++ = *p++) ; /* Resolve updirs ... */ err = resolve_updirs(new_pat); if (err) { Safefree(new_pat); /* The pattern is incorrect: tried to move up above the volume root, see above. We quit silently. */ return 0; } /* remove trailing colon ... */ remove_trColon(new_pat); patnext = (U8 *) new_pat; #endif /* MACOS_TRADITIONAL */ if (flags & GLOB_QUOTE) { /* Protect the quoted characters. */ while (bufnext < bufend && (c = *patnext++) != BG_EOS) if (c == BG_QUOTE) { #ifdef DOSISH /* To avoid backslashitis on Win32, * we only treat \ as a quoting character * if it precedes one of the * metacharacters []-{}~\ */ if ((c = *patnext++) != '[' && c != ']' && c != '-' && c != '{' && c != '}' && c != '~' && c != '\\') { #else if ((c = *patnext++) == BG_EOS) { #endif c = BG_QUOTE; --patnext; } *bufnext++ = c | M_PROTECT; } else *bufnext++ = c; } else while (bufnext < bufend && (c = *patnext++) != BG_EOS) *bufnext++ = c; *bufnext = BG_EOS; #ifdef MACOS_TRADITIONAL if (flags & GLOB_BRACE) err = globexp1(patbuf, pglob); else err = glob0(patbuf, pglob); Safefree(new_pat); return err; #else if (flags & GLOB_BRACE) return globexp1(patbuf, pglob); else return glob0(patbuf, pglob); #endif } /* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob) { const Char* ptr = pattern; int rv; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == BG_LBRACE && pattern[1] == BG_RBRACE && pattern[2] == BG_EOS) return glob0(pattern, pglob); while ((ptr = (const Char *) g_strchr((Char *) ptr, BG_LBRACE)) != NULL) if (!globexp2(ptr, pattern, pglob, &rv)) return rv; return glob0(pattern, pglob); } /* * Recursive brace globbing helper. Tries to expand a single brace. * If it succeeds then it invokes globexp1 with the new pattern. * If it fails then it tries to glob the rest of the pattern and returns. */ static int globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv) { int i; Char *lm, *ls; const Char *pe, *pm, *pl; Char patbuf[MAXPATHLEN]; /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) ; *lm = BG_EOS; ls = lm; /* Find the balanced brace */ for (i = 0, pe = ++ptr; *pe; pe++) if (*pe == BG_LBRACKET) { /* Ignore everything between [] */ for (pm = pe++; *pe != BG_RBRACKET && *pe != BG_EOS; pe++) ; if (*pe == BG_EOS) { /* * We could not find a matching BG_RBRACKET. * Ignore and just look for BG_RBRACE */ pe = pm; } } else if (*pe == BG_LBRACE) i++; else if (*pe == BG_RBRACE) { if (i == 0) break; i--; } /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == BG_EOS) { *rv = glob0(patbuf, pglob); return 0; } for (i = 0, pl = pm = ptr; pm <= pe; pm++) { switch (*pm) { case BG_LBRACKET: /* Ignore everything between [] */ for (pl = pm++; *pm != BG_RBRACKET && *pm != BG_EOS; pm++) ; if (*pm == BG_EOS) { /* * We could not find a matching BG_RBRACKET. * Ignore and just look for BG_RBRACE */ pm = pl; } break; case BG_LBRACE: i++; break; case BG_RBRACE: if (i) { i--; break; } /* FALLTHROUGH */ case BG_COMMA: if (i && *pm == BG_COMMA) break; else { /* Append the current string */ for (lm = ls; (pl < pm); *lm++ = *pl++) ; /* * Append the rest of the pattern after the * closing brace */ for (pl = pe + 1; (*lm++ = *pl++) != BG_EOS; ) ; /* Expand the current pattern */ #ifdef GLOB_DEBUG qprintf("globexp2:", patbuf); #endif /* GLOB_DEBUG */ *rv = globexp1(patbuf, pglob); /* move after the comma, to the next string */ pl = pm + 1; } break; default: break; } } *rv = 0; return 0; }
/* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. It is not an error * to find no matches. */ static int glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { const Char *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[PATH_MAX]; qpatnext = pattern; oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) { ++qpatnext; } if (*qpatnext == EOS || g_strchr(qpatnext + 1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) { --qpatnext; } break; } *bufnext++ = M_SET; if (c == NOT) { *bufnext++ = M_NOT; } c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) { *bufnext++ = M_ALL; } break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; if ((err = glob1(patbuf, patbuf+PATH_MAX - 1, pglob, limitp, 1)) != 0) { return err; } /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc) { if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) { return globextend(pattern, pglob, limitp, NULL); } else { return GLOB_NOMATCH; } } if (!(pglob->gl_flags & GLOB_NOSORT)) { if ((pglob->gl_flags & GLOB_KEEPSTAT)) { /* Keep the paths and stat info synced during sort */ struct glob_path_stat *path_stat; int i; int n = pglob->gl_pathc - oldpathc; int o = pglob->gl_offs + oldpathc; if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL) { return GLOB_NOSPACE; } for (i = 0; i < n; i++) { path_stat[i].gps_path = pglob->gl_pathv[o + i]; path_stat[i].gps_stat = pglob->gl_statv[o + i]; } qsort(path_stat, n, sizeof(*path_stat), compare_gps); for (i = 0; i < n; i++) { pglob->gl_pathv[o + i] = path_stat[i].gps_path; pglob->gl_statv[o + i] = path_stat[i].gps_stat; } free(path_stat); } else { qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); } } return 0; }
/* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. */ static int glob0(const Char *pattern, glob_t *pglob, size_t *limit) { const Char *qpatnext; int err; size_t oldpathc; Char *bufnext, c, patbuf[MAXPATHLEN]; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, pglob, limit)) != 0) return(err); /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc) { if (((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) return(globextend(pattern, pglob, limit)); else return(GLOB_NOMATCH); } if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return(0); }
/* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. It is not an error * to find no matches. */ static int glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { const Char *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[PATH_MAX]; qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { if (c == LBRACKET && *qpatnext == ':') { do { err = g_charclass(&qpatnext, &bufnext); if (err) break; c = *qpatnext++; } while (c == LBRACKET && *qpatnext == ':'); if (err == -1 && !(pglob->gl_flags & GLOB_NOCHECK)) return GLOB_NOMATCH; if (c == RBRACKET) break; } *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, patbuf + PATH_MAX - 1, pglob, limitp)) != 0) return err; /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified. */ if (pglob->gl_pathc == oldpathc) { if ((pglob->gl_flags & GLOB_NOCHECK)) return globextend(pattern, pglob, limitp, NULL); else return GLOB_NOMATCH; } if (!(pglob->gl_flags & GLOB_NOSORT)) { qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); } return 0; }
/* * expand tilde from the passwd file. */ static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) { struct passwd *pwd; char *h; const Char *p; Char *b, *eb; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return pattern; /* Copy up to the end of the string or / */ eb = &patbuf[patbuf_len - 1]; for (p = pattern + 1, h = (char *) patbuf; h < (char *)eb && *p && *p != SLASH; *h++ = *p++) ; *h = EOS; #if 0 if (h == (char *)eb) return what; #endif if (((char *) patbuf)[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME * first and then trying the password file */ #if 0 if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { #endif if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { if ((pwd = getpwuid(getuid())) == NULL) return pattern; else h = pwd->pw_dir; } } else { /* * Expand a ~user */ if ((pwd = getpwnam((char*) patbuf)) == NULL) return pattern; else h = pwd->pw_dir; } /* Copy the home directory */ for (b = patbuf; b < eb && *h; *b++ = *h++) ; /* Append the rest of the pattern */ while (b < eb && (*b++ = *p++) != EOS) ; *b = EOS; return patbuf; } /* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. It is not an error * to find no matches. */ static int glob0(const Char *pattern, glob_t *pglob) { const Char *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[MAXPATHLEN]; size_t limit = 0; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) return(err); /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc) { if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) return(globextend(pattern, pglob, &limit)); else return(GLOB_NOMATCH); } if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return(0); } static int compare(const void *p, const void *q) { return(strcmp(*(char **)p, *(char **)q)); } static int glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) { Char pathbuf[MAXPATHLEN]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, pathbuf, pathbuf+MAXPATHLEN-1, pattern, pattern_last, pglob, limitp)); }
int bsd_glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) { const U8 *patnext; int c; Char *bufnext, *bufend, patbuf[MAXPATHLEN]; patnext = (U8 *) pattern; /* TODO: GLOB_APPEND / GLOB_DOOFFS aren't supported yet */ #if 0 if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } #else pglob->gl_pathc = 0; pglob->gl_pathv = NULL; pglob->gl_offs = 0; #endif pglob->gl_flags = flags & ~GLOB_MAGCHAR; pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; bufnext = patbuf; bufend = bufnext + MAXPATHLEN - 1; #ifdef DOSISH /* Nasty hack to treat patterns like "C:*" correctly. In this * case, the * should match any file in the current directory * on the C: drive. However, the glob code does not treat the * colon specially, so it looks for files beginning "C:" in * the current directory. To fix this, change the pattern to * add an explicit "./" at the start (just after the drive * letter and colon - ie change to "C:./"). */ if (isalpha(pattern[0]) && pattern[1] == ':' && pattern[2] != BG_SEP && pattern[2] != BG_SEP2 && bufend - bufnext > 4) { *bufnext++ = pattern[0]; *bufnext++ = ':'; *bufnext++ = '.'; *bufnext++ = BG_SEP; patnext += 2; } #endif if (flags & GLOB_QUOTE) { /* Protect the quoted characters. */ while (bufnext < bufend && (c = *patnext++) != BG_EOS) if (c == BG_QUOTE) { #ifdef DOSISH /* To avoid backslashitis on Win32, * we only treat \ as a quoting character * if it precedes one of the * metacharacters []-{}~\ */ if ((c = *patnext++) != '[' && c != ']' && c != '-' && c != '{' && c != '}' && c != '~' && c != '\\') { #else if ((c = *patnext++) == BG_EOS) { #endif c = BG_QUOTE; --patnext; } *bufnext++ = c | M_PROTECT; } else *bufnext++ = c; } else while (bufnext < bufend && (c = *patnext++) != BG_EOS) *bufnext++ = c; *bufnext = BG_EOS; if (flags & GLOB_BRACE) return globexp1(patbuf, pglob); else return glob0(patbuf, pglob); } /* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob) { const Char* ptr = pattern; int rv; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == BG_LBRACE && pattern[1] == BG_RBRACE && pattern[2] == BG_EOS) return glob0(pattern, pglob); while ((ptr = (const Char *) g_strchr((Char *) ptr, BG_LBRACE)) != NULL) if (!globexp2(ptr, pattern, pglob, &rv)) return rv; return glob0(pattern, pglob); } /* * Recursive brace globbing helper. Tries to expand a single brace. * If it succeeds then it invokes globexp1 with the new pattern. * If it fails then it tries to glob the rest of the pattern and returns. */ static int globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv) { int i; Char *lm, *ls; const Char *pe, *pm, *pm1, *pl; Char patbuf[MAXPATHLEN]; /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) ; *lm = BG_EOS; ls = lm; /* Find the balanced brace */ for (i = 0, pe = ++ptr; *pe; pe++) if (*pe == BG_LBRACKET) { /* Ignore everything between [] */ for (pm = pe++; *pe != BG_RBRACKET && *pe != BG_EOS; pe++) ; if (*pe == BG_EOS) { /* * We could not find a matching BG_RBRACKET. * Ignore and just look for BG_RBRACE */ pe = pm; } } else if (*pe == BG_LBRACE) i++; else if (*pe == BG_RBRACE) { if (i == 0) break; i--; } /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == BG_EOS) { *rv = glob0(patbuf, pglob); return 0; } for (i = 0, pl = pm = ptr; pm <= pe; pm++) { switch (*pm) { case BG_LBRACKET: /* Ignore everything between [] */ for (pm1 = pm++; *pm != BG_RBRACKET && *pm != BG_EOS; pm++) ; if (*pm == BG_EOS) { /* * We could not find a matching BG_RBRACKET. * Ignore and just look for BG_RBRACE */ pm = pm1; } break; case BG_LBRACE: i++; break; case BG_RBRACE: if (i) { i--; break; } /* FALLTHROUGH */ case BG_COMMA: if (i && *pm == BG_COMMA) break; else { /* Append the current string */ for (lm = ls; (pl < pm); *lm++ = *pl++) ; /* * Append the rest of the pattern after the * closing brace */ for (pl = pe + 1; (*lm++ = *pl++) != BG_EOS; ) ; /* Expand the current pattern */ #ifdef GLOB_DEBUG qprintf("globexp2:", patbuf); #endif /* GLOB_DEBUG */ *rv = globexp1(patbuf, pglob); /* move after the comma, to the next string */ pl = pm + 1; } break; default: break; } } *rv = 0; return 0; }
/* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. It is not an error * to find no matches. */ static int glob0(const Char *pattern, glob_t *pglob) { const Char *qpat, *qpatnext; int c, err, oldflags, oldpathc; Char *bufnext, patbuf[MAXPATHLEN]; size_t limit = 0; qpat = globtilde(pattern, patbuf, MAXPATHLEN, pglob); qpatnext = qpat; oldflags = pglob->gl_flags; oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != BG_EOS) { switch (c) { case BG_LBRACKET: c = *qpatnext; if (c == BG_NOT) ++qpatnext; if (*qpatnext == BG_EOS || g_strchr((Char *) qpatnext+1, BG_RBRACKET) == NULL) { *bufnext++ = BG_LBRACKET; if (c == BG_NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == BG_NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == BG_RANGE && (c = qpatnext[1]) != BG_RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != BG_RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case BG_QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case BG_STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = BG_EOS; #ifdef GLOB_DEBUG qprintf("glob0:", patbuf); #endif /* GLOB_DEBUG */ if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) { pglob->gl_flags = oldflags; return(err); } /* * If there was no match we are going to append the pattern * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the pattern did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if (pglob->gl_pathc == oldpathc && ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR)))) { #ifdef GLOB_DEBUG printf("calling globextend from glob0\n"); #endif /* GLOB_DEBUG */ pglob->gl_flags = oldflags; return(globextend(qpat, pglob, &limit)); } else if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), (pglob->gl_flags & (GLOB_ALPHASORT|GLOB_NOCASE)) ? ci_compare : compare); pglob->gl_flags = oldflags; return(0); }