void dummy_list_work (MAILSTREAM *stream,char *dir,char *pat,char *contents, long level) { unsigned long i = 1; FILEFINDBUF3 f; HDIR hd = HDIR_CREATE; struct stat sbuf; char tmp[MAILTMPLEN]; /* punt if bogus name */ if (!mailboxdir (tmp,dir,NIL)) return; /* make directory wildcard */ strcat (tmp,(tmp[strlen (tmp) -1] == '\\') ? "*.*" : "\\*.*"); /* do nothing if can't open directory */ if (!DosFindFirst (tmp,&hd,FILE_NORMAL,&f,sizeof (f),&i,FIL_STANDARD)) { /* list it if not at top-level */ if (!level && dir && pmatch_full (dir,pat,'\\')) dummy_listed (stream,'\\',dir,LATT_NOSELECT,contents); /* scan directory */ if (!dir || dir[strlen (dir) -1] == '\\') do { if (((f.name[0] != '.') || (f.name[1] && ((f.name[1] != '.') || f.name[2]))) && (strlen (f.name) <= NETMAXMBX)) { /* see if name is useful */ if (dir) sprintf (tmp,"%s%s",dir,f.name); else strcpy (tmp,f.name); /* make sure useful and can get info */ if ((pmatch_full (tmp,pat,'\\') || pmatch_full (strcat (tmp,"\\"),pat,'\\') || dmatch (tmp,pat,'\\')) && mailboxdir (tmp,dir,f.name) && tmp[0] && !stat (tmp,&sbuf)) { /* now make name we'd return */ if (dir) sprintf (tmp,"%s%s",dir,f.name); else strcpy (tmp,f.name); /* only interested in file type */ switch (sbuf.st_mode & S_IFMT) { case S_IFDIR: /* directory? */ if (pmatch_full (tmp,pat,'\\')) { if (!dummy_listed (stream,'\\',tmp,LATT_NOSELECT,contents))break; strcat (tmp,"\\");/* set up for dmatch call */ } /* try again with trailing \ */ else if (pmatch_full (strcat (tmp,"\\"),pat,'\\') && !dummy_listed (stream,'\\',tmp,LATT_NOSELECT,contents)) break; if (dmatch (tmp,pat,'\\') && (level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL))) dummy_list_work (stream,tmp,pat,contents,level+1); break; case S_IFREG: /* ordinary name */ if (pmatch_full (tmp,pat,'\\') && !pmatch ("INBOX",tmp)) dummy_listed (stream,'\\',tmp,LATT_NOINFERIORS,contents); break; } } } i = 1; } while (!DosFindNext (h,&f,sizeof (f),&i)); } }
void dummy_list_work (MAILSTREAM *stream,char *dir,char *pat,char *contents, long level) { struct _finddata_t f; struct stat sbuf; long fhandle; char tmp[MAILTMPLEN]; size_t len = 0; /* punt if bogus name */ if (!mailboxdir (tmp,dir,NIL)) return; /* make directory wildcard */ strcat (tmp,(tmp[strlen (tmp) -1] == '\\') ? "*.*" : "\\*.*"); /* do nothing if can't open directory */ if ((fhandle = _findfirst (tmp,&f)) >= 0) { /* list it if at top-level */ if (!level && dir && pmatch_full (dir,pat,'\\')) dummy_listed (stream,'\\',dir,LATT_NOSELECT,contents); /* scan directory */ if (!dir || dir[(len = strlen (dir)) - 1] == '\\') do if (((f.name[0] != '.') || (f.name[1] && ((f.name[1] != '.') || f.name[2]))) && ((len + strlen (f.name)) <= NETMAXMBX)) { /* see if name is useful */ if (dir) sprintf (tmp,"%s%s",dir,f.name); else strcpy (tmp,f.name); /* make sure useful and can get info */ if ((pmatch_full (tmp,pat,'\\') || pmatch_full (strcat (tmp,"\\"),pat,'\\') || dmatch (tmp,pat,'\\')) && mailboxdir (tmp,dir,f.name) && tmp[0] && !stat (tmp,&sbuf)) { /* now make name we'd return */ if (dir) sprintf (tmp,"%s%s",dir,f.name); else strcpy (tmp,f.name); /* only interested in file type */ switch (sbuf.st_mode & S_IFMT) { case S_IFDIR: /* directory? */ if (pmatch_full (tmp,pat,'\\')) { if (!dummy_listed (stream,'\\',tmp,LATT_NOSELECT,contents))break; strcat (tmp,"\\");/* set up for dmatch call */ } /* try again with trailing \ */ else if (pmatch_full (strcat (tmp,"\\"),pat,'\\') && !dummy_listed (stream,'\\',tmp,LATT_NOSELECT,contents)) break; if (dmatch (tmp,pat,'\\') && (level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL))) dummy_list_work (stream,tmp,pat,contents,level+1); break; case S_IFREG: /* ordinary name */ if (pmatch_full (tmp,pat,'\\') && !pmatch ("INBOX",tmp)) dummy_listed (stream,'\\',tmp,LATT_NOINFERIORS,contents); break; } } } while (!_findnext (fhandle,&f)); _findclose(fhandle); } }
static List *lglob(List *s, char *p, char *m, size_t slashcount) { List *q, *r, *top, foo; static struct { List l; size_t size; } slash; if (slashcount+1 > slash.size) { slash.size = 2*(slashcount+1); slash.l.w = erealloc(slash.l.w, slash.size); } slash.l.w[slashcount] = '\0'; while (slashcount > 0) slash.l.w[--slashcount] = '/'; for (top = r = NULL; s != NULL; s = s->n) { q = dmatch(s->w, p, m); if (q != NULL) { foo.w = s->w; foo.m = NULL; foo.n = NULL; if (!(s->w[0] == '/' && s->w[1] == '\0')) /* need to separate */ q = concat(&slash.l, q); /* dir/name with slash */ q = concat(&foo, q); if (r == NULL) top = r = q; else r->n = q; while (r->n != NULL) r = r->n; } } return top; }
void device_register(device_t dev, void *aux) { device_t isaboot, pciboot; isaboot = device_isa_register(dev, aux); pciboot = device_pci_register(dev, aux); if (isaboot == NULL && pciboot == NULL) return; if (booted_device != NULL) { /* XXX should be a panic() */ dmatch(__func__, dev); } else booted_device = (isaboot != NULL) ? isaboot : pciboot; }
static List *doglob(char *w, char *m) { static char *dir = NULL, *pattern = NULL, *metadir = NULL, *metapattern = NULL; static size_t dsize = 0; char *d, *p, *md, *mp; size_t psize; char *s = w; List firstdir; List *matched; if ((psize = strlen(w) + 1) > dsize || dir == NULL) { efree(dir); efree(pattern); efree(metadir); efree(metapattern); dir = ealloc(psize); pattern = ealloc(psize); metadir = ealloc(psize); metapattern = ealloc(psize); dsize = psize; } d = dir; p = pattern; md = metadir; mp = metapattern; while (*s != '/' && *s != '\0') { *d++ = *s++; /* get first directory component */ *md++ = *m++; } *d = '\0'; /* Special case: no slashes in the pattern, i.e., open the current directory. Remember that w cannot consist of slashes alone (the other way *s could be zero) since doglob gets called iff there's a metacharacter to be matched */ if (*s == '\0') { matched = dmatch(".", dir, metadir); goto end; } if (*w == '/') { firstdir.w = dir; firstdir.m = metadir; firstdir.n = NULL; matched = &firstdir; } else { /* we must glob against current directory, since the first character is not a slash. */ matched = dmatch(".", dir, metadir); } do { size_t slashcount; sigchk(); for (slashcount = 0; *s == '/'; s++, m++) slashcount++; /* skip slashes */ while (*s != '/' && *s != '\0') *p++ = *s++, *mp++ = *m++; /* get pattern */ *p = '\0'; matched = lglob(matched, pattern, metapattern, slashcount); p = pattern, mp = metapattern; } while (*s != '\0'); end: if (matched == NULL) { matched = nnew(List); matched->w = w; matched->m = NULL; matched->n = NULL; } return matched; }
/* * Attempt to find the device from which we were booted. If we can do so, * and not instructed not to do so, change rootdev to correspond to the * load device. */ static void findroot(void) { struct btinfo_rootdevice *biv; struct btinfo_bootdisk *bid; struct btinfo_bootwedge *biw; struct btinfo_biosgeom *big; device_t dv; deviter_t di; if (booted_device) return; if (lookup_bootinfo(BTINFO_NETIF) != NULL) { /* * We got netboot interface information, but device_register() * failed to match it to a configured device. Boot disk * information cannot be present at the same time, so give * up. */ printf("%s: netboot interface not found.\n", __func__); return; } if ((biv = lookup_bootinfo(BTINFO_ROOTDEVICE)) != NULL) { for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { cfdata_t cd; size_t len; if (device_class(dv) != DV_DISK) continue; cd = device_cfdata(dv); len = strlen(cd->cf_name); if (strncmp(cd->cf_name, biv->devname, len) == 0 && biv->devname[len] - '0' == device_unit(dv)) { booted_device = dv; booted_partition = biv->devname[len + 1] - 'a'; booted_nblks = 0; break; } } DPRINTF(("%s: BTINFO_ROOTDEVICE %s\n", __func__, booted_device ? device_xname(booted_device) : "not found")); deviter_release(&di); if (dv != NULL) return; } bid = lookup_bootinfo(BTINFO_BOOTDISK); biw = lookup_bootinfo(BTINFO_BOOTWEDGE); if (biw != NULL) { /* * Scan all disk devices for ones that match the passed data. * Don't break if one is found, to get possible multiple * matches - for problem tracking. Use the first match anyway * because lower devices numbers are more likely to be the * boot device. */ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (is_valid_disk(dv)) { /* * Don't trust BIOS device numbers, try * to match the information passed by the * boot loader instead. */ if ((biw->biosdev & 0x80) == 0 || match_bootwedge(dv, biw) == 0) continue; goto bootwedge_found; } continue; bootwedge_found: if (booted_device) { dmatch(__func__, dv); continue; } booted_device = dv; booted_partition = bid != NULL ? bid->partition : 0; booted_nblks = biw->nblks; booted_startblk = biw->startblk; } deviter_release(&di); DPRINTF(("%s: BTINFO_BOOTWEDGE %s\n", __func__, booted_device ? device_xname(booted_device) : "not found")); if (booted_nblks) return; } if (bid != NULL) { /* * Scan all disk devices for ones that match the passed data. * Don't break if one is found, to get possible multiple * matches - for problem tracking. Use the first match anyway * because lower device numbers are more likely to be the * boot device. */ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (device_is_a(dv, "fd") && device_class(dv) == DV_DISK) { /* * Assume the configured unit number matches * the BIOS device number. (This is the old * behavior.) Needs some ideas how to handle * the BIOS's "swap floppy drive" options. */ /* XXX device_unit() abuse */ if ((bid->biosdev & 0x80) != 0 || device_unit(dv) != bid->biosdev) continue; goto bootdisk_found; } if (is_valid_disk(dv)) { /* * Don't trust BIOS device numbers, try * to match the information passed by the * boot loader instead. */ if ((bid->biosdev & 0x80) == 0 || match_bootdisk(dv, bid) == 0) continue; goto bootdisk_found; } continue; bootdisk_found: if (booted_device) { dmatch(__func__, dv); continue; } booted_device = dv; booted_partition = bid->partition; booted_nblks = 0; } deviter_release(&di); DPRINTF(("%s: BTINFO_BOOTDISK %s\n", __func__, booted_device ? device_xname(booted_device) : "not found")); if (booted_device) return; /* * No booted device found; check CD-ROM boot at last. * * Our bootloader assumes CD-ROM boot if biosdev is larger * or equal than the number of hard drives recognized by the * BIOS. The number of drives can be found in BTINFO_BIOSGEOM * here. For example, if we have wd0, wd1, and cd0: * * big->num = 2 (for wd0 and wd1) * bid->biosdev = 0x80 (wd0) * bid->biosdev = 0x81 (wd1) * bid->biosdev = 0x82 (cd0) * * See src/sys/arch/i386/stand/boot/devopen.c and * src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c . */ if ((big = lookup_bootinfo(BTINFO_BIOSGEOM)) != NULL && bid->biosdev >= 0x80 + big->num) { /* * XXX * There is no proper way to detect which unit is * recognized as a bootable CD-ROM drive by the BIOS. * Assume the first unit is the one. */ for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL; dv = deviter_next(&di)) { if (device_class(dv) == DV_DISK && device_is_a(dv, "cd")) { booted_device = dv; booted_partition = 0; booted_nblks = 0; break; } } deviter_release(&di); DPRINTF(("%s: BTINFO_BIOSGEOM %s\n", __func__, booted_device ? device_xname(booted_device) : "not found")); } } }