plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

util.c (2697B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <auth.h>
      4 #include <fcall.h>
      5 #include <bio.h>
      6 #include "tapefs.h"
      7 
      8 Idmap *
      9 getpass(char *file)
     10 {
     11 	Biobuf *bp;
     12 	char *cp;
     13 	Idmap *up;
     14 	int nid, maxid;
     15 	char *line[4];
     16 
     17 	if ((bp = Bopen(file, OREAD)) == 0)
     18 		error("Can't open passwd/group");
     19 	up = emalloc(1*sizeof(Idmap));
     20 	maxid = 1;
     21 	nid = 0;
     22 	while ((cp = Brdline(bp, '\n'))) {
     23 		int nf;
     24 		cp[Blinelen(bp)-1] = 0;
     25 		nf = getfields(cp, line, 3, 0, ":\n");
     26 		if (nf<3) {
     27 			fprint(2, "bad format in %s\n", file);
     28 			break;
     29 		}
     30 		if (nid>=maxid) {
     31 			maxid *= 2;
     32 			up = (Idmap *)erealloc(up, maxid*sizeof(Idmap));
     33 		}
     34 		up[nid].id = atoi(line[2]);
     35 		up[nid].name = strdup(line[0]);
     36 		nid++;
     37 	}
     38 	Bterm(bp);
     39 	up[nid].name = 0;
     40 	return up;
     41 }
     42 
     43 char *
     44 mapid(Idmap *up, int id)
     45 {
     46 	char buf[16];
     47 
     48 	if (up)
     49 		while (up->name){
     50 			if (up->id==id)
     51 				return strdup(up->name);
     52 			up++;
     53 		}
     54 	sprint(buf, "%d", id);
     55 	return strdup(buf);
     56 }
     57 
     58 Ram *
     59 poppath(Fileinf fi, int new)
     60 {
     61 	char *suffix;
     62 	Ram *dir, *ent;
     63 	Fileinf f;
     64 
     65 	if (*fi.name=='\0')
     66 		return 0;
     67 	if (suffix=strrchr(fi.name, '/')){
     68 		*suffix = 0;
     69 		suffix++;
     70 		if (*suffix=='\0'){
     71 			fi.mode |= DMDIR;
     72 			return poppath(fi, 1);
     73 		}
     74 		f = fi;
     75 		f.size = 0;
     76 		f.addr = 0;
     77 		f.mode = 0555|DMDIR;
     78 		dir = poppath(f, 0);
     79 		if (dir==0)
     80 			dir = ram;
     81 	} else {
     82 		suffix = fi.name;
     83 		dir = ram;
     84 		if (strcmp(suffix, ".")==0)
     85 			return dir;
     86 	}
     87 	ent = lookup(dir, suffix);
     88 	fi.mode |= 0400;			/* at least user read */
     89 	if (ent){
     90 		if (((fi.mode&DMDIR)!=0) != ((ent->qid.type&QTDIR)!=0)){
     91 			fprint(2, "%s/%s directory botch\n", fi.name, suffix);
     92 			exits("");
     93 		}
     94 		if (new)  {
     95 			ent->ndata = fi.size;
     96 			ent->addr = fi.addr;
     97 			ent->data = fi.data;
     98 			ent->perm = fi.mode;
     99 			ent->mtime = fi.mdate;
    100 			ent->user = mapid(uidmap, fi.uid);
    101 			ent->group = mapid(gidmap, fi.gid);
    102 		}
    103 	} else {
    104 		fi.name = suffix;
    105 		ent = popfile(dir, fi);
    106 	}
    107 	return ent;
    108 }
    109 
    110 Ram *
    111 popfile(Ram *dir, Fileinf fi)
    112 {
    113 	Ram *ent = (Ram *)emalloc(sizeof(Ram));
    114 	if (*fi.name=='\0')
    115 		return 0;
    116 	ent->busy = 1;
    117 	ent->open = 0;
    118 	ent->parent = dir;
    119 	ent->next = dir->child;
    120 	dir->child = ent;
    121 	ent->child = 0;
    122 	ent->qid.path = ++path;
    123 	ent->qid.vers = 0;
    124 	if(fi.mode&DMDIR)
    125 		ent->qid.type = QTDIR;
    126 	else
    127 		ent->qid.type = QTFILE;
    128 	ent->perm = fi.mode;
    129 	ent->name = estrdup(fi.name);
    130 	ent->atime = ent->mtime = fi.mdate;
    131 	ent->user = mapid(uidmap, fi.uid);
    132 	ent->group = mapid(gidmap, fi.gid);
    133 	ent->ndata = fi.size;
    134 	ent->data = fi.data;
    135 	ent->addr = fi.addr;
    136 	ent->replete |= replete;
    137 	return ent;
    138 }
    139 
    140 Ram *
    141 lookup(Ram *dir, char *name)
    142 {
    143 	Ram *r;
    144 
    145 	if (dir==0)
    146 		return 0;
    147 	for (r=dir->child; r; r=r->next){
    148 		if (r->busy==0 || strcmp(r->name, name)!=0)
    149 			continue;
    150 		return r;
    151 	}
    152 	return 0;
    153 }