Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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, *origname;
62
	Ram *dir, *ent;
63
	Fileinf f;
64
 
65
	if (*fi.name=='\0')
66
		return 0;
67
	origname = estrdup(fi.name);
68
	if (suffix=strrchr(fi.name, '/')){
69
		*suffix = 0;
70
		suffix++;
71
		if (*suffix=='\0'){
72
			fi.mode |= DMDIR;
73
			free(origname);
74
			return poppath(fi, 1);
75
		}
76
		/*
77
		 * create parent directory of suffix;
78
		 * may recurse, thus shortening fi.name even further.
79
		 */
80
		f = fi;
81
		f.size = 0;
82
		f.addr = 0;
83
		f.mode = 0555|DMDIR;
84
		dir = poppath(f, 0);
85
		if (dir==0)
86
			dir = ram;
87
	} else {
88
		suffix = fi.name;
89
		dir = ram;
90
		if (strcmp(suffix, ".")==0) {
91
			free(origname);
92
			return dir;
93
		}
94
	}
95
	ent = lookup(dir, suffix);
96
	fi.mode |= 0400;			/* at least user read */
97
	if (ent){
98
		if (((fi.mode&DMDIR)!=0) != ((ent->qid.type&QTDIR)!=0)){
99
			fprint(2,
100
		"%s file type changed; probably due to union dir.; ignoring\n",
101
				origname);
102
			free(origname);
103
			return ent;
104
		}
105
		if (new)  {
106
			ent->ndata = fi.size;
107
			ent->addr = fi.addr;
108
			ent->data = fi.data;
109
			ent->perm = fi.mode;
110
			ent->mtime = fi.mdate;
111
			ent->user = mapid(uidmap, fi.uid);
112
			ent->group = mapid(gidmap, fi.gid);
113
		}
114
	} else {
115
		fi.name = suffix;
116
		ent = popfile(dir, fi);
117
	}
118
	free(origname);
119
	return ent;
120
}
121
 
122
Ram *
123
popfile(Ram *dir, Fileinf fi)
124
{
125
	Ram *ent = (Ram *)emalloc(sizeof(Ram));
126
	if (*fi.name=='\0')
127
		return 0;
128
	ent->busy = 1;
129
	ent->open = 0;
130
	ent->parent = dir;
131
	ent->next = dir->child;
132
	dir->child = ent;
133
	ent->child = 0;
134
	ent->qid.path = ++path;
135
	ent->qid.vers = 0;
136
	if(fi.mode&DMDIR)
137
		ent->qid.type = QTDIR;
138
	else
139
		ent->qid.type = QTFILE;
140
	ent->perm = fi.mode;
141
	ent->name = estrdup(fi.name);
142
	ent->atime = ent->mtime = fi.mdate;
143
	ent->user = mapid(uidmap, fi.uid);
144
	ent->group = mapid(gidmap, fi.gid);
145
	ent->ndata = fi.size;
146
	ent->data = fi.data;
147
	ent->addr = fi.addr;
148
	ent->replete |= replete;
149
	return ent;
150
}
151
 
152
Ram *
153
lookup(Ram *dir, char *name)
154
{
155
	Ram *r;
156
 
157
	if (dir==0)
158
		return 0;
159
	for (r=dir->child; r; r=r->next){
160
		if (r->busy==0 || strcmp(r->name, name)!=0)
161
			continue;
162
		return r;
163
	}
164
	return 0;
165
}