Blame


1 7285a491 2004-06-17 devnull #include <u.h>
2 7285a491 2004-06-17 devnull #include <libc.h>
3 7285a491 2004-06-17 devnull #include <bio.h>
4 7285a491 2004-06-17 devnull #include <libsec.h>
5 7285a491 2004-06-17 devnull
6 7285a491 2004-06-17 devnull #include "iso9660.h"
7 7285a491 2004-06-17 devnull
8 7285a491 2004-06-17 devnull void
9 7285a491 2004-06-17 devnull mkdirec(Direc *direc, XDir *d)
10 7285a491 2004-06-17 devnull {
11 7285a491 2004-06-17 devnull memset(direc, 0, sizeof(Direc));
12 7285a491 2004-06-17 devnull direc->name = atom(d->name);
13 7285a491 2004-06-17 devnull direc->uid = atom(d->uid);
14 7285a491 2004-06-17 devnull direc->gid = atom(d->gid);
15 7285a491 2004-06-17 devnull direc->uidno = d->uidno;
16 7285a491 2004-06-17 devnull direc->gidno = d->gidno;
17 7285a491 2004-06-17 devnull direc->mode = d->mode;
18 7285a491 2004-06-17 devnull direc->length = d->length;
19 7285a491 2004-06-17 devnull direc->mtime = d->mtime;
20 7285a491 2004-06-17 devnull direc->atime = d->atime;
21 7285a491 2004-06-17 devnull direc->ctime = d->ctime;
22 7285a491 2004-06-17 devnull direc->symlink = d->symlink;
23 7285a491 2004-06-17 devnull }
24 7285a491 2004-06-17 devnull
25 7285a491 2004-06-17 devnull static int
26 7285a491 2004-06-17 devnull strecmp(char *a, char *ea, char *b)
27 7285a491 2004-06-17 devnull {
28 7285a491 2004-06-17 devnull int r;
29 7285a491 2004-06-17 devnull
30 7285a491 2004-06-17 devnull if((r = strncmp(a, b, ea-a)) != 0)
31 7285a491 2004-06-17 devnull return r;
32 7285a491 2004-06-17 devnull
33 7285a491 2004-06-17 devnull if(b[ea-a] == '\0')
34 7285a491 2004-06-17 devnull return 0;
35 7285a491 2004-06-17 devnull return 1;
36 7285a491 2004-06-17 devnull }
37 7285a491 2004-06-17 devnull
38 7285a491 2004-06-17 devnull /*
39 7285a491 2004-06-17 devnull * Binary search a list of directories for the
40 7285a491 2004-06-17 devnull * entry with name name.
41 7285a491 2004-06-17 devnull * If no entry is found, return a pointer to
42 7285a491 2004-06-17 devnull * where a new such entry would go.
43 7285a491 2004-06-17 devnull */
44 7285a491 2004-06-17 devnull static Direc*
45 7285a491 2004-06-17 devnull dbsearch(char *name, int nname, Direc *d, int n)
46 7285a491 2004-06-17 devnull {
47 7285a491 2004-06-17 devnull int i;
48 7285a491 2004-06-17 devnull
49 7285a491 2004-06-17 devnull while(n > 0) {
50 7285a491 2004-06-17 devnull i = strecmp(name, name+nname, d[n/2].name);
51 7285a491 2004-06-17 devnull if(i < 0)
52 7285a491 2004-06-17 devnull n = n/2;
53 7285a491 2004-06-17 devnull else if(i > 0) {
54 7285a491 2004-06-17 devnull d += n/2+1;
55 7285a491 2004-06-17 devnull n -= (n/2+1);
56 7285a491 2004-06-17 devnull } else
57 7285a491 2004-06-17 devnull return &d[n/2];
58 7285a491 2004-06-17 devnull }
59 7285a491 2004-06-17 devnull return d;
60 7285a491 2004-06-17 devnull }
61 7285a491 2004-06-17 devnull
62 7285a491 2004-06-17 devnull /*
63 7285a491 2004-06-17 devnull * Walk to name, starting at d.
64 7285a491 2004-06-17 devnull */
65 7285a491 2004-06-17 devnull Direc*
66 7285a491 2004-06-17 devnull walkdirec(Direc *d, char *name)
67 7285a491 2004-06-17 devnull {
68 7285a491 2004-06-17 devnull char *p, *nextp, *slashp;
69 7285a491 2004-06-17 devnull Direc *nd;
70 7285a491 2004-06-17 devnull
71 7285a491 2004-06-17 devnull for(p=name; p && *p; p=nextp) {
72 7285a491 2004-06-17 devnull if((slashp = strchr(p, '/')) != nil)
73 7285a491 2004-06-17 devnull nextp = slashp+1;
74 7285a491 2004-06-17 devnull else
75 7285a491 2004-06-17 devnull nextp = slashp = p+strlen(p);
76 7285a491 2004-06-17 devnull
77 7285a491 2004-06-17 devnull nd = dbsearch(p, slashp-p, d->child, d->nchild);
78 7285a491 2004-06-17 devnull if(nd >= d->child+d->nchild || strecmp(p, slashp, nd->name) != 0)
79 7285a491 2004-06-17 devnull return nil;
80 7285a491 2004-06-17 devnull d = nd;
81 7285a491 2004-06-17 devnull }
82 7285a491 2004-06-17 devnull return d;
83 7285a491 2004-06-17 devnull }
84 7285a491 2004-06-17 devnull
85 7285a491 2004-06-17 devnull /*
86 7285a491 2004-06-17 devnull * Add the file ``name'' with attributes d to the
87 7285a491 2004-06-17 devnull * directory ``root''. Name may contain multiple
88 7285a491 2004-06-17 devnull * elements; all but the last must exist already.
89 7285a491 2004-06-17 devnull *
90 7285a491 2004-06-17 devnull * The child lists are kept sorted by utfname.
91 7285a491 2004-06-17 devnull */
92 7285a491 2004-06-17 devnull Direc*
93 7285a491 2004-06-17 devnull adddirec(Direc *root, char *name, XDir *d)
94 7285a491 2004-06-17 devnull {
95 7285a491 2004-06-17 devnull char *p;
96 7285a491 2004-06-17 devnull Direc *nd;
97 7285a491 2004-06-17 devnull int off;
98 7285a491 2004-06-17 devnull
99 7285a491 2004-06-17 devnull if(name[0] == '/')
100 7285a491 2004-06-17 devnull name++;
101 7285a491 2004-06-17 devnull if((p = strrchr(name, '/')) != nil) {
102 7285a491 2004-06-17 devnull *p = '\0';
103 7285a491 2004-06-17 devnull root = walkdirec(root, name);
104 7285a491 2004-06-17 devnull if(root == nil) {
105 7285a491 2004-06-17 devnull sysfatal("error in proto file: no entry for /%s but /%s/%s\n", name, name, p+1);
106 7285a491 2004-06-17 devnull return nil;
107 7285a491 2004-06-17 devnull }
108 7285a491 2004-06-17 devnull *p = '/';
109 7285a491 2004-06-17 devnull p++;
110 7285a491 2004-06-17 devnull } else
111 7285a491 2004-06-17 devnull p = name;
112 7285a491 2004-06-17 devnull
113 7285a491 2004-06-17 devnull nd = dbsearch(p, strlen(p), root->child, root->nchild);
114 7285a491 2004-06-17 devnull off = nd - root->child;
115 7285a491 2004-06-17 devnull if(off < root->nchild && strcmp(nd->name, p) == 0) {
116 7285a491 2004-06-17 devnull if ((d->mode & DMDIR) == 0)
117 7285a491 2004-06-17 devnull fprint(2, "warning: proto lists %s twice\n", name);
118 7285a491 2004-06-17 devnull return nil;
119 7285a491 2004-06-17 devnull }
120 7285a491 2004-06-17 devnull
121 7285a491 2004-06-17 devnull if(root->nchild%Ndirblock == 0) {
122 7285a491 2004-06-17 devnull root->child = erealloc(root->child, (root->nchild+Ndirblock)*sizeof(Direc));
123 7285a491 2004-06-17 devnull nd = root->child + off;
124 7285a491 2004-06-17 devnull }
125 7285a491 2004-06-17 devnull
126 7285a491 2004-06-17 devnull memmove(nd+1, nd, (root->nchild - off)*sizeof(Direc));
127 7285a491 2004-06-17 devnull mkdirec(nd, d);
128 7285a491 2004-06-17 devnull nd->name = atom(p);
129 7285a491 2004-06-17 devnull root->nchild++;
130 7285a491 2004-06-17 devnull return nd;
131 7285a491 2004-06-17 devnull }
132 7285a491 2004-06-17 devnull
133 7285a491 2004-06-17 devnull /*
134 7285a491 2004-06-17 devnull * Copy the tree src into dst.
135 7285a491 2004-06-17 devnull */
136 7285a491 2004-06-17 devnull void
137 7285a491 2004-06-17 devnull copydirec(Direc *dst, Direc *src)
138 7285a491 2004-06-17 devnull {
139 7285a491 2004-06-17 devnull int i, n;
140 7285a491 2004-06-17 devnull
141 7285a491 2004-06-17 devnull *dst = *src;
142 7285a491 2004-06-17 devnull
143 7285a491 2004-06-17 devnull if((src->mode & DMDIR) == 0)
144 7285a491 2004-06-17 devnull return;
145 7285a491 2004-06-17 devnull
146 7285a491 2004-06-17 devnull n = (src->nchild + Ndirblock - 1);
147 7285a491 2004-06-17 devnull n -= n%Ndirblock;
148 7285a491 2004-06-17 devnull dst->child = emalloc(n*sizeof(Direc));
149 7285a491 2004-06-17 devnull
150 7285a491 2004-06-17 devnull n = dst->nchild;
151 7285a491 2004-06-17 devnull for(i=0; i<n; i++)
152 7285a491 2004-06-17 devnull copydirec(&dst->child[i], &src->child[i]);
153 7285a491 2004-06-17 devnull }
154 7285a491 2004-06-17 devnull
155 7285a491 2004-06-17 devnull /*
156 7285a491 2004-06-17 devnull * Turn the Dbadname flag on for any entries
157 7285a491 2004-06-17 devnull * that have non-conforming names.
158 7285a491 2004-06-17 devnull */
159 7285a491 2004-06-17 devnull static void
160 7285a491 2004-06-17 devnull _checknames(Direc *d, int (*isbadname)(char*), int isroot)
161 7285a491 2004-06-17 devnull {
162 7285a491 2004-06-17 devnull int i;
163 7285a491 2004-06-17 devnull
164 7285a491 2004-06-17 devnull if(!isroot && isbadname(d->name))
165 7285a491 2004-06-17 devnull d->flags |= Dbadname;
166 7285a491 2004-06-17 devnull
167 7285a491 2004-06-17 devnull if(strcmp(d->name, "_conform.map") == 0)
168 7285a491 2004-06-17 devnull d->flags |= Dbadname;
169 7285a491 2004-06-17 devnull
170 7285a491 2004-06-17 devnull for(i=0; i<d->nchild; i++)
171 7285a491 2004-06-17 devnull _checknames(&d->child[i], isbadname, 0);
172 7285a491 2004-06-17 devnull }
173 7285a491 2004-06-17 devnull
174 7285a491 2004-06-17 devnull void
175 7285a491 2004-06-17 devnull checknames(Direc *d, int (*isbadname)(char*))
176 7285a491 2004-06-17 devnull {
177 7285a491 2004-06-17 devnull _checknames(d, isbadname, 1);
178 7285a491 2004-06-17 devnull }
179 7285a491 2004-06-17 devnull
180 7285a491 2004-06-17 devnull /*
181 7285a491 2004-06-17 devnull * Set the names to conform to 8.3
182 7285a491 2004-06-17 devnull * by changing them to numbers.
183 7285a491 2004-06-17 devnull * Plan 9 gets the right names from its
184 7285a491 2004-06-17 devnull * own directory entry.
185 7285a491 2004-06-17 devnull *
186 7285a491 2004-06-17 devnull * We used to write a _conform.map file to translate
187 7285a491 2004-06-17 devnull * names. Joliet should take care of most of the
188 7285a491 2004-06-17 devnull * interoperability with other systems now.
189 7285a491 2004-06-17 devnull */
190 7285a491 2004-06-17 devnull void
191 7285a491 2004-06-17 devnull convertnames(Direc *d, char* (*cvt)(char*, char*))
192 7285a491 2004-06-17 devnull {
193 7285a491 2004-06-17 devnull int i;
194 7285a491 2004-06-17 devnull char new[1024];
195 7285a491 2004-06-17 devnull
196 7285a491 2004-06-17 devnull if(d->flags & Dbadname)
197 7285a491 2004-06-17 devnull cvt(new, conform(d->name, d->mode & DMDIR));
198 7285a491 2004-06-17 devnull else
199 7285a491 2004-06-17 devnull cvt(new, d->name);
200 7285a491 2004-06-17 devnull d->confname = atom(new);
201 7285a491 2004-06-17 devnull
202 7285a491 2004-06-17 devnull for(i=0; i<d->nchild; i++)
203 7285a491 2004-06-17 devnull convertnames(&d->child[i], cvt);
204 7285a491 2004-06-17 devnull }
205 7285a491 2004-06-17 devnull
206 7285a491 2004-06-17 devnull /*
207 7285a491 2004-06-17 devnull * Sort a directory with a given comparison function.
208 7285a491 2004-06-17 devnull * After this is called on a tree, adddirec should not be,
209 7285a491 2004-06-17 devnull * since the entries may no longer be sorted as adddirec expects.
210 7285a491 2004-06-17 devnull */
211 7285a491 2004-06-17 devnull void
212 7285a491 2004-06-17 devnull dsort(Direc *d, int (*cmp)(const void*, const void*))
213 7285a491 2004-06-17 devnull {
214 7285a491 2004-06-17 devnull int i, n;
215 7285a491 2004-06-17 devnull
216 7285a491 2004-06-17 devnull n = d->nchild;
217 7285a491 2004-06-17 devnull qsort(d->child, n, sizeof(d[0]), cmp);
218 7285a491 2004-06-17 devnull
219 7285a491 2004-06-17 devnull for(i=0; i<n; i++)
220 7285a491 2004-06-17 devnull dsort(&d->child[i], cmp);
221 7285a491 2004-06-17 devnull }
222 7285a491 2004-06-17 devnull