Blame


1 18824b58 2008-08-03 rsc #include "a.h"
2 18824b58 2008-08-03 rsc
3 18824b58 2008-08-03 rsc enum
4 18824b58 2008-08-03 rsc {
5 18824b58 2008-08-03 rsc Qroot = 0, // /smug/
6 18824b58 2008-08-03 rsc Qctl, // /smug/ctl
7 18824b58 2008-08-03 rsc Qrpclog, // /smug/rpclog
8 18824b58 2008-08-03 rsc Quploads, // /smug/uploads
9 18824b58 2008-08-03 rsc Qnick, // /smug/nick/
10 18824b58 2008-08-03 rsc Qnickctl, // /smug/nick/ctl
11 18824b58 2008-08-03 rsc Qalbums, // /smug/nick/albums/
12 18824b58 2008-08-03 rsc Qalbumsctl, // /smug/nick/albums/ctl
13 18824b58 2008-08-03 rsc Qcategory, // /smug/nick/Category/
14 18824b58 2008-08-03 rsc Qcategoryctl, // /smug/nick/Category/ctl
15 18824b58 2008-08-03 rsc Qalbum, // /smug/nick/Category/Album/
16 18824b58 2008-08-03 rsc Qalbumctl, // /smug/nick/Category/Album/ctl
17 18824b58 2008-08-03 rsc Qalbumsettings, // /smug/nick/Category/Album/settings
18 18824b58 2008-08-03 rsc Quploadfile, // /smug/nick/Category/Album/upload/file.jpg
19 18824b58 2008-08-03 rsc Qimage, // /smug/nick/Category/Album/Image/
20 18824b58 2008-08-03 rsc Qimagectl, // /smug/nick/Category/Album/Image/ctl
21 18824b58 2008-08-03 rsc Qimageexif, // /smug/nick/Category/Album/Image/exif
22 18824b58 2008-08-03 rsc Qimagesettings, // /smug/nick/Category/Album/Image/settings
23 18824b58 2008-08-03 rsc Qimageurl, // /smug/nick/Category/Album/Image/url
24 18824b58 2008-08-03 rsc Qimagefile, // /smug/nick/Category/Album/Image/file.jpg
25 18824b58 2008-08-03 rsc };
26 18824b58 2008-08-03 rsc
27 18824b58 2008-08-03 rsc void
28 18824b58 2008-08-03 rsc mylock(Lock *lk)
29 18824b58 2008-08-03 rsc {
30 18824b58 2008-08-03 rsc lock(lk);
31 18824b58 2008-08-03 rsc fprint(2, "locked from %p\n", getcallerpc(&lk));
32 18824b58 2008-08-03 rsc }
33 18824b58 2008-08-03 rsc
34 18824b58 2008-08-03 rsc void
35 18824b58 2008-08-03 rsc myunlock(Lock *lk)
36 18824b58 2008-08-03 rsc {
37 18824b58 2008-08-03 rsc unlock(lk);
38 18824b58 2008-08-03 rsc fprint(2, "unlocked from %p\n", getcallerpc(&lk));
39 18824b58 2008-08-03 rsc }
40 18824b58 2008-08-03 rsc
41 18824b58 2008-08-03 rsc //#define lock mylock
42 18824b58 2008-08-03 rsc //#define unlock myunlock
43 18824b58 2008-08-03 rsc
44 18824b58 2008-08-03 rsc typedef struct Upload Upload;
45 18824b58 2008-08-03 rsc
46 18824b58 2008-08-03 rsc typedef struct SmugFid SmugFid;
47 18824b58 2008-08-03 rsc struct SmugFid
48 18824b58 2008-08-03 rsc {
49 18824b58 2008-08-03 rsc int type;
50 18824b58 2008-08-03 rsc int nickid;
51 18824b58 2008-08-03 rsc vlong category; // -1 for "albums"
52 18824b58 2008-08-03 rsc vlong album;
53 18824b58 2008-08-03 rsc char *albumkey;
54 18824b58 2008-08-03 rsc vlong image;
55 18824b58 2008-08-03 rsc char *imagekey;
56 18824b58 2008-08-03 rsc Upload *upload;
57 18824b58 2008-08-03 rsc int upwriter;
58 18824b58 2008-08-03 rsc };
59 18824b58 2008-08-03 rsc
60 18824b58 2008-08-03 rsc #define QTYPE(p) ((p)&0xFF)
61 18824b58 2008-08-03 rsc #define QARG(p) ((p)>>8)
62 18824b58 2008-08-03 rsc #define QPATH(p, q) ((p)|((q)<<8))
63 18824b58 2008-08-03 rsc
64 18824b58 2008-08-03 rsc char **nick;
65 18824b58 2008-08-03 rsc int nnick;
66 18824b58 2008-08-03 rsc
67 18824b58 2008-08-03 rsc struct Upload
68 18824b58 2008-08-03 rsc {
69 18824b58 2008-08-03 rsc Lock lk;
70 18824b58 2008-08-03 rsc int fd;
71 18824b58 2008-08-03 rsc char *name;
72 18824b58 2008-08-03 rsc char *file;
73 18824b58 2008-08-03 rsc vlong album;
74 18824b58 2008-08-03 rsc vlong length;
75 18824b58 2008-08-03 rsc char *albumkey;
76 18824b58 2008-08-03 rsc int size;
77 18824b58 2008-08-03 rsc int ready;
78 18824b58 2008-08-03 rsc int nwriters;
79 18824b58 2008-08-03 rsc int uploaded;
80 18824b58 2008-08-03 rsc int ref;
81 18824b58 2008-08-03 rsc int uploading;
82 18824b58 2008-08-03 rsc };
83 18824b58 2008-08-03 rsc
84 18824b58 2008-08-03 rsc Upload **up;
85 18824b58 2008-08-03 rsc int nup;
86 18824b58 2008-08-03 rsc QLock uploadlock;
87 18824b58 2008-08-03 rsc Rendez uploadrendez;
88 18824b58 2008-08-03 rsc
89 18824b58 2008-08-03 rsc void uploader(void*);
90 18824b58 2008-08-03 rsc
91 18824b58 2008-08-03 rsc Upload*
92 18824b58 2008-08-03 rsc newupload(SmugFid *sf, char *name)
93 18824b58 2008-08-03 rsc {
94 18824b58 2008-08-03 rsc Upload *u;
95 18824b58 2008-08-03 rsc int fd, i;
96 18824b58 2008-08-03 rsc char tmp[] = "/var/tmp/smugfs.XXXXXX";
97 18824b58 2008-08-03 rsc
98 18824b58 2008-08-03 rsc if((fd = opentemp(tmp, ORDWR)) < 0)
99 18824b58 2008-08-03 rsc return nil;
100 18824b58 2008-08-03 rsc qlock(&uploadlock);
101 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
102 18824b58 2008-08-03 rsc u = up[i];
103 18824b58 2008-08-03 rsc lock(&u->lk);
104 18824b58 2008-08-03 rsc if(u->ref == 0){
105 18824b58 2008-08-03 rsc u->ref = 1;
106 18824b58 2008-08-03 rsc goto Reuse;
107 18824b58 2008-08-03 rsc }
108 18824b58 2008-08-03 rsc unlock(&u->lk);
109 18824b58 2008-08-03 rsc }
110 18824b58 2008-08-03 rsc if(nup == 0){
111 18824b58 2008-08-03 rsc uploadrendez.l = &uploadlock;
112 18824b58 2008-08-03 rsc proccreate(uploader, nil, STACKSIZE);
113 18824b58 2008-08-03 rsc }
114 18824b58 2008-08-03 rsc u = emalloc(sizeof *u);
115 18824b58 2008-08-03 rsc lock(&u->lk);
116 18824b58 2008-08-03 rsc u->ref = 1;
117 18824b58 2008-08-03 rsc up = erealloc(up, (nup+1)*sizeof up[0]);
118 18824b58 2008-08-03 rsc up[nup++] = u;
119 18824b58 2008-08-03 rsc Reuse:
120 18824b58 2008-08-03 rsc qunlock(&uploadlock);
121 18824b58 2008-08-03 rsc u->fd = fd;
122 18824b58 2008-08-03 rsc u->name = estrdup(name);
123 18824b58 2008-08-03 rsc u->file = estrdup(tmp);
124 18824b58 2008-08-03 rsc u->album = sf->album;
125 18824b58 2008-08-03 rsc u->albumkey = estrdup(sf->albumkey);
126 18824b58 2008-08-03 rsc u->nwriters = 1;
127 18824b58 2008-08-03 rsc unlock(&u->lk);
128 18824b58 2008-08-03 rsc return u;
129 18824b58 2008-08-03 rsc }
130 18824b58 2008-08-03 rsc
131 18824b58 2008-08-03 rsc void
132 18824b58 2008-08-03 rsc closeupload(Upload *u)
133 18824b58 2008-08-03 rsc {
134 18824b58 2008-08-03 rsc lock(&u->lk);
135 18824b58 2008-08-03 rsc fprint(2, "close %p from %p: %d\n", u, getcallerpc(&u), u->ref);
136 18824b58 2008-08-03 rsc if(--u->ref > 0){
137 18824b58 2008-08-03 rsc unlock(&u->lk);
138 18824b58 2008-08-03 rsc return;
139 18824b58 2008-08-03 rsc }
140 18824b58 2008-08-03 rsc if(u->ref < 0)
141 18824b58 2008-08-03 rsc abort();
142 18824b58 2008-08-03 rsc if(u->fd >= 0){
143 18824b58 2008-08-03 rsc close(u->fd);
144 18824b58 2008-08-03 rsc u->fd = -1;
145 18824b58 2008-08-03 rsc }
146 18824b58 2008-08-03 rsc if(u->name){
147 18824b58 2008-08-03 rsc free(u->name);
148 18824b58 2008-08-03 rsc u->name = nil;
149 18824b58 2008-08-03 rsc }
150 18824b58 2008-08-03 rsc if(u->file){
151 18824b58 2008-08-03 rsc remove(u->file);
152 18824b58 2008-08-03 rsc free(u->file);
153 18824b58 2008-08-03 rsc u->file = nil;
154 18824b58 2008-08-03 rsc }
155 18824b58 2008-08-03 rsc u->album = 0;
156 18824b58 2008-08-03 rsc if(u->albumkey){
157 18824b58 2008-08-03 rsc free(u->albumkey);
158 18824b58 2008-08-03 rsc u->albumkey = nil;
159 18824b58 2008-08-03 rsc }
160 18824b58 2008-08-03 rsc u->size = 0;
161 18824b58 2008-08-03 rsc u->ready = 0;
162 18824b58 2008-08-03 rsc u->nwriters = 0;
163 18824b58 2008-08-03 rsc u->uploaded = 0;
164 18824b58 2008-08-03 rsc u->uploading = 0;
165 18824b58 2008-08-03 rsc u->length = 0;
166 18824b58 2008-08-03 rsc unlock(&u->lk);
167 18824b58 2008-08-03 rsc }
168 18824b58 2008-08-03 rsc
169 18824b58 2008-08-03 rsc Upload*
170 18824b58 2008-08-03 rsc getuploadindex(SmugFid *sf, int *index)
171 18824b58 2008-08-03 rsc {
172 18824b58 2008-08-03 rsc int i;
173 18824b58 2008-08-03 rsc Upload *u;
174 18824b58 2008-08-03 rsc
175 18824b58 2008-08-03 rsc qlock(&uploadlock);
176 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
177 18824b58 2008-08-03 rsc u = up[i];
178 18824b58 2008-08-03 rsc lock(&u->lk);
179 18824b58 2008-08-03 rsc if(u->ref > 0 && !u->uploaded && u->album == sf->album && (*index)-- == 0){
180 18824b58 2008-08-03 rsc qunlock(&uploadlock);
181 18824b58 2008-08-03 rsc u->ref++;
182 18824b58 2008-08-03 rsc fprint(2, "bump %p from %p: %d\n", u, getcallerpc(&sf), u->ref);
183 18824b58 2008-08-03 rsc unlock(&u->lk);
184 18824b58 2008-08-03 rsc return u;
185 18824b58 2008-08-03 rsc }
186 18824b58 2008-08-03 rsc unlock(&u->lk);
187 18824b58 2008-08-03 rsc }
188 18824b58 2008-08-03 rsc qunlock(&uploadlock);
189 18824b58 2008-08-03 rsc return nil;
190 18824b58 2008-08-03 rsc }
191 18824b58 2008-08-03 rsc
192 18824b58 2008-08-03 rsc Upload*
193 18824b58 2008-08-03 rsc getuploadname(SmugFid *sf, char *name)
194 18824b58 2008-08-03 rsc {
195 18824b58 2008-08-03 rsc int i;
196 18824b58 2008-08-03 rsc Upload *u;
197 18824b58 2008-08-03 rsc
198 18824b58 2008-08-03 rsc qlock(&uploadlock);
199 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
200 18824b58 2008-08-03 rsc u = up[i];
201 18824b58 2008-08-03 rsc lock(&u->lk);
202 18824b58 2008-08-03 rsc if(u->ref > 0 && !u->uploaded && u->album == sf->album && strcmp(name, u->name) == 0){
203 18824b58 2008-08-03 rsc qunlock(&uploadlock);
204 18824b58 2008-08-03 rsc u->ref++;
205 18824b58 2008-08-03 rsc fprint(2, "bump %p from %p: %d\n", u, getcallerpc(&sf), u->ref);
206 18824b58 2008-08-03 rsc unlock(&u->lk);
207 18824b58 2008-08-03 rsc return u;
208 18824b58 2008-08-03 rsc }
209 18824b58 2008-08-03 rsc unlock(&u->lk);
210 18824b58 2008-08-03 rsc }
211 18824b58 2008-08-03 rsc qunlock(&uploadlock);
212 18824b58 2008-08-03 rsc return nil;
213 18824b58 2008-08-03 rsc }
214 18824b58 2008-08-03 rsc
215 18824b58 2008-08-03 rsc void doupload(Upload*);
216 18824b58 2008-08-03 rsc
217 18824b58 2008-08-03 rsc void
218 18824b58 2008-08-03 rsc uploader(void *v)
219 18824b58 2008-08-03 rsc {
220 18824b58 2008-08-03 rsc int i, did;
221 18824b58 2008-08-03 rsc Upload *u;
222 18824b58 2008-08-03 rsc
223 18824b58 2008-08-03 rsc qlock(&uploadlock);
224 18824b58 2008-08-03 rsc for(;;){
225 18824b58 2008-08-03 rsc did = 0;
226 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
227 18824b58 2008-08-03 rsc u = up[i];
228 18824b58 2008-08-03 rsc lock(&u->lk);
229 18824b58 2008-08-03 rsc if(u->ref > 0 && u->ready && !u->uploading && !u->uploaded){
230 18824b58 2008-08-03 rsc u->uploading = 1;
231 18824b58 2008-08-03 rsc unlock(&u->lk);
232 18824b58 2008-08-03 rsc qunlock(&uploadlock);
233 18824b58 2008-08-03 rsc doupload(u);
234 18824b58 2008-08-03 rsc closeupload(u);
235 18824b58 2008-08-03 rsc fprint(2, "done %d\n", u->ref);
236 18824b58 2008-08-03 rsc did = 1;
237 18824b58 2008-08-03 rsc qlock(&uploadlock);
238 18824b58 2008-08-03 rsc }else
239 18824b58 2008-08-03 rsc unlock(&u->lk);
240 18824b58 2008-08-03 rsc }
241 18824b58 2008-08-03 rsc if(!did)
242 18824b58 2008-08-03 rsc rsleep(&uploadrendez);
243 18824b58 2008-08-03 rsc }
244 18824b58 2008-08-03 rsc }
245 18824b58 2008-08-03 rsc
246 18824b58 2008-08-03 rsc void
247 18824b58 2008-08-03 rsc kickupload(Upload *u)
248 18824b58 2008-08-03 rsc {
249 18824b58 2008-08-03 rsc Dir *d;
250 18824b58 2008-08-03 rsc
251 18824b58 2008-08-03 rsc lock(&u->lk);
252 18824b58 2008-08-03 rsc if((d = dirfstat(u->fd)) != nil)
253 18824b58 2008-08-03 rsc u->length = d->length;
254 18824b58 2008-08-03 rsc close(u->fd);
255 18824b58 2008-08-03 rsc u->fd = -1;
256 18824b58 2008-08-03 rsc u->ref++;
257 18824b58 2008-08-03 rsc fprint(2, "kick %p from %p: %d\n", u, getcallerpc(&u), u->ref);
258 18824b58 2008-08-03 rsc u->ready = 1;
259 18824b58 2008-08-03 rsc unlock(&u->lk);
260 18824b58 2008-08-03 rsc qlock(&uploadlock);
261 18824b58 2008-08-03 rsc rwakeup(&uploadrendez);
262 18824b58 2008-08-03 rsc qunlock(&uploadlock);
263 18824b58 2008-08-03 rsc }
264 18824b58 2008-08-03 rsc
265 18824b58 2008-08-03 rsc void
266 18824b58 2008-08-03 rsc doupload(Upload *u)
267 18824b58 2008-08-03 rsc {
268 18824b58 2008-08-03 rsc Dir *d;
269 18824b58 2008-08-03 rsc vlong datalen;
270 18824b58 2008-08-03 rsc Fmt fmt;
271 18824b58 2008-08-03 rsc char *req;
272 18824b58 2008-08-03 rsc char buf[8192];
273 18824b58 2008-08-03 rsc int n, total;
274 18824b58 2008-08-03 rsc uchar digest[MD5dlen];
275 18824b58 2008-08-03 rsc DigestState ds;
276 18824b58 2008-08-03 rsc Json *jv;
277 18824b58 2008-08-03 rsc
278 18824b58 2008-08-03 rsc if((u->fd = open(u->file, OREAD)) < 0){
279 18824b58 2008-08-03 rsc fprint(2, "cannot reopen temporary file %s: %r\n", u->file);
280 18824b58 2008-08-03 rsc return;
281 18824b58 2008-08-03 rsc }
282 18824b58 2008-08-03 rsc if((d = dirfstat(u->fd)) == nil){
283 18824b58 2008-08-03 rsc fprint(2, "fstat: %r\n");
284 18824b58 2008-08-03 rsc return;
285 18824b58 2008-08-03 rsc }
286 18824b58 2008-08-03 rsc datalen = d->length;
287 18824b58 2008-08-03 rsc free(d);
288 18824b58 2008-08-03 rsc
289 18824b58 2008-08-03 rsc memset(&ds, 0, sizeof ds);
290 18824b58 2008-08-03 rsc seek(u->fd, 0, 0);
291 18824b58 2008-08-03 rsc total = 0;
292 18824b58 2008-08-03 rsc while((n = read(u->fd, buf, sizeof buf)) > 0){
293 18824b58 2008-08-03 rsc md5((uchar*)buf, n, nil, &ds);
294 18824b58 2008-08-03 rsc total += n;
295 18824b58 2008-08-03 rsc }
296 18824b58 2008-08-03 rsc if(total != datalen){
297 18824b58 2008-08-03 rsc fprint(2, "bad total: %lld %lld\n", total, datalen);
298 18824b58 2008-08-03 rsc return;
299 18824b58 2008-08-03 rsc }
300 18824b58 2008-08-03 rsc md5(nil, 0, digest, &ds);
301 18824b58 2008-08-03 rsc
302 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
303 18824b58 2008-08-03 rsc fmtprint(&fmt, "PUT /%s HTTP/1.0\r\n", u->name);
304 18824b58 2008-08-03 rsc fmtprint(&fmt, "Content-Length: %lld\r\n", datalen);
305 18824b58 2008-08-03 rsc fmtprint(&fmt, "Content-MD5: %.16lH\r\n", digest);
306 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-SessionID: %s\r\n", sessid);
307 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-Version: %s\r\n", API_VERSION);
308 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-ResponseType: JSON\r\n");
309 18824b58 2008-08-03 rsc // Can send X-Smug-ImageID instead to replace existing files.
310 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-AlbumID: %lld\r\n", u->album);
311 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-FileName: %s\r\n", u->name);
312 18824b58 2008-08-03 rsc fmtprint(&fmt, "\r\n");
313 18824b58 2008-08-03 rsc req = fmtstrflush(&fmt);
314 18824b58 2008-08-03 rsc
315 18824b58 2008-08-03 rsc seek(u->fd, 0, 0);
316 18824b58 2008-08-03 rsc jv = jsonupload(&http, UPLOAD_HOST, req, u->fd, datalen);
317 18824b58 2008-08-03 rsc free(req);
318 18824b58 2008-08-03 rsc if(jv == nil){
319 18824b58 2008-08-03 rsc fprint(2, "upload: %r\n");
320 18824b58 2008-08-03 rsc return;
321 18824b58 2008-08-03 rsc }
322 18824b58 2008-08-03 rsc
323 18824b58 2008-08-03 rsc close(u->fd);
324 18824b58 2008-08-03 rsc remove(u->file);
325 18824b58 2008-08-03 rsc free(u->file);
326 18824b58 2008-08-03 rsc u->file = nil;
327 18824b58 2008-08-03 rsc u->fd = -1;
328 18824b58 2008-08-03 rsc u->uploaded = 1;
329 18824b58 2008-08-03 rsc rpclog("uploaded: %J", jv);
330 18824b58 2008-08-03 rsc jclose(jv);
331 18824b58 2008-08-03 rsc }
332 18824b58 2008-08-03 rsc
333 18824b58 2008-08-03 rsc int
334 18824b58 2008-08-03 rsc nickindex(char *name)
335 18824b58 2008-08-03 rsc {
336 18824b58 2008-08-03 rsc int i;
337 18824b58 2008-08-03 rsc Json *v;
338 18824b58 2008-08-03 rsc
339 18824b58 2008-08-03 rsc for(i=0; i<nnick; i++)
340 18824b58 2008-08-03 rsc if(strcmp(nick[i], name) == 0)
341 18824b58 2008-08-03 rsc return i;
342 18824b58 2008-08-03 rsc v = smug("smugmug.users.getTree", "NickName", name, nil);
343 18824b58 2008-08-03 rsc if(v == nil)
344 18824b58 2008-08-03 rsc return -1;
345 18824b58 2008-08-03 rsc nick = erealloc(nick, (nnick+1)*sizeof nick[0]);
346 18824b58 2008-08-03 rsc nick[nnick] = estrdup(name);
347 18824b58 2008-08-03 rsc return nnick++;
348 18824b58 2008-08-03 rsc }
349 18824b58 2008-08-03 rsc
350 18824b58 2008-08-03 rsc char*
351 18824b58 2008-08-03 rsc nickname(int i)
352 18824b58 2008-08-03 rsc {
353 18824b58 2008-08-03 rsc if(i < 0 || i >= nnick)
354 18824b58 2008-08-03 rsc return nil;
355 18824b58 2008-08-03 rsc return nick[i];
356 18824b58 2008-08-03 rsc }
357 18824b58 2008-08-03 rsc
358 18824b58 2008-08-03 rsc void
359 18824b58 2008-08-03 rsc responderrstr(Req *r)
360 18824b58 2008-08-03 rsc {
361 18824b58 2008-08-03 rsc char err[ERRMAX];
362 18824b58 2008-08-03 rsc
363 18824b58 2008-08-03 rsc rerrstr(err, sizeof err);
364 18824b58 2008-08-03 rsc respond(r, err);
365 18824b58 2008-08-03 rsc }
366 18824b58 2008-08-03 rsc
367 18824b58 2008-08-03 rsc static char*
368 18824b58 2008-08-03 rsc xclone(Fid *oldfid, Fid *newfid)
369 18824b58 2008-08-03 rsc {
370 18824b58 2008-08-03 rsc SmugFid *sf;
371 18824b58 2008-08-03 rsc
372 18824b58 2008-08-03 rsc if(oldfid->aux == nil)
373 18824b58 2008-08-03 rsc return nil;
374 18824b58 2008-08-03 rsc
375 18824b58 2008-08-03 rsc sf = emalloc(sizeof *sf);
376 18824b58 2008-08-03 rsc *sf = *(SmugFid*)oldfid->aux;
377 18824b58 2008-08-03 rsc sf->upload = nil;
378 18824b58 2008-08-03 rsc sf->upwriter = 0;
379 18824b58 2008-08-03 rsc if(sf->albumkey)
380 18824b58 2008-08-03 rsc sf->albumkey = estrdup(sf->albumkey);
381 18824b58 2008-08-03 rsc if(sf->imagekey)
382 18824b58 2008-08-03 rsc sf->imagekey = estrdup(sf->imagekey);
383 18824b58 2008-08-03 rsc newfid->aux = sf;
384 18824b58 2008-08-03 rsc return nil;
385 18824b58 2008-08-03 rsc }
386 18824b58 2008-08-03 rsc
387 18824b58 2008-08-03 rsc static void
388 18824b58 2008-08-03 rsc xdestroyfid(Fid *fid)
389 18824b58 2008-08-03 rsc {
390 18824b58 2008-08-03 rsc SmugFid *sf;
391 18824b58 2008-08-03 rsc
392 18824b58 2008-08-03 rsc sf = fid->aux;
393 18824b58 2008-08-03 rsc free(sf->albumkey);
394 18824b58 2008-08-03 rsc free(sf->imagekey);
395 18824b58 2008-08-03 rsc if(sf->upload){
396 18824b58 2008-08-03 rsc if(sf->upwriter && --sf->upload->nwriters == 0){
397 18824b58 2008-08-03 rsc fprint(2, "should upload %s\n", sf->upload->name);
398 18824b58 2008-08-03 rsc kickupload(sf->upload);
399 18824b58 2008-08-03 rsc }
400 18824b58 2008-08-03 rsc closeupload(sf->upload);
401 18824b58 2008-08-03 rsc sf->upload = nil;
402 18824b58 2008-08-03 rsc }
403 18824b58 2008-08-03 rsc free(sf);
404 18824b58 2008-08-03 rsc }
405 18824b58 2008-08-03 rsc
406 18824b58 2008-08-03 rsc static Json*
407 18824b58 2008-08-03 rsc getcategories(SmugFid *sf)
408 18824b58 2008-08-03 rsc {
409 18824b58 2008-08-03 rsc Json *v, *w;
410 18824b58 2008-08-03 rsc
411 18824b58 2008-08-03 rsc v = smug("smugmug.categories.get", "NickName", nickname(sf->nickid), nil);
412 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Categories"));
413 18824b58 2008-08-03 rsc jclose(v);
414 18824b58 2008-08-03 rsc return w;
415 18824b58 2008-08-03 rsc }
416 18824b58 2008-08-03 rsc
417 18824b58 2008-08-03 rsc static Json*
418 18824b58 2008-08-03 rsc getcategorytree(SmugFid *sf)
419 18824b58 2008-08-03 rsc {
420 18824b58 2008-08-03 rsc Json *v, *w;
421 18824b58 2008-08-03 rsc
422 18824b58 2008-08-03 rsc v = smug("smugmug.users.getTree", "NickName", nickname(sf->nickid), nil);
423 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Categories"));
424 18824b58 2008-08-03 rsc jclose(v);
425 18824b58 2008-08-03 rsc return w;
426 18824b58 2008-08-03 rsc }
427 18824b58 2008-08-03 rsc
428 18824b58 2008-08-03 rsc static Json*
429 18824b58 2008-08-03 rsc getcategory(SmugFid *sf, vlong id)
430 18824b58 2008-08-03 rsc {
431 18824b58 2008-08-03 rsc int i;
432 18824b58 2008-08-03 rsc Json *v, *w;
433 18824b58 2008-08-03 rsc
434 18824b58 2008-08-03 rsc v = getcategorytree(sf);
435 18824b58 2008-08-03 rsc if(v == nil)
436 18824b58 2008-08-03 rsc return nil;
437 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
438 18824b58 2008-08-03 rsc if(jint(jwalk(v->value[i], "id")) == id){
439 18824b58 2008-08-03 rsc w = jincref(v->value[i]);
440 18824b58 2008-08-03 rsc jclose(v);
441 18824b58 2008-08-03 rsc return w;
442 18824b58 2008-08-03 rsc }
443 18824b58 2008-08-03 rsc }
444 18824b58 2008-08-03 rsc jclose(v);
445 18824b58 2008-08-03 rsc return nil;
446 18824b58 2008-08-03 rsc }
447 18824b58 2008-08-03 rsc
448 18824b58 2008-08-03 rsc static vlong
449 18824b58 2008-08-03 rsc getcategoryid(SmugFid *sf, char *name)
450 18824b58 2008-08-03 rsc {
451 18824b58 2008-08-03 rsc int i;
452 18824b58 2008-08-03 rsc vlong id;
453 18824b58 2008-08-03 rsc Json *v;
454 18824b58 2008-08-03 rsc
455 18824b58 2008-08-03 rsc v = getcategories(sf);
456 18824b58 2008-08-03 rsc if(v == nil)
457 18824b58 2008-08-03 rsc return -1;
458 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
459 18824b58 2008-08-03 rsc if(jstrcmp(jwalk(v->value[i], "Name"), name) == 0){
460 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
461 18824b58 2008-08-03 rsc if(id < 0){
462 18824b58 2008-08-03 rsc jclose(v);
463 18824b58 2008-08-03 rsc return -1;
464 18824b58 2008-08-03 rsc }
465 18824b58 2008-08-03 rsc jclose(v);
466 18824b58 2008-08-03 rsc return id;
467 18824b58 2008-08-03 rsc }
468 18824b58 2008-08-03 rsc }
469 18824b58 2008-08-03 rsc jclose(v);
470 18824b58 2008-08-03 rsc return -1;
471 18824b58 2008-08-03 rsc }
472 18824b58 2008-08-03 rsc
473 18824b58 2008-08-03 rsc static vlong
474 18824b58 2008-08-03 rsc getcategoryindex(SmugFid *sf, int i)
475 18824b58 2008-08-03 rsc {
476 18824b58 2008-08-03 rsc Json *v;
477 18824b58 2008-08-03 rsc vlong id;
478 18824b58 2008-08-03 rsc
479 18824b58 2008-08-03 rsc v = getcategories(sf);
480 18824b58 2008-08-03 rsc if(v == nil)
481 18824b58 2008-08-03 rsc return -1;
482 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
483 18824b58 2008-08-03 rsc jclose(v);
484 18824b58 2008-08-03 rsc return -1;
485 18824b58 2008-08-03 rsc }
486 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
487 18824b58 2008-08-03 rsc jclose(v);
488 18824b58 2008-08-03 rsc return id;
489 18824b58 2008-08-03 rsc }
490 18824b58 2008-08-03 rsc
491 18824b58 2008-08-03 rsc static Json*
492 18824b58 2008-08-03 rsc getalbum(SmugFid *sf, vlong albumid, char *albumkey)
493 18824b58 2008-08-03 rsc {
494 18824b58 2008-08-03 rsc char id[50];
495 18824b58 2008-08-03 rsc Json *v, *w;
496 18824b58 2008-08-03 rsc
497 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", albumid);
498 18824b58 2008-08-03 rsc v = smug("smugmug.albums.getInfo",
499 18824b58 2008-08-03 rsc "AlbumID", id, "AlbumKey", albumkey,
500 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
501 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Album"));
502 18824b58 2008-08-03 rsc jclose(v);
503 18824b58 2008-08-03 rsc return w;
504 18824b58 2008-08-03 rsc }
505 18824b58 2008-08-03 rsc
506 18824b58 2008-08-03 rsc static Json*
507 18824b58 2008-08-03 rsc getalbums(SmugFid *sf)
508 18824b58 2008-08-03 rsc {
509 18824b58 2008-08-03 rsc Json *v, *w;
510 18824b58 2008-08-03 rsc
511 18824b58 2008-08-03 rsc if(sf->category >= 0)
512 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
513 18824b58 2008-08-03 rsc else
514 18824b58 2008-08-03 rsc v = smug("smugmug.albums.get",
515 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
516 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Albums"));
517 18824b58 2008-08-03 rsc jclose(v);
518 18824b58 2008-08-03 rsc return w;
519 18824b58 2008-08-03 rsc }
520 18824b58 2008-08-03 rsc
521 18824b58 2008-08-03 rsc static vlong
522 18824b58 2008-08-03 rsc getalbumid(SmugFid *sf, char *name, char **keyp)
523 18824b58 2008-08-03 rsc {
524 18824b58 2008-08-03 rsc int i;
525 18824b58 2008-08-03 rsc vlong id;
526 18824b58 2008-08-03 rsc Json *v;
527 18824b58 2008-08-03 rsc char *key;
528 18824b58 2008-08-03 rsc
529 18824b58 2008-08-03 rsc v = getalbums(sf);
530 18824b58 2008-08-03 rsc if(v == nil)
531 18824b58 2008-08-03 rsc return -1;
532 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
533 18824b58 2008-08-03 rsc if(jstrcmp(jwalk(v->value[i], "Title"), name) == 0){
534 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
535 18824b58 2008-08-03 rsc key = jstring(jwalk(v->value[i], "Key"));
536 18824b58 2008-08-03 rsc if(id < 0 || key == nil){
537 18824b58 2008-08-03 rsc jclose(v);
538 18824b58 2008-08-03 rsc return -1;
539 18824b58 2008-08-03 rsc }
540 18824b58 2008-08-03 rsc if(keyp)
541 18824b58 2008-08-03 rsc *keyp = estrdup(key);
542 18824b58 2008-08-03 rsc jclose(v);
543 18824b58 2008-08-03 rsc return id;
544 18824b58 2008-08-03 rsc }
545 18824b58 2008-08-03 rsc }
546 18824b58 2008-08-03 rsc jclose(v);
547 18824b58 2008-08-03 rsc return -1;
548 18824b58 2008-08-03 rsc }
549 18824b58 2008-08-03 rsc
550 18824b58 2008-08-03 rsc static vlong
551 18824b58 2008-08-03 rsc getalbumindex(SmugFid *sf, int i, char **keyp)
552 18824b58 2008-08-03 rsc {
553 18824b58 2008-08-03 rsc vlong id;
554 18824b58 2008-08-03 rsc Json *v;
555 18824b58 2008-08-03 rsc char *key;
556 18824b58 2008-08-03 rsc
557 18824b58 2008-08-03 rsc v = getalbums(sf);
558 18824b58 2008-08-03 rsc if(v == nil)
559 18824b58 2008-08-03 rsc return -1;
560 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
561 18824b58 2008-08-03 rsc jclose(v);
562 18824b58 2008-08-03 rsc return -1;
563 18824b58 2008-08-03 rsc }
564 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
565 18824b58 2008-08-03 rsc key = jstring(jwalk(v->value[i], "Key"));
566 18824b58 2008-08-03 rsc if(id < 0 || key == nil){
567 18824b58 2008-08-03 rsc jclose(v);
568 18824b58 2008-08-03 rsc return -1;
569 18824b58 2008-08-03 rsc }
570 18824b58 2008-08-03 rsc if(keyp)
571 18824b58 2008-08-03 rsc *keyp = estrdup(key);
572 18824b58 2008-08-03 rsc jclose(v);
573 18824b58 2008-08-03 rsc return id;
574 18824b58 2008-08-03 rsc }
575 18824b58 2008-08-03 rsc
576 18824b58 2008-08-03 rsc static Json*
577 18824b58 2008-08-03 rsc getimages(SmugFid *sf, vlong albumid, char *albumkey)
578 18824b58 2008-08-03 rsc {
579 18824b58 2008-08-03 rsc char id[50];
580 18824b58 2008-08-03 rsc Json *v, *w;
581 18824b58 2008-08-03 rsc
582 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", albumid);
583 18824b58 2008-08-03 rsc v = smug("smugmug.images.get",
584 18824b58 2008-08-03 rsc "AlbumID", id, "AlbumKey", albumkey,
585 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
586 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Images"));
587 18824b58 2008-08-03 rsc jclose(v);
588 18824b58 2008-08-03 rsc return w;
589 18824b58 2008-08-03 rsc }
590 18824b58 2008-08-03 rsc
591 18824b58 2008-08-03 rsc static vlong
592 18824b58 2008-08-03 rsc getimageid(SmugFid *sf, char *name, char **keyp)
593 18824b58 2008-08-03 rsc {
594 18824b58 2008-08-03 rsc int i;
595 18824b58 2008-08-03 rsc vlong id;
596 18824b58 2008-08-03 rsc Json *v;
597 18824b58 2008-08-03 rsc char *p;
598 18824b58 2008-08-03 rsc char *key;
599 18824b58 2008-08-03 rsc
600 18824b58 2008-08-03 rsc id = strtol(name, &p, 10);
601 18824b58 2008-08-03 rsc if(*p != 0 || *name == 0)
602 18824b58 2008-08-03 rsc return -1;
603 18824b58 2008-08-03 rsc
604 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
605 18824b58 2008-08-03 rsc if(v == nil)
606 18824b58 2008-08-03 rsc return -1;
607 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
608 18824b58 2008-08-03 rsc if(jint(jwalk(v->value[i], "id")) == id){
609 18824b58 2008-08-03 rsc key = jstring(jwalk(v->value[i], "Key"));
610 18824b58 2008-08-03 rsc if(key == nil){
611 18824b58 2008-08-03 rsc jclose(v);
612 18824b58 2008-08-03 rsc return -1;
613 18824b58 2008-08-03 rsc }
614 18824b58 2008-08-03 rsc if(keyp)
615 18824b58 2008-08-03 rsc *keyp = estrdup(key);
616 18824b58 2008-08-03 rsc jclose(v);
617 18824b58 2008-08-03 rsc return id;
618 18824b58 2008-08-03 rsc }
619 18824b58 2008-08-03 rsc }
620 18824b58 2008-08-03 rsc jclose(v);
621 18824b58 2008-08-03 rsc return -1;
622 18824b58 2008-08-03 rsc }
623 18824b58 2008-08-03 rsc
624 18824b58 2008-08-03 rsc static Json*
625 18824b58 2008-08-03 rsc getimageinfo(SmugFid *sf, vlong imageid, char *imagekey)
626 18824b58 2008-08-03 rsc {
627 18824b58 2008-08-03 rsc char id[50];
628 18824b58 2008-08-03 rsc Json *v, *w;
629 18824b58 2008-08-03 rsc
630 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", imageid);
631 18824b58 2008-08-03 rsc v = smug("smugmug.images.getInfo",
632 18824b58 2008-08-03 rsc "ImageID", id, "ImageKey", imagekey,
633 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
634 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Image"));
635 18824b58 2008-08-03 rsc jclose(v);
636 18824b58 2008-08-03 rsc return w;
637 18824b58 2008-08-03 rsc }
638 18824b58 2008-08-03 rsc
639 18824b58 2008-08-03 rsc static Json*
640 18824b58 2008-08-03 rsc getimageexif(SmugFid *sf, vlong imageid, char *imagekey)
641 18824b58 2008-08-03 rsc {
642 18824b58 2008-08-03 rsc char id[50];
643 18824b58 2008-08-03 rsc Json *v, *w;
644 18824b58 2008-08-03 rsc
645 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", imageid);
646 18824b58 2008-08-03 rsc v = smug("smugmug.images.getEXIF",
647 18824b58 2008-08-03 rsc "ImageID", id, "ImageKey", imagekey,
648 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
649 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Image"));
650 18824b58 2008-08-03 rsc jclose(v);
651 18824b58 2008-08-03 rsc return w;
652 18824b58 2008-08-03 rsc }
653 18824b58 2008-08-03 rsc
654 18824b58 2008-08-03 rsc static vlong
655 18824b58 2008-08-03 rsc getimageindex(SmugFid *sf, int i, char **keyp)
656 18824b58 2008-08-03 rsc {
657 18824b58 2008-08-03 rsc vlong id;
658 18824b58 2008-08-03 rsc Json *v;
659 18824b58 2008-08-03 rsc char *key;
660 18824b58 2008-08-03 rsc
661 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
662 18824b58 2008-08-03 rsc if(v == nil)
663 18824b58 2008-08-03 rsc return -1;
664 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
665 18824b58 2008-08-03 rsc jclose(v);
666 18824b58 2008-08-03 rsc return -1;
667 18824b58 2008-08-03 rsc }
668 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
669 18824b58 2008-08-03 rsc key = jstring(jwalk(v->value[i], "Key"));
670 18824b58 2008-08-03 rsc if(id < 0 || key == nil){
671 18824b58 2008-08-03 rsc jclose(v);
672 18824b58 2008-08-03 rsc return -1;
673 18824b58 2008-08-03 rsc }
674 18824b58 2008-08-03 rsc if(keyp)
675 18824b58 2008-08-03 rsc *keyp = estrdup(key);
676 18824b58 2008-08-03 rsc jclose(v);
677 18824b58 2008-08-03 rsc return id;
678 18824b58 2008-08-03 rsc }
679 18824b58 2008-08-03 rsc
680 18824b58 2008-08-03 rsc static char*
681 18824b58 2008-08-03 rsc categoryname(SmugFid *sf)
682 18824b58 2008-08-03 rsc {
683 18824b58 2008-08-03 rsc Json *v;
684 18824b58 2008-08-03 rsc char *s;
685 18824b58 2008-08-03 rsc
686 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
687 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "Name"));
688 18824b58 2008-08-03 rsc if(s)
689 18824b58 2008-08-03 rsc s = estrdup(s);
690 18824b58 2008-08-03 rsc jclose(v);
691 18824b58 2008-08-03 rsc return s;
692 18824b58 2008-08-03 rsc }
693 18824b58 2008-08-03 rsc
694 18824b58 2008-08-03 rsc static char*
695 18824b58 2008-08-03 rsc albumname(SmugFid *sf)
696 18824b58 2008-08-03 rsc {
697 18824b58 2008-08-03 rsc Json *v;
698 18824b58 2008-08-03 rsc char *s;
699 18824b58 2008-08-03 rsc
700 18824b58 2008-08-03 rsc v = getalbum(sf, sf->album, sf->albumkey);
701 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "Title"));
702 18824b58 2008-08-03 rsc if(s)
703 18824b58 2008-08-03 rsc s = estrdup(s);
704 18824b58 2008-08-03 rsc jclose(v);
705 18824b58 2008-08-03 rsc return s;
706 18824b58 2008-08-03 rsc }
707 18824b58 2008-08-03 rsc
708 18824b58 2008-08-03 rsc static char*
709 18824b58 2008-08-03 rsc imagename(SmugFid *sf)
710 18824b58 2008-08-03 rsc {
711 18824b58 2008-08-03 rsc char *s;
712 18824b58 2008-08-03 rsc Json *v;
713 18824b58 2008-08-03 rsc
714 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
715 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "FileName"));
716 18824b58 2008-08-03 rsc if(s && s[0])
717 18824b58 2008-08-03 rsc s = estrdup(s);
718 18824b58 2008-08-03 rsc else
719 18824b58 2008-08-03 rsc s = smprint("%lld.jpg", sf->image); // TODO: use Format
720 18824b58 2008-08-03 rsc jclose(v);
721 18824b58 2008-08-03 rsc return s;
722 18824b58 2008-08-03 rsc }
723 18824b58 2008-08-03 rsc
724 18824b58 2008-08-03 rsc static vlong
725 18824b58 2008-08-03 rsc imagelength(SmugFid *sf)
726 18824b58 2008-08-03 rsc {
727 18824b58 2008-08-03 rsc vlong length;
728 18824b58 2008-08-03 rsc Json *v;
729 18824b58 2008-08-03 rsc
730 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
731 18824b58 2008-08-03 rsc length = jint(jwalk(v, "Size"));
732 18824b58 2008-08-03 rsc jclose(v);
733 18824b58 2008-08-03 rsc return length;
734 18824b58 2008-08-03 rsc }
735 18824b58 2008-08-03 rsc
736 18824b58 2008-08-03 rsc static struct {
737 18824b58 2008-08-03 rsc char *key;
738 18824b58 2008-08-03 rsc char *name;
739 18824b58 2008-08-03 rsc } urls[] = {
740 18824b58 2008-08-03 rsc "AlbumURL", "album",
741 18824b58 2008-08-03 rsc "TinyURL", "tiny",
742 18824b58 2008-08-03 rsc "ThumbURL", "thumb",
743 18824b58 2008-08-03 rsc "SmallURL", "small",
744 18824b58 2008-08-03 rsc "MediumURL", "medium",
745 18824b58 2008-08-03 rsc "LargeURL", "large",
746 18824b58 2008-08-03 rsc "XLargeURL", "xlarge",
747 18824b58 2008-08-03 rsc "X2LargeURL", "xxlarge",
748 18824b58 2008-08-03 rsc "X3LargeURL", "xxxlarge",
749 18824b58 2008-08-03 rsc "OriginalURL", "original",
750 18824b58 2008-08-03 rsc };
751 18824b58 2008-08-03 rsc
752 18824b58 2008-08-03 rsc static char*
753 18824b58 2008-08-03 rsc imageurl(SmugFid *sf)
754 18824b58 2008-08-03 rsc {
755 18824b58 2008-08-03 rsc Json *v;
756 18824b58 2008-08-03 rsc char *s;
757 18824b58 2008-08-03 rsc int i;
758 18824b58 2008-08-03 rsc
759 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
760 18824b58 2008-08-03 rsc for(i=nelem(urls)-1; i>=0; i--){
761 18824b58 2008-08-03 rsc if((s = jstring(jwalk(v, urls[i].key))) != nil){
762 18824b58 2008-08-03 rsc s = estrdup(s);
763 18824b58 2008-08-03 rsc jclose(v);
764 18824b58 2008-08-03 rsc return s;
765 18824b58 2008-08-03 rsc }
766 18824b58 2008-08-03 rsc }
767 18824b58 2008-08-03 rsc jclose(v);
768 18824b58 2008-08-03 rsc return nil;
769 18824b58 2008-08-03 rsc }
770 18824b58 2008-08-03 rsc
771 18824b58 2008-08-03 rsc static char* imagestrings[] =
772 18824b58 2008-08-03 rsc {
773 18824b58 2008-08-03 rsc "Caption",
774 18824b58 2008-08-03 rsc "LastUpdated",
775 18824b58 2008-08-03 rsc "FileName",
776 18824b58 2008-08-03 rsc "MD5Sum",
777 18824b58 2008-08-03 rsc "Watermark",
778 18824b58 2008-08-03 rsc "Format",
779 18824b58 2008-08-03 rsc "Keywords",
780 18824b58 2008-08-03 rsc "Date",
781 18824b58 2008-08-03 rsc "AlbumURL",
782 18824b58 2008-08-03 rsc "TinyURL",
783 18824b58 2008-08-03 rsc "ThumbURL",
784 18824b58 2008-08-03 rsc "SmallURL",
785 18824b58 2008-08-03 rsc "MediumURL",
786 18824b58 2008-08-03 rsc "LargeURL",
787 18824b58 2008-08-03 rsc "XLargeURL",
788 18824b58 2008-08-03 rsc "X2LargeURL",
789 18824b58 2008-08-03 rsc "X3LargeURL",
790 18824b58 2008-08-03 rsc "OriginalURL",
791 18824b58 2008-08-03 rsc "Album",
792 18824b58 2008-08-03 rsc };
793 18824b58 2008-08-03 rsc
794 18824b58 2008-08-03 rsc static char* albumbools[] =
795 18824b58 2008-08-03 rsc {
796 18824b58 2008-08-03 rsc "Public",
797 18824b58 2008-08-03 rsc "Printable",
798 18824b58 2008-08-03 rsc "Filenames",
799 18824b58 2008-08-03 rsc "Comments",
800 18824b58 2008-08-03 rsc "External",
801 18824b58 2008-08-03 rsc "Originals",
802 18824b58 2008-08-03 rsc "EXIF",
803 18824b58 2008-08-03 rsc "Share",
804 18824b58 2008-08-03 rsc "SortDirection",
805 18824b58 2008-08-03 rsc "FamilyEdit",
806 18824b58 2008-08-03 rsc "FriendEdit",
807 18824b58 2008-08-03 rsc "HideOwner",
808 18824b58 2008-08-03 rsc "CanRank",
809 18824b58 2008-08-03 rsc "Clean",
810 18824b58 2008-08-03 rsc "Geography",
811 18824b58 2008-08-03 rsc "SmugSearchable",
812 18824b58 2008-08-03 rsc "WorldSearchable",
813 18824b58 2008-08-03 rsc "SquareThumbs",
814 18824b58 2008-08-03 rsc "X2Larges",
815 18824b58 2008-08-03 rsc "X3Larges",
816 18824b58 2008-08-03 rsc };
817 18824b58 2008-08-03 rsc
818 18824b58 2008-08-03 rsc static char* albumstrings[] =
819 18824b58 2008-08-03 rsc {
820 18824b58 2008-08-03 rsc "Description"
821 18824b58 2008-08-03 rsc "Keywords",
822 18824b58 2008-08-03 rsc "Password",
823 18824b58 2008-08-03 rsc "PasswordHint",
824 18824b58 2008-08-03 rsc "SortMethod",
825 18824b58 2008-08-03 rsc "LastUpdated",
826 18824b58 2008-08-03 rsc };
827 18824b58 2008-08-03 rsc
828 18824b58 2008-08-03 rsc static char*
829 18824b58 2008-08-03 rsc readctl(SmugFid *sf)
830 18824b58 2008-08-03 rsc {
831 18824b58 2008-08-03 rsc int i;
832 18824b58 2008-08-03 rsc Upload *u;
833 18824b58 2008-08-03 rsc char *s;
834 18824b58 2008-08-03 rsc Json *v, *vv;
835 18824b58 2008-08-03 rsc Fmt fmt;
836 18824b58 2008-08-03 rsc
837 18824b58 2008-08-03 rsc v = nil;
838 18824b58 2008-08-03 rsc switch(sf->type){
839 18824b58 2008-08-03 rsc case Qctl:
840 18824b58 2008-08-03 rsc return smprint("%#J\n", userinfo);
841 18824b58 2008-08-03 rsc
842 18824b58 2008-08-03 rsc case Quploads:
843 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
844 18824b58 2008-08-03 rsc qlock(&uploadlock);
845 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
846 18824b58 2008-08-03 rsc u = up[i];
847 18824b58 2008-08-03 rsc lock(&u->lk);
848 18824b58 2008-08-03 rsc if(u->ready && !u->uploaded && u->ref > 0)
849 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s %s%s\n", u->name, u->file, u->uploading ? " [uploading]" : "");
850 18824b58 2008-08-03 rsc unlock(&u->lk);
851 18824b58 2008-08-03 rsc }
852 18824b58 2008-08-03 rsc qunlock(&uploadlock);
853 18824b58 2008-08-03 rsc return fmtstrflush(&fmt);
854 18824b58 2008-08-03 rsc
855 18824b58 2008-08-03 rsc case Qnickctl:
856 18824b58 2008-08-03 rsc v = getcategories(sf);
857 18824b58 2008-08-03 rsc break;
858 18824b58 2008-08-03 rsc
859 18824b58 2008-08-03 rsc case Qcategoryctl:
860 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
861 18824b58 2008-08-03 rsc break;
862 18824b58 2008-08-03 rsc
863 18824b58 2008-08-03 rsc case Qalbumctl:
864 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
865 18824b58 2008-08-03 rsc break;
866 18824b58 2008-08-03 rsc
867 18824b58 2008-08-03 rsc case Qalbumsctl:
868 18824b58 2008-08-03 rsc v = getalbums(sf);
869 18824b58 2008-08-03 rsc break;
870 18824b58 2008-08-03 rsc
871 18824b58 2008-08-03 rsc case Qimagectl:
872 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
873 18824b58 2008-08-03 rsc break;
874 18824b58 2008-08-03 rsc
875 18824b58 2008-08-03 rsc case Qimageurl:
876 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
877 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
878 18824b58 2008-08-03 rsc for(i=0; i<nelem(urls); i++)
879 18824b58 2008-08-03 rsc if((s = jstring(jwalk(v, urls[i].key))) != nil)
880 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s %s\n", urls[i].name, s);
881 18824b58 2008-08-03 rsc jclose(v);
882 18824b58 2008-08-03 rsc return fmtstrflush(&fmt);
883 18824b58 2008-08-03 rsc
884 18824b58 2008-08-03 rsc case Qimageexif:
885 18824b58 2008-08-03 rsc v = getimageexif(sf, sf->image, sf->imagekey);
886 18824b58 2008-08-03 rsc break;
887 18824b58 2008-08-03 rsc
888 18824b58 2008-08-03 rsc case Qalbumsettings:
889 18824b58 2008-08-03 rsc v = getalbum(sf, sf->album, sf->albumkey);
890 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
891 18824b58 2008-08-03 rsc fmtprint(&fmt, "id\t%lld\n", jint(jwalk(v, "id")));
892 18824b58 2008-08-03 rsc // TODO: Category/id
893 18824b58 2008-08-03 rsc // TODO: SubCategory/id
894 18824b58 2008-08-03 rsc // TODO: Community/id
895 18824b58 2008-08-03 rsc // TODO: Template/id
896 18824b58 2008-08-03 rsc fmtprint(&fmt, "Highlight\t%lld\n", jint(jwalk(v, "Highlight/id")));
897 18824b58 2008-08-03 rsc fmtprint(&fmt, "Position\t%lld\n", jint(jwalk(v, "Position")));
898 18824b58 2008-08-03 rsc fmtprint(&fmt, "ImageCount\t%lld\n", jint(jwalk(v, "ImageCount")));
899 18824b58 2008-08-03 rsc for(i=0; i<nelem(albumbools); i++){
900 18824b58 2008-08-03 rsc vv = jwalk(v, albumbools[i]);
901 18824b58 2008-08-03 rsc if(vv)
902 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%J\n", albumbools[i], vv);
903 18824b58 2008-08-03 rsc }
904 18824b58 2008-08-03 rsc for(i=0; i<nelem(albumstrings); i++){
905 18824b58 2008-08-03 rsc s = jstring(jwalk(v, albumstrings[i]));
906 18824b58 2008-08-03 rsc if(s)
907 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%s\n", albumstrings[i], s);
908 18824b58 2008-08-03 rsc }
909 18824b58 2008-08-03 rsc s = fmtstrflush(&fmt);
910 18824b58 2008-08-03 rsc jclose(v);
911 18824b58 2008-08-03 rsc return s;
912 18824b58 2008-08-03 rsc
913 18824b58 2008-08-03 rsc case Qimagesettings:
914 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
915 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
916 18824b58 2008-08-03 rsc fmtprint(&fmt, "id\t%lld\n", jint(jwalk(v, "id")));
917 18824b58 2008-08-03 rsc fmtprint(&fmt, "Position\t%lld\n", jint(jwalk(v, "Position")));
918 18824b58 2008-08-03 rsc fmtprint(&fmt, "Serial\t%lld\n", jint(jwalk(v, "Serial")));
919 18824b58 2008-08-03 rsc fmtprint(&fmt, "Size\t%lld\t%lldx%lld\n",
920 18824b58 2008-08-03 rsc jint(jwalk(v, "Size")),
921 18824b58 2008-08-03 rsc jint(jwalk(v, "Width")),
922 18824b58 2008-08-03 rsc jint(jwalk(v, "Height")));
923 18824b58 2008-08-03 rsc vv = jwalk(v, "Hidden");
924 18824b58 2008-08-03 rsc fmtprint(&fmt, "Hidden\t%J\n", vv);
925 18824b58 2008-08-03 rsc // TODO: Album/id
926 18824b58 2008-08-03 rsc for(i=0; i<nelem(imagestrings); i++){
927 18824b58 2008-08-03 rsc s = jstring(jwalk(v, imagestrings[i]));
928 18824b58 2008-08-03 rsc if(s)
929 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%s\n", imagestrings[i], s);
930 18824b58 2008-08-03 rsc }
931 18824b58 2008-08-03 rsc s = fmtstrflush(&fmt);
932 18824b58 2008-08-03 rsc jclose(v);
933 18824b58 2008-08-03 rsc return s;
934 18824b58 2008-08-03 rsc }
935 18824b58 2008-08-03 rsc
936 18824b58 2008-08-03 rsc if(v == nil)
937 18824b58 2008-08-03 rsc return estrdup("");
938 18824b58 2008-08-03 rsc s = smprint("%#J\n", v);
939 18824b58 2008-08-03 rsc jclose(v);
940 18824b58 2008-08-03 rsc return s;
941 18824b58 2008-08-03 rsc }
942 18824b58 2008-08-03 rsc
943 18824b58 2008-08-03 rsc
944 18824b58 2008-08-03 rsc static void
945 18824b58 2008-08-03 rsc dostat(SmugFid *sf, Qid *qid, Dir *dir)
946 18824b58 2008-08-03 rsc {
947 18824b58 2008-08-03 rsc Qid q;
948 18824b58 2008-08-03 rsc char *name;
949 18824b58 2008-08-03 rsc int freename;
950 18824b58 2008-08-03 rsc ulong mode;
951 18824b58 2008-08-03 rsc char *uid;
952 18824b58 2008-08-03 rsc char *s;
953 18824b58 2008-08-03 rsc vlong length;
954 18824b58 2008-08-03 rsc
955 18824b58 2008-08-03 rsc memset(&q, 0, sizeof q);
956 18824b58 2008-08-03 rsc name = nil;
957 18824b58 2008-08-03 rsc freename = 0;
958 18824b58 2008-08-03 rsc uid = "smugfs";
959 18824b58 2008-08-03 rsc q.type = 0;
960 18824b58 2008-08-03 rsc q.vers = 0;
961 18824b58 2008-08-03 rsc q.path = QPATH(sf->type, sf->nickid);
962 18824b58 2008-08-03 rsc length = 0;
963 18824b58 2008-08-03 rsc mode = 0444;
964 18824b58 2008-08-03 rsc
965 18824b58 2008-08-03 rsc switch(sf->type){
966 18824b58 2008-08-03 rsc case Qroot:
967 18824b58 2008-08-03 rsc name = "/";
968 18824b58 2008-08-03 rsc q.type = QTDIR;
969 18824b58 2008-08-03 rsc break;
970 18824b58 2008-08-03 rsc case Qctl:
971 18824b58 2008-08-03 rsc name = "ctl";
972 18824b58 2008-08-03 rsc mode |= 0222;
973 18824b58 2008-08-03 rsc break;
974 18824b58 2008-08-03 rsc case Quploads:
975 18824b58 2008-08-03 rsc name = "uploads";
976 18824b58 2008-08-03 rsc s = readctl(sf);
977 18824b58 2008-08-03 rsc if(s){
978 18824b58 2008-08-03 rsc length = strlen(s);
979 18824b58 2008-08-03 rsc free(s);
980 18824b58 2008-08-03 rsc }
981 18824b58 2008-08-03 rsc break;
982 18824b58 2008-08-03 rsc case Qrpclog:
983 18824b58 2008-08-03 rsc name = "rpclog";
984 18824b58 2008-08-03 rsc break;
985 18824b58 2008-08-03 rsc case Qnick:
986 18824b58 2008-08-03 rsc name = nickname(sf->nickid);
987 18824b58 2008-08-03 rsc q.type = QTDIR;
988 18824b58 2008-08-03 rsc break;
989 18824b58 2008-08-03 rsc case Qnickctl:
990 18824b58 2008-08-03 rsc name = "ctl";
991 18824b58 2008-08-03 rsc mode |= 0222;
992 18824b58 2008-08-03 rsc break;
993 18824b58 2008-08-03 rsc case Qalbums:
994 18824b58 2008-08-03 rsc name = "albums";
995 18824b58 2008-08-03 rsc q.type = QTDIR;
996 18824b58 2008-08-03 rsc break;
997 18824b58 2008-08-03 rsc case Qalbumsctl:
998 18824b58 2008-08-03 rsc name = "ctl";
999 18824b58 2008-08-03 rsc mode |= 0222;
1000 18824b58 2008-08-03 rsc break;
1001 18824b58 2008-08-03 rsc case Qcategory:
1002 18824b58 2008-08-03 rsc name = categoryname(sf);
1003 18824b58 2008-08-03 rsc freename = 1;
1004 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->category << 8);
1005 18824b58 2008-08-03 rsc q.type = QTDIR;
1006 18824b58 2008-08-03 rsc break;
1007 18824b58 2008-08-03 rsc case Qcategoryctl:
1008 18824b58 2008-08-03 rsc name = "ctl";
1009 18824b58 2008-08-03 rsc mode |= 0222;
1010 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->category << 8);
1011 18824b58 2008-08-03 rsc break;
1012 18824b58 2008-08-03 rsc case Qalbum:
1013 18824b58 2008-08-03 rsc name = albumname(sf);
1014 18824b58 2008-08-03 rsc freename = 1;
1015 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->album << 8);
1016 18824b58 2008-08-03 rsc q.type = QTDIR;
1017 18824b58 2008-08-03 rsc break;
1018 18824b58 2008-08-03 rsc case Qalbumctl:
1019 18824b58 2008-08-03 rsc name = "ctl";
1020 18824b58 2008-08-03 rsc mode |= 0222;
1021 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->album << 8);
1022 18824b58 2008-08-03 rsc break;
1023 18824b58 2008-08-03 rsc case Qalbumsettings:
1024 18824b58 2008-08-03 rsc name = "settings";
1025 18824b58 2008-08-03 rsc mode |= 0222;
1026 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->album << 8);
1027 18824b58 2008-08-03 rsc break;
1028 18824b58 2008-08-03 rsc case Quploadfile:
1029 18824b58 2008-08-03 rsc q.path |= QPATH(0, (uintptr)sf->upload << 8);
1030 18824b58 2008-08-03 rsc if(sf->upload){
1031 18824b58 2008-08-03 rsc Dir *dd;
1032 18824b58 2008-08-03 rsc name = sf->upload->name;
1033 18824b58 2008-08-03 rsc if(sf->upload->fd >= 0){
1034 18824b58 2008-08-03 rsc dd = dirfstat(sf->upload->fd);
1035 18824b58 2008-08-03 rsc if(dd){
1036 18824b58 2008-08-03 rsc length = dd->length;
1037 18824b58 2008-08-03 rsc free(dd);
1038 18824b58 2008-08-03 rsc }
1039 18824b58 2008-08-03 rsc }else
1040 18824b58 2008-08-03 rsc length = sf->upload->length;
1041 18824b58 2008-08-03 rsc if(!sf->upload->ready)
1042 18824b58 2008-08-03 rsc mode |= 0222;
1043 18824b58 2008-08-03 rsc }
1044 18824b58 2008-08-03 rsc break;
1045 18824b58 2008-08-03 rsc case Qimage:
1046 18824b58 2008-08-03 rsc name = smprint("%lld", sf->image);
1047 18824b58 2008-08-03 rsc freename = 1;
1048 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1049 18824b58 2008-08-03 rsc q.type = QTDIR;
1050 18824b58 2008-08-03 rsc break;
1051 18824b58 2008-08-03 rsc case Qimagectl:
1052 18824b58 2008-08-03 rsc name = "ctl";
1053 18824b58 2008-08-03 rsc mode |= 0222;
1054 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1055 18824b58 2008-08-03 rsc break;
1056 18824b58 2008-08-03 rsc case Qimagesettings:
1057 18824b58 2008-08-03 rsc name = "settings";
1058 18824b58 2008-08-03 rsc mode |= 0222;
1059 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1060 18824b58 2008-08-03 rsc break;
1061 18824b58 2008-08-03 rsc case Qimageexif:
1062 18824b58 2008-08-03 rsc name = "exif";
1063 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1064 18824b58 2008-08-03 rsc break;
1065 18824b58 2008-08-03 rsc case Qimageurl:
1066 18824b58 2008-08-03 rsc name = "url";
1067 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1068 18824b58 2008-08-03 rsc break;
1069 18824b58 2008-08-03 rsc case Qimagefile:
1070 18824b58 2008-08-03 rsc name = imagename(sf);
1071 18824b58 2008-08-03 rsc freename = 1;
1072 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1073 18824b58 2008-08-03 rsc length = imagelength(sf);
1074 18824b58 2008-08-03 rsc break;
1075 18824b58 2008-08-03 rsc default:
1076 18824b58 2008-08-03 rsc name = "?egreg";
1077 18824b58 2008-08-03 rsc q.path = 0;
1078 18824b58 2008-08-03 rsc break;
1079 18824b58 2008-08-03 rsc }
1080 18824b58 2008-08-03 rsc
1081 18824b58 2008-08-03 rsc if(name == nil){
1082 18824b58 2008-08-03 rsc name = "???";
1083 18824b58 2008-08-03 rsc freename = 0;
1084 18824b58 2008-08-03 rsc }
1085 18824b58 2008-08-03 rsc
1086 18824b58 2008-08-03 rsc if(qid)
1087 18824b58 2008-08-03 rsc *qid = q;
1088 18824b58 2008-08-03 rsc if(dir){
1089 18824b58 2008-08-03 rsc memset(dir, 0, sizeof *dir);
1090 18824b58 2008-08-03 rsc dir->name = estrdup9p(name);
1091 18824b58 2008-08-03 rsc dir->muid = estrdup9p("muid");
1092 18824b58 2008-08-03 rsc mode |= q.type<<24;
1093 18824b58 2008-08-03 rsc if(mode & DMDIR)
1094 18824b58 2008-08-03 rsc mode |= 0555;
1095 18824b58 2008-08-03 rsc dir->mode = mode;
1096 18824b58 2008-08-03 rsc dir->uid = estrdup9p(uid);
1097 18824b58 2008-08-03 rsc dir->gid = estrdup9p("smugfs");
1098 18824b58 2008-08-03 rsc dir->qid = q;
1099 18824b58 2008-08-03 rsc dir->length = length;
1100 18824b58 2008-08-03 rsc }
1101 18824b58 2008-08-03 rsc if(freename)
1102 18824b58 2008-08-03 rsc free(name);
1103 18824b58 2008-08-03 rsc }
1104 18824b58 2008-08-03 rsc
1105 18824b58 2008-08-03 rsc static char*
1106 18824b58 2008-08-03 rsc xwalk1(Fid *fid, char *name, Qid *qid)
1107 18824b58 2008-08-03 rsc {
1108 18824b58 2008-08-03 rsc int dotdot, i;
1109 18824b58 2008-08-03 rsc vlong id;
1110 18824b58 2008-08-03 rsc char *key;
1111 18824b58 2008-08-03 rsc SmugFid *sf;
1112 18824b58 2008-08-03 rsc char *x;
1113 18824b58 2008-08-03 rsc Upload *u;
1114 18824b58 2008-08-03 rsc
1115 18824b58 2008-08-03 rsc dotdot = strcmp(name, "..") == 0;
1116 18824b58 2008-08-03 rsc sf = fid->aux;
1117 18824b58 2008-08-03 rsc switch(sf->type){
1118 18824b58 2008-08-03 rsc default:
1119 18824b58 2008-08-03 rsc NotFound:
1120 18824b58 2008-08-03 rsc return "file not found";
1121 18824b58 2008-08-03 rsc
1122 18824b58 2008-08-03 rsc case Qroot:
1123 18824b58 2008-08-03 rsc if(dotdot)
1124 18824b58 2008-08-03 rsc break;
1125 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1126 18824b58 2008-08-03 rsc sf->type = Qctl;
1127 18824b58 2008-08-03 rsc break;
1128 18824b58 2008-08-03 rsc }
1129 18824b58 2008-08-03 rsc if(strcmp(name, "uploads") == 0){
1130 18824b58 2008-08-03 rsc sf->type = Quploads;
1131 18824b58 2008-08-03 rsc break;
1132 18824b58 2008-08-03 rsc }
1133 18824b58 2008-08-03 rsc if(strcmp(name, "rpclog") == 0){
1134 18824b58 2008-08-03 rsc sf->type = Qrpclog;
1135 18824b58 2008-08-03 rsc break;
1136 18824b58 2008-08-03 rsc }
1137 18824b58 2008-08-03 rsc if((i = nickindex(name)) >= 0){
1138 18824b58 2008-08-03 rsc sf->nickid = i;
1139 18824b58 2008-08-03 rsc sf->type = Qnick;
1140 18824b58 2008-08-03 rsc break;
1141 18824b58 2008-08-03 rsc }
1142 18824b58 2008-08-03 rsc goto NotFound;
1143 18824b58 2008-08-03 rsc
1144 18824b58 2008-08-03 rsc case Qnick:
1145 18824b58 2008-08-03 rsc if(dotdot){
1146 18824b58 2008-08-03 rsc sf->type = Qroot;
1147 18824b58 2008-08-03 rsc sf->nickid = 0;
1148 18824b58 2008-08-03 rsc break;
1149 18824b58 2008-08-03 rsc }
1150 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1151 18824b58 2008-08-03 rsc sf->type = Qnickctl;
1152 18824b58 2008-08-03 rsc break;
1153 18824b58 2008-08-03 rsc }
1154 18824b58 2008-08-03 rsc if(strcmp(name, "albums") == 0){
1155 18824b58 2008-08-03 rsc sf->category = -1;
1156 18824b58 2008-08-03 rsc sf->type = Qalbums;
1157 18824b58 2008-08-03 rsc break;
1158 18824b58 2008-08-03 rsc }
1159 18824b58 2008-08-03 rsc if((id = getcategoryid(sf, name)) >= 0){
1160 18824b58 2008-08-03 rsc sf->category = id;
1161 18824b58 2008-08-03 rsc sf->type = Qcategory;
1162 18824b58 2008-08-03 rsc break;
1163 18824b58 2008-08-03 rsc }
1164 18824b58 2008-08-03 rsc goto NotFound;
1165 18824b58 2008-08-03 rsc
1166 18824b58 2008-08-03 rsc case Qalbums:
1167 18824b58 2008-08-03 rsc case Qcategory:
1168 18824b58 2008-08-03 rsc if(dotdot){
1169 18824b58 2008-08-03 rsc sf->category = 0;
1170 18824b58 2008-08-03 rsc sf->type = Qnick;
1171 18824b58 2008-08-03 rsc break;
1172 18824b58 2008-08-03 rsc }
1173 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1174 18824b58 2008-08-03 rsc sf->type++;
1175 18824b58 2008-08-03 rsc break;
1176 18824b58 2008-08-03 rsc }
1177 18824b58 2008-08-03 rsc if((id = getalbumid(sf, name, &key)) >= 0){
1178 18824b58 2008-08-03 rsc sf->album = id;
1179 18824b58 2008-08-03 rsc sf->albumkey = key;
1180 18824b58 2008-08-03 rsc sf->type = Qalbum;
1181 18824b58 2008-08-03 rsc break;
1182 18824b58 2008-08-03 rsc }
1183 18824b58 2008-08-03 rsc goto NotFound;
1184 18824b58 2008-08-03 rsc
1185 18824b58 2008-08-03 rsc case Qalbum:
1186 18824b58 2008-08-03 rsc if(dotdot){
1187 18824b58 2008-08-03 rsc free(sf->albumkey);
1188 18824b58 2008-08-03 rsc sf->albumkey = nil;
1189 18824b58 2008-08-03 rsc sf->album = 0;
1190 18824b58 2008-08-03 rsc if(sf->category == -1)
1191 18824b58 2008-08-03 rsc sf->type = Qalbums;
1192 18824b58 2008-08-03 rsc else
1193 18824b58 2008-08-03 rsc sf->type = Qcategory;
1194 18824b58 2008-08-03 rsc break;
1195 18824b58 2008-08-03 rsc }
1196 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1197 18824b58 2008-08-03 rsc sf->type = Qalbumctl;
1198 18824b58 2008-08-03 rsc break;
1199 18824b58 2008-08-03 rsc }
1200 18824b58 2008-08-03 rsc if(strcmp(name, "settings") == 0){
1201 18824b58 2008-08-03 rsc sf->type = Qalbumsettings;
1202 18824b58 2008-08-03 rsc break;
1203 18824b58 2008-08-03 rsc }
1204 18824b58 2008-08-03 rsc if((id = getimageid(sf, name, &key)) >= 0){
1205 18824b58 2008-08-03 rsc sf->image = id;
1206 18824b58 2008-08-03 rsc sf->imagekey = key;
1207 18824b58 2008-08-03 rsc sf->type = Qimage;
1208 18824b58 2008-08-03 rsc break;
1209 18824b58 2008-08-03 rsc }
1210 18824b58 2008-08-03 rsc if((u = getuploadname(sf, name)) != nil){
1211 18824b58 2008-08-03 rsc sf->upload = u;
1212 18824b58 2008-08-03 rsc sf->type = Quploadfile;
1213 18824b58 2008-08-03 rsc break;
1214 18824b58 2008-08-03 rsc }
1215 18824b58 2008-08-03 rsc goto NotFound;
1216 18824b58 2008-08-03 rsc
1217 18824b58 2008-08-03 rsc case Qimage:
1218 18824b58 2008-08-03 rsc if(dotdot){
1219 18824b58 2008-08-03 rsc free(sf->imagekey);
1220 18824b58 2008-08-03 rsc sf->imagekey = nil;
1221 18824b58 2008-08-03 rsc sf->image = 0;
1222 18824b58 2008-08-03 rsc sf->type = Qalbum;
1223 18824b58 2008-08-03 rsc break;
1224 18824b58 2008-08-03 rsc }
1225 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1226 18824b58 2008-08-03 rsc sf->type = Qimagectl;
1227 18824b58 2008-08-03 rsc break;
1228 18824b58 2008-08-03 rsc }
1229 18824b58 2008-08-03 rsc if(strcmp(name, "url") == 0){
1230 18824b58 2008-08-03 rsc sf->type = Qimageurl;
1231 18824b58 2008-08-03 rsc break;
1232 18824b58 2008-08-03 rsc }
1233 18824b58 2008-08-03 rsc if(strcmp(name, "settings") == 0){
1234 18824b58 2008-08-03 rsc sf->type = Qimagesettings;
1235 18824b58 2008-08-03 rsc break;
1236 18824b58 2008-08-03 rsc }
1237 18824b58 2008-08-03 rsc if(strcmp(name, "exif") == 0){
1238 18824b58 2008-08-03 rsc sf->type = Qimageexif;
1239 18824b58 2008-08-03 rsc break;
1240 18824b58 2008-08-03 rsc }
1241 18824b58 2008-08-03 rsc x = imagename(sf);
1242 18824b58 2008-08-03 rsc if(x && strcmp(name, x) == 0){
1243 18824b58 2008-08-03 rsc free(x);
1244 18824b58 2008-08-03 rsc sf->type = Qimagefile;
1245 18824b58 2008-08-03 rsc break;
1246 18824b58 2008-08-03 rsc }
1247 18824b58 2008-08-03 rsc free(x);
1248 18824b58 2008-08-03 rsc goto NotFound;
1249 18824b58 2008-08-03 rsc }
1250 18824b58 2008-08-03 rsc dostat(sf, qid, nil);
1251 18824b58 2008-08-03 rsc fid->qid = *qid;
1252 18824b58 2008-08-03 rsc return nil;
1253 18824b58 2008-08-03 rsc }
1254 18824b58 2008-08-03 rsc
1255 18824b58 2008-08-03 rsc static int
1256 18824b58 2008-08-03 rsc dodirgen(int i, Dir *d, void *v)
1257 18824b58 2008-08-03 rsc {
1258 18824b58 2008-08-03 rsc SmugFid *sf, xsf;
1259 18824b58 2008-08-03 rsc char *key;
1260 18824b58 2008-08-03 rsc vlong id;
1261 18824b58 2008-08-03 rsc Upload *u;
1262 18824b58 2008-08-03 rsc
1263 18824b58 2008-08-03 rsc sf = v;
1264 18824b58 2008-08-03 rsc xsf = *sf;
1265 18824b58 2008-08-03 rsc if(i-- == 0){
1266 18824b58 2008-08-03 rsc xsf.type++; // ctl in every directory
1267 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1268 18824b58 2008-08-03 rsc return 0;
1269 18824b58 2008-08-03 rsc }
1270 18824b58 2008-08-03 rsc
1271 18824b58 2008-08-03 rsc switch(sf->type){
1272 18824b58 2008-08-03 rsc default:
1273 18824b58 2008-08-03 rsc return -1;
1274 18824b58 2008-08-03 rsc
1275 18824b58 2008-08-03 rsc case Qroot:
1276 18824b58 2008-08-03 rsc if(i-- == 0){
1277 18824b58 2008-08-03 rsc xsf.type = Qrpclog;
1278 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1279 18824b58 2008-08-03 rsc return 0;
1280 18824b58 2008-08-03 rsc }
1281 18824b58 2008-08-03 rsc if(i < 0 || i >= nnick)
1282 18824b58 2008-08-03 rsc return -1;
1283 18824b58 2008-08-03 rsc xsf.type = Qnick;
1284 18824b58 2008-08-03 rsc xsf.nickid = i;
1285 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1286 18824b58 2008-08-03 rsc return 0;
1287 18824b58 2008-08-03 rsc
1288 18824b58 2008-08-03 rsc case Qnick:
1289 18824b58 2008-08-03 rsc if(i-- == 0){
1290 18824b58 2008-08-03 rsc xsf.type = Qalbums;
1291 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1292 18824b58 2008-08-03 rsc return 0;
1293 18824b58 2008-08-03 rsc }
1294 18824b58 2008-08-03 rsc if((id = getcategoryindex(sf, i)) < 0)
1295 18824b58 2008-08-03 rsc return -1;
1296 18824b58 2008-08-03 rsc xsf.type = Qcategory;
1297 18824b58 2008-08-03 rsc xsf.category = id;
1298 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1299 18824b58 2008-08-03 rsc return 0;
1300 18824b58 2008-08-03 rsc
1301 18824b58 2008-08-03 rsc case Qalbums:
1302 18824b58 2008-08-03 rsc case Qcategory:
1303 18824b58 2008-08-03 rsc if((id = getalbumindex(sf, i, &key)) < 0)
1304 18824b58 2008-08-03 rsc return -1;
1305 18824b58 2008-08-03 rsc xsf.type = Qalbum;
1306 18824b58 2008-08-03 rsc xsf.album = id;
1307 18824b58 2008-08-03 rsc xsf.albumkey = key;
1308 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1309 18824b58 2008-08-03 rsc free(key);
1310 18824b58 2008-08-03 rsc return 0;
1311 18824b58 2008-08-03 rsc
1312 18824b58 2008-08-03 rsc case Qalbum:
1313 18824b58 2008-08-03 rsc if(i-- == 0){
1314 18824b58 2008-08-03 rsc xsf.type = Qalbumsettings;
1315 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1316 18824b58 2008-08-03 rsc return 0;
1317 18824b58 2008-08-03 rsc }
1318 18824b58 2008-08-03 rsc if((u = getuploadindex(sf, &i)) != nil){
1319 18824b58 2008-08-03 rsc xsf.upload = u;
1320 18824b58 2008-08-03 rsc xsf.type = Quploadfile;
1321 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1322 18824b58 2008-08-03 rsc closeupload(u);
1323 18824b58 2008-08-03 rsc return 0;
1324 18824b58 2008-08-03 rsc }
1325 18824b58 2008-08-03 rsc if((id = getimageindex(sf, i, &key)) < 0)
1326 18824b58 2008-08-03 rsc return -1;
1327 18824b58 2008-08-03 rsc xsf.type = Qimage;
1328 18824b58 2008-08-03 rsc xsf.image = id;
1329 18824b58 2008-08-03 rsc xsf.imagekey = key;
1330 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1331 18824b58 2008-08-03 rsc free(key);
1332 18824b58 2008-08-03 rsc return 0;
1333 18824b58 2008-08-03 rsc
1334 18824b58 2008-08-03 rsc case Qimage:
1335 18824b58 2008-08-03 rsc if(i-- == 0){
1336 18824b58 2008-08-03 rsc xsf.type = Qimagefile;
1337 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1338 18824b58 2008-08-03 rsc return 0;
1339 18824b58 2008-08-03 rsc }
1340 18824b58 2008-08-03 rsc if(i-- == 0){
1341 18824b58 2008-08-03 rsc xsf.type = Qimageexif;
1342 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1343 18824b58 2008-08-03 rsc return 0;
1344 18824b58 2008-08-03 rsc }
1345 18824b58 2008-08-03 rsc if(i-- == 0){
1346 18824b58 2008-08-03 rsc xsf.type = Qimagesettings;
1347 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1348 18824b58 2008-08-03 rsc return 0;
1349 18824b58 2008-08-03 rsc }
1350 18824b58 2008-08-03 rsc if(i-- == 0){
1351 18824b58 2008-08-03 rsc xsf.type = Qimageurl;
1352 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1353 18824b58 2008-08-03 rsc return 0;
1354 18824b58 2008-08-03 rsc }
1355 18824b58 2008-08-03 rsc return -1;
1356 18824b58 2008-08-03 rsc }
1357 18824b58 2008-08-03 rsc }
1358 18824b58 2008-08-03 rsc
1359 18824b58 2008-08-03 rsc static void
1360 18824b58 2008-08-03 rsc xstat(Req *r)
1361 18824b58 2008-08-03 rsc {
1362 18824b58 2008-08-03 rsc dostat(r->fid->aux, nil, &r->d);
1363 18824b58 2008-08-03 rsc respond(r, nil);
1364 18824b58 2008-08-03 rsc }
1365 18824b58 2008-08-03 rsc
1366 18824b58 2008-08-03 rsc static void
1367 18824b58 2008-08-03 rsc xwstat(Req *r)
1368 18824b58 2008-08-03 rsc {
1369 18824b58 2008-08-03 rsc SmugFid *sf;
1370 18824b58 2008-08-03 rsc Json *v;
1371 18824b58 2008-08-03 rsc char *s;
1372 18824b58 2008-08-03 rsc char strid[50];
1373 18824b58 2008-08-03 rsc
1374 18824b58 2008-08-03 rsc sf = r->fid->aux;
1375 18824b58 2008-08-03 rsc if(r->d.uid[0] || r->d.gid[0] || r->d.muid[0] || ~r->d.mode != 0
1376 18824b58 2008-08-03 rsc || ~r->d.atime != 0 || ~r->d.mtime != 0 || ~r->d.length != 0){
1377 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1378 18824b58 2008-08-03 rsc return;
1379 18824b58 2008-08-03 rsc }
1380 18824b58 2008-08-03 rsc if(r->d.name[0]){
1381 18824b58 2008-08-03 rsc switch(sf->type){
1382 18824b58 2008-08-03 rsc default:
1383 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1384 18824b58 2008-08-03 rsc return;
1385 18824b58 2008-08-03 rsc // TODO: rename category
1386 18824b58 2008-08-03 rsc case Qalbum:
1387 18824b58 2008-08-03 rsc snprint(strid, sizeof strid, "%lld", sf->album);
1388 18824b58 2008-08-03 rsc v = ncsmug("smugmug.albums.changeSettings",
1389 18824b58 2008-08-03 rsc "AlbumID", strid, "Title", r->d.name, nil);
1390 18824b58 2008-08-03 rsc if(v == nil)
1391 18824b58 2008-08-03 rsc responderrstr(r);
1392 18824b58 2008-08-03 rsc else
1393 18824b58 2008-08-03 rsc respond(r, nil);
1394 18824b58 2008-08-03 rsc s = smprint("&AlbumID=%lld&", sf->album);
1395 18824b58 2008-08-03 rsc jcacheflush(s);
1396 18824b58 2008-08-03 rsc free(s);
1397 18824b58 2008-08-03 rsc jcacheflush("smugmug.albums.get&");
1398 18824b58 2008-08-03 rsc return;
1399 18824b58 2008-08-03 rsc }
1400 18824b58 2008-08-03 rsc }
1401 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1402 18824b58 2008-08-03 rsc }
1403 18824b58 2008-08-03 rsc
1404 18824b58 2008-08-03 rsc static void
1405 18824b58 2008-08-03 rsc xattach(Req *r)
1406 18824b58 2008-08-03 rsc {
1407 18824b58 2008-08-03 rsc SmugFid *sf;
1408 18824b58 2008-08-03 rsc
1409 18824b58 2008-08-03 rsc sf = emalloc(sizeof *sf);
1410 18824b58 2008-08-03 rsc r->fid->aux = sf;
1411 18824b58 2008-08-03 rsc sf->type = Qroot;
1412 18824b58 2008-08-03 rsc dostat(sf, &r->ofcall.qid, nil);
1413 18824b58 2008-08-03 rsc r->fid->qid = r->ofcall.qid;
1414 18824b58 2008-08-03 rsc respond(r, nil);
1415 18824b58 2008-08-03 rsc }
1416 18824b58 2008-08-03 rsc
1417 18824b58 2008-08-03 rsc void
1418 18824b58 2008-08-03 rsc xopen(Req *r)
1419 18824b58 2008-08-03 rsc {
1420 18824b58 2008-08-03 rsc SmugFid *sf;
1421 18824b58 2008-08-03 rsc
1422 18824b58 2008-08-03 rsc if((r->ifcall.mode&~OTRUNC) > 2){
1423 18824b58 2008-08-03 rsc respond(r, "permission denied");
1424 18824b58 2008-08-03 rsc return;
1425 18824b58 2008-08-03 rsc }
1426 18824b58 2008-08-03 rsc
1427 18824b58 2008-08-03 rsc sf = r->fid->aux;
1428 18824b58 2008-08-03 rsc switch(sf->type){
1429 18824b58 2008-08-03 rsc case Qctl:
1430 18824b58 2008-08-03 rsc case Qnickctl:
1431 18824b58 2008-08-03 rsc case Qalbumsctl:
1432 18824b58 2008-08-03 rsc case Qcategoryctl:
1433 18824b58 2008-08-03 rsc case Qalbumctl:
1434 18824b58 2008-08-03 rsc case Qimagectl:
1435 18824b58 2008-08-03 rsc case Qalbumsettings:
1436 18824b58 2008-08-03 rsc case Qimagesettings:
1437 18824b58 2008-08-03 rsc break;
1438 18824b58 2008-08-03 rsc
1439 18824b58 2008-08-03 rsc case Quploadfile:
1440 18824b58 2008-08-03 rsc if(r->ifcall.mode != OREAD){
1441 18824b58 2008-08-03 rsc lock(&sf->upload->lk);
1442 18824b58 2008-08-03 rsc if(sf->upload->ready){
1443 18824b58 2008-08-03 rsc unlock(&sf->upload->lk);
1444 18824b58 2008-08-03 rsc respond(r, "permission denied");
1445 18824b58 2008-08-03 rsc return;
1446 18824b58 2008-08-03 rsc }
1447 18824b58 2008-08-03 rsc sf->upwriter = 1;
1448 18824b58 2008-08-03 rsc sf->upload->nwriters++;
1449 18824b58 2008-08-03 rsc unlock(&sf->upload->lk);
1450 18824b58 2008-08-03 rsc }
1451 18824b58 2008-08-03 rsc break;
1452 18824b58 2008-08-03 rsc
1453 18824b58 2008-08-03 rsc default:
1454 18824b58 2008-08-03 rsc if(r->ifcall.mode != OREAD){
1455 18824b58 2008-08-03 rsc respond(r, "permission denied");
1456 18824b58 2008-08-03 rsc return;
1457 18824b58 2008-08-03 rsc }
1458 18824b58 2008-08-03 rsc break;
1459 18824b58 2008-08-03 rsc }
1460 18824b58 2008-08-03 rsc
1461 18824b58 2008-08-03 rsc r->ofcall.qid = r->fid->qid;
1462 18824b58 2008-08-03 rsc respond(r, nil);
1463 18824b58 2008-08-03 rsc }
1464 18824b58 2008-08-03 rsc
1465 18824b58 2008-08-03 rsc void
1466 18824b58 2008-08-03 rsc xcreate(Req *r)
1467 18824b58 2008-08-03 rsc {
1468 18824b58 2008-08-03 rsc SmugFid *sf;
1469 18824b58 2008-08-03 rsc Json *v;
1470 18824b58 2008-08-03 rsc vlong id;
1471 18824b58 2008-08-03 rsc char strid[50], *key;
1472 18824b58 2008-08-03 rsc Upload *u;
1473 18824b58 2008-08-03 rsc
1474 18824b58 2008-08-03 rsc sf = r->fid->aux;
1475 18824b58 2008-08-03 rsc switch(sf->type){
1476 18824b58 2008-08-03 rsc case Qnick:
1477 18824b58 2008-08-03 rsc // Create new category.
1478 18824b58 2008-08-03 rsc if(!(r->ifcall.perm&DMDIR))
1479 18824b58 2008-08-03 rsc break;
1480 18824b58 2008-08-03 rsc v = ncsmug("smugmug.categories.create",
1481 18824b58 2008-08-03 rsc "Name", r->ifcall.name, nil);
1482 18824b58 2008-08-03 rsc if(v == nil){
1483 18824b58 2008-08-03 rsc responderrstr(r);
1484 18824b58 2008-08-03 rsc return;
1485 18824b58 2008-08-03 rsc }
1486 18824b58 2008-08-03 rsc id = jint(jwalk(v, "Category/id"));
1487 18824b58 2008-08-03 rsc if(id < 0){
1488 18824b58 2008-08-03 rsc fprint(2, "Create category: %J\n", v);
1489 18824b58 2008-08-03 rsc jclose(v);
1490 18824b58 2008-08-03 rsc responderrstr(r);
1491 18824b58 2008-08-03 rsc return;
1492 18824b58 2008-08-03 rsc }
1493 18824b58 2008-08-03 rsc sf->type = Qcategory;
1494 18824b58 2008-08-03 rsc sf->category = id;
1495 18824b58 2008-08-03 rsc jcacheflush("method=smugmug.users.getTree&");
1496 18824b58 2008-08-03 rsc jcacheflush("method=smugmug.categories.get&");
1497 18824b58 2008-08-03 rsc dostat(sf, &r->ofcall.qid, nil);
1498 18824b58 2008-08-03 rsc respond(r, nil);
1499 18824b58 2008-08-03 rsc return;
1500 18824b58 2008-08-03 rsc
1501 18824b58 2008-08-03 rsc case Qcategory:
1502 18824b58 2008-08-03 rsc // Create new album.
1503 18824b58 2008-08-03 rsc if(!(r->ifcall.perm&DMDIR))
1504 18824b58 2008-08-03 rsc break;
1505 18824b58 2008-08-03 rsc snprint(strid, sizeof strid, "%lld", sf->category);
1506 18824b58 2008-08-03 rsc // Start with most restrictive settings.
1507 18824b58 2008-08-03 rsc v = ncsmug("smugmug.albums.create",
1508 18824b58 2008-08-03 rsc "Title", r->ifcall.name,
1509 18824b58 2008-08-03 rsc "CategoryID", strid,
1510 18824b58 2008-08-03 rsc "Public", "0",
1511 18824b58 2008-08-03 rsc "WorldSearchable", "0",
1512 18824b58 2008-08-03 rsc "SmugSearchable", "0",
1513 18824b58 2008-08-03 rsc nil);
1514 18824b58 2008-08-03 rsc if(v == nil){
1515 18824b58 2008-08-03 rsc responderrstr(r);
1516 18824b58 2008-08-03 rsc return;
1517 18824b58 2008-08-03 rsc }
1518 18824b58 2008-08-03 rsc id = jint(jwalk(v, "Album/id"));
1519 18824b58 2008-08-03 rsc key = jstring(jwalk(v, "Album/Key"));
1520 18824b58 2008-08-03 rsc if(id < 0 || key == nil){
1521 18824b58 2008-08-03 rsc fprint(2, "Create album: %J\n", v);
1522 18824b58 2008-08-03 rsc jclose(v);
1523 18824b58 2008-08-03 rsc responderrstr(r);
1524 18824b58 2008-08-03 rsc return;
1525 18824b58 2008-08-03 rsc }
1526 18824b58 2008-08-03 rsc sf->type = Qalbum;
1527 18824b58 2008-08-03 rsc sf->album = id;
1528 18824b58 2008-08-03 rsc sf->albumkey = estrdup(key);
1529 18824b58 2008-08-03 rsc jclose(v);
1530 18824b58 2008-08-03 rsc jcacheflush("method=smugmug.users.getTree&");
1531 18824b58 2008-08-03 rsc dostat(sf, &r->ofcall.qid, nil);
1532 18824b58 2008-08-03 rsc respond(r, nil);
1533 18824b58 2008-08-03 rsc return;
1534 18824b58 2008-08-03 rsc
1535 18824b58 2008-08-03 rsc case Qalbum:
1536 18824b58 2008-08-03 rsc // Upload image to album.
1537 18824b58 2008-08-03 rsc if(r->ifcall.perm&DMDIR)
1538 18824b58 2008-08-03 rsc break;
1539 18824b58 2008-08-03 rsc u = newupload(sf, r->ifcall.name);
1540 18824b58 2008-08-03 rsc if(u == nil){
1541 18824b58 2008-08-03 rsc responderrstr(r);
1542 18824b58 2008-08-03 rsc return;
1543 18824b58 2008-08-03 rsc }
1544 18824b58 2008-08-03 rsc sf->upload = u;
1545 18824b58 2008-08-03 rsc sf->upwriter = 1;
1546 18824b58 2008-08-03 rsc sf->type = Quploadfile;
1547 18824b58 2008-08-03 rsc dostat(sf, &r->ofcall.qid, nil);
1548 18824b58 2008-08-03 rsc respond(r, nil);
1549 18824b58 2008-08-03 rsc return;
1550 18824b58 2008-08-03 rsc }
1551 18824b58 2008-08-03 rsc respond(r, "permission denied");
1552 18824b58 2008-08-03 rsc }
1553 18824b58 2008-08-03 rsc
1554 18824b58 2008-08-03 rsc static int
1555 18824b58 2008-08-03 rsc writetofd(Req *r, int fd)
1556 18824b58 2008-08-03 rsc {
1557 18824b58 2008-08-03 rsc int total, n;
1558 18824b58 2008-08-03 rsc
1559 18824b58 2008-08-03 rsc total = 0;
1560 18824b58 2008-08-03 rsc while(total < r->ifcall.count){
1561 18824b58 2008-08-03 rsc n = pwrite(fd, (char*)r->ifcall.data+total, r->ifcall.count-total, r->ifcall.offset+total);
1562 18824b58 2008-08-03 rsc if(n <= 0)
1563 18824b58 2008-08-03 rsc return -1;
1564 18824b58 2008-08-03 rsc total += n;
1565 18824b58 2008-08-03 rsc }
1566 18824b58 2008-08-03 rsc r->ofcall.count = r->ifcall.count;
1567 18824b58 2008-08-03 rsc return 0;
1568 18824b58 2008-08-03 rsc }
1569 18824b58 2008-08-03 rsc
1570 18824b58 2008-08-03 rsc static void
1571 18824b58 2008-08-03 rsc readfromfd(Req *r, int fd)
1572 18824b58 2008-08-03 rsc {
1573 18824b58 2008-08-03 rsc int n;
1574 18824b58 2008-08-03 rsc n = pread(fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
1575 18824b58 2008-08-03 rsc if(n < 0)
1576 18824b58 2008-08-03 rsc n = 0;
1577 18824b58 2008-08-03 rsc r->ofcall.count = n;
1578 18824b58 2008-08-03 rsc }
1579 18824b58 2008-08-03 rsc
1580 18824b58 2008-08-03 rsc void
1581 18824b58 2008-08-03 rsc xread(Req *r)
1582 18824b58 2008-08-03 rsc {
1583 18824b58 2008-08-03 rsc SmugFid *sf;
1584 18824b58 2008-08-03 rsc char *data;
1585 18824b58 2008-08-03 rsc int fd;
1586 18824b58 2008-08-03 rsc HTTPHeader hdr;
1587 18824b58 2008-08-03 rsc char *url;
1588 18824b58 2008-08-03 rsc
1589 18824b58 2008-08-03 rsc sf = r->fid->aux;
1590 18824b58 2008-08-03 rsc r->ofcall.count = 0;
1591 18824b58 2008-08-03 rsc switch(sf->type){
1592 18824b58 2008-08-03 rsc default:
1593 18824b58 2008-08-03 rsc respond(r, "not implemented");
1594 18824b58 2008-08-03 rsc return;
1595 18824b58 2008-08-03 rsc case Qroot:
1596 18824b58 2008-08-03 rsc case Qnick:
1597 18824b58 2008-08-03 rsc case Qalbums:
1598 18824b58 2008-08-03 rsc case Qcategory:
1599 18824b58 2008-08-03 rsc case Qalbum:
1600 18824b58 2008-08-03 rsc case Qimage:
1601 18824b58 2008-08-03 rsc dirread9p(r, dodirgen, sf);
1602 18824b58 2008-08-03 rsc break;
1603 18824b58 2008-08-03 rsc case Qrpclog:
1604 18824b58 2008-08-03 rsc rpclogread(r);
1605 18824b58 2008-08-03 rsc return;
1606 18824b58 2008-08-03 rsc case Qctl:
1607 18824b58 2008-08-03 rsc case Qnickctl:
1608 18824b58 2008-08-03 rsc case Qalbumsctl:
1609 18824b58 2008-08-03 rsc case Qcategoryctl:
1610 18824b58 2008-08-03 rsc case Qalbumctl:
1611 18824b58 2008-08-03 rsc case Qimagectl:
1612 18824b58 2008-08-03 rsc case Qimageurl:
1613 18824b58 2008-08-03 rsc case Qimageexif:
1614 18824b58 2008-08-03 rsc case Quploads:
1615 18824b58 2008-08-03 rsc case Qimagesettings:
1616 18824b58 2008-08-03 rsc case Qalbumsettings:
1617 18824b58 2008-08-03 rsc data = readctl(sf);
1618 18824b58 2008-08-03 rsc readstr(r, data);
1619 18824b58 2008-08-03 rsc free(data);
1620 18824b58 2008-08-03 rsc break;
1621 18824b58 2008-08-03 rsc case Qimagefile:
1622 18824b58 2008-08-03 rsc url = imageurl(sf);
1623 18824b58 2008-08-03 rsc if(url == nil || (fd = download(url, &hdr)) < 0){
1624 18824b58 2008-08-03 rsc free(url);
1625 18824b58 2008-08-03 rsc responderrstr(r);
1626 18824b58 2008-08-03 rsc return;
1627 18824b58 2008-08-03 rsc }
1628 18824b58 2008-08-03 rsc readfromfd(r, fd);
1629 18824b58 2008-08-03 rsc free(url);
1630 18824b58 2008-08-03 rsc close(fd);
1631 18824b58 2008-08-03 rsc break;
1632 18824b58 2008-08-03 rsc case Quploadfile:
1633 18824b58 2008-08-03 rsc if(sf->upload)
1634 18824b58 2008-08-03 rsc readfromfd(r, sf->upload->fd);
1635 18824b58 2008-08-03 rsc break;
1636 18824b58 2008-08-03 rsc }
1637 18824b58 2008-08-03 rsc respond(r, nil);
1638 18824b58 2008-08-03 rsc }
1639 18824b58 2008-08-03 rsc
1640 18824b58 2008-08-03 rsc void
1641 18824b58 2008-08-03 rsc xwrite(Req *r)
1642 18824b58 2008-08-03 rsc {
1643 18824b58 2008-08-03 rsc int sync;
1644 18824b58 2008-08-03 rsc char *s, *t, *p;
1645 18824b58 2008-08-03 rsc Json *v;
1646 18824b58 2008-08-03 rsc char strid[50];
1647 18824b58 2008-08-03 rsc SmugFid *sf;
1648 18824b58 2008-08-03 rsc
1649 18824b58 2008-08-03 rsc sf = r->fid->aux;
1650 18824b58 2008-08-03 rsc r->ofcall.count = r->ifcall.count;
1651 18824b58 2008-08-03 rsc sync = (r->ifcall.count==4 && memcmp(r->ifcall.data, "sync", 4) == 0);
1652 18824b58 2008-08-03 rsc switch(sf->type){
1653 18824b58 2008-08-03 rsc case Qctl:
1654 18824b58 2008-08-03 rsc if(sync){
1655 18824b58 2008-08-03 rsc jcacheflush(nil);
1656 18824b58 2008-08-03 rsc respond(r, nil);
1657 18824b58 2008-08-03 rsc return;
1658 18824b58 2008-08-03 rsc }
1659 18824b58 2008-08-03 rsc break;
1660 18824b58 2008-08-03 rsc case Qnickctl:
1661 18824b58 2008-08-03 rsc if(sync){
1662 18824b58 2008-08-03 rsc s = smprint("&NickName=%s&", nickname(sf->nickid));
1663 18824b58 2008-08-03 rsc jcacheflush(s);
1664 18824b58 2008-08-03 rsc free(s);
1665 18824b58 2008-08-03 rsc respond(r, nil);
1666 18824b58 2008-08-03 rsc return;
1667 18824b58 2008-08-03 rsc }
1668 18824b58 2008-08-03 rsc break;
1669 18824b58 2008-08-03 rsc case Qalbumsctl:
1670 18824b58 2008-08-03 rsc case Qcategoryctl:
1671 18824b58 2008-08-03 rsc jcacheflush("smugmug.categories.get");
1672 18824b58 2008-08-03 rsc break;
1673 18824b58 2008-08-03 rsc case Qalbumctl:
1674 18824b58 2008-08-03 rsc if(sync){
1675 18824b58 2008-08-03 rsc s = smprint("&AlbumID=%lld&", sf->album);
1676 18824b58 2008-08-03 rsc jcacheflush(s);
1677 18824b58 2008-08-03 rsc free(s);
1678 18824b58 2008-08-03 rsc respond(r, nil);
1679 18824b58 2008-08-03 rsc return;
1680 18824b58 2008-08-03 rsc }
1681 18824b58 2008-08-03 rsc break;
1682 18824b58 2008-08-03 rsc case Qimagectl:
1683 18824b58 2008-08-03 rsc if(sync){
1684 18824b58 2008-08-03 rsc s = smprint("&ImageID=%lld&", sf->image);
1685 18824b58 2008-08-03 rsc jcacheflush(s);
1686 18824b58 2008-08-03 rsc free(s);
1687 18824b58 2008-08-03 rsc respond(r, nil);
1688 18824b58 2008-08-03 rsc return;
1689 18824b58 2008-08-03 rsc }
1690 18824b58 2008-08-03 rsc break;
1691 18824b58 2008-08-03 rsc case Quploadfile:
1692 18824b58 2008-08-03 rsc if(sf->upload){
1693 18824b58 2008-08-03 rsc if(writetofd(r, sf->upload->fd) < 0){
1694 18824b58 2008-08-03 rsc responderrstr(r);
1695 18824b58 2008-08-03 rsc return;
1696 18824b58 2008-08-03 rsc }
1697 18824b58 2008-08-03 rsc respond(r, nil);
1698 18824b58 2008-08-03 rsc return;
1699 18824b58 2008-08-03 rsc }
1700 18824b58 2008-08-03 rsc break;
1701 18824b58 2008-08-03 rsc case Qimagesettings:
1702 18824b58 2008-08-03 rsc case Qalbumsettings:
1703 18824b58 2008-08-03 rsc s = (char*)r->ifcall.data; // lib9p nul-terminated it
1704 18824b58 2008-08-03 rsc t = strpbrk(s, " \r\t\n");
1705 18824b58 2008-08-03 rsc if(t == nil)
1706 18824b58 2008-08-03 rsc t = "";
1707 18824b58 2008-08-03 rsc else{
1708 18824b58 2008-08-03 rsc *t++ = 0;
1709 18824b58 2008-08-03 rsc while(*t == ' ' || *t == '\r' || *t == '\t' || *t == '\n')
1710 18824b58 2008-08-03 rsc t++;
1711 18824b58 2008-08-03 rsc }
1712 18824b58 2008-08-03 rsc p = strchr(t, '\n');
1713 18824b58 2008-08-03 rsc if(p && p[1] == 0)
1714 18824b58 2008-08-03 rsc *p = 0;
1715 18824b58 2008-08-03 rsc else if(p){
1716 18824b58 2008-08-03 rsc respond(r, "newline in argument");
1717 18824b58 2008-08-03 rsc return;
1718 18824b58 2008-08-03 rsc }
1719 18824b58 2008-08-03 rsc if(sf->type == Qalbumsettings)
1720 18824b58 2008-08-03 rsc goto Albumsettings;
1721 18824b58 2008-08-03 rsc snprint(strid, sizeof strid, "%lld", sf->image);
1722 18824b58 2008-08-03 rsc v = ncsmug("smugmug.images.changeSettings",
1723 18824b58 2008-08-03 rsc "ImageID", strid,
1724 18824b58 2008-08-03 rsc s, t, nil);
1725 18824b58 2008-08-03 rsc if(v == nil)
1726 18824b58 2008-08-03 rsc responderrstr(r);
1727 18824b58 2008-08-03 rsc else
1728 18824b58 2008-08-03 rsc respond(r, nil);
1729 18824b58 2008-08-03 rsc s = smprint("&ImageID=%lld&", sf->image);
1730 18824b58 2008-08-03 rsc jcacheflush(s);
1731 18824b58 2008-08-03 rsc free(s);
1732 18824b58 2008-08-03 rsc return;
1733 18824b58 2008-08-03 rsc Albumsettings:
1734 18824b58 2008-08-03 rsc snprint(strid, sizeof strid, "%lld", sf->album);
1735 18824b58 2008-08-03 rsc v = ncsmug("smugmug.albums.changeSettings",
1736 18824b58 2008-08-03 rsc "AlbumID", strid, s, t, nil);
1737 18824b58 2008-08-03 rsc if(v == nil)
1738 18824b58 2008-08-03 rsc responderrstr(r);
1739 18824b58 2008-08-03 rsc else
1740 18824b58 2008-08-03 rsc respond(r, nil);
1741 18824b58 2008-08-03 rsc s = smprint("&AlbumID=%lld&", sf->album);
1742 18824b58 2008-08-03 rsc jcacheflush(s);
1743 18824b58 2008-08-03 rsc free(s);
1744 18824b58 2008-08-03 rsc return;
1745 18824b58 2008-08-03 rsc }
1746 18824b58 2008-08-03 rsc respond(r, "invalid control message");
1747 18824b58 2008-08-03 rsc return;
1748 18824b58 2008-08-03 rsc }
1749 18824b58 2008-08-03 rsc
1750 18824b58 2008-08-03 rsc void
1751 18824b58 2008-08-03 rsc xremove(Req *r)
1752 18824b58 2008-08-03 rsc {
1753 18824b58 2008-08-03 rsc char id[100];
1754 18824b58 2008-08-03 rsc SmugFid *sf;
1755 18824b58 2008-08-03 rsc Json *v;
1756 18824b58 2008-08-03 rsc
1757 18824b58 2008-08-03 rsc sf = r->fid->aux;
1758 18824b58 2008-08-03 rsc switch(sf->type){
1759 18824b58 2008-08-03 rsc default:
1760 18824b58 2008-08-03 rsc respond(r, "permission denied");
1761 18824b58 2008-08-03 rsc return;
1762 18824b58 2008-08-03 rsc case Qcategoryctl:
1763 18824b58 2008-08-03 rsc case Qalbumctl:
1764 18824b58 2008-08-03 rsc case Qalbumsettings:
1765 18824b58 2008-08-03 rsc case Qimagectl:
1766 18824b58 2008-08-03 rsc case Qimagesettings:
1767 18824b58 2008-08-03 rsc case Qimageexif:
1768 18824b58 2008-08-03 rsc case Qimageurl:
1769 18824b58 2008-08-03 rsc case Qimagefile:
1770 18824b58 2008-08-03 rsc /* ignore remove request, but no error, so rm -r works */
1771 18824b58 2008-08-03 rsc /* you can pretend they get removed and immediately grow back! */
1772 18824b58 2008-08-03 rsc respond(r, nil);
1773 18824b58 2008-08-03 rsc return;
1774 18824b58 2008-08-03 rsc case Qcategory:
1775 18824b58 2008-08-03 rsc v = getalbums(sf);
1776 18824b58 2008-08-03 rsc if(v && v->len > 0){
1777 18824b58 2008-08-03 rsc respond(r, "directory not empty");
1778 18824b58 2008-08-03 rsc return;
1779 18824b58 2008-08-03 rsc }
1780 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", sf->category);
1781 18824b58 2008-08-03 rsc v = ncsmug("smugmug.categories.delete",
1782 18824b58 2008-08-03 rsc "CategoryID", id, nil);
1783 18824b58 2008-08-03 rsc if(v == nil)
1784 18824b58 2008-08-03 rsc responderrstr(r);
1785 18824b58 2008-08-03 rsc else{
1786 18824b58 2008-08-03 rsc jclose(v);
1787 18824b58 2008-08-03 rsc jcacheflush("smugmug.users.getTree");
1788 18824b58 2008-08-03 rsc jcacheflush("smugmug.categories.get");
1789 18824b58 2008-08-03 rsc respond(r, nil);
1790 18824b58 2008-08-03 rsc }
1791 18824b58 2008-08-03 rsc return;
1792 18824b58 2008-08-03 rsc case Qalbum:
1793 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
1794 18824b58 2008-08-03 rsc if(v && v->len > 0){
1795 18824b58 2008-08-03 rsc respond(r, "directory not empty");
1796 18824b58 2008-08-03 rsc return;
1797 18824b58 2008-08-03 rsc }
1798 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", sf->album);
1799 18824b58 2008-08-03 rsc v = ncsmug("smugmug.albums.delete",
1800 18824b58 2008-08-03 rsc "AlbumID", id, nil);
1801 18824b58 2008-08-03 rsc if(v == nil)
1802 18824b58 2008-08-03 rsc responderrstr(r);
1803 18824b58 2008-08-03 rsc else{
1804 18824b58 2008-08-03 rsc jclose(v);
1805 18824b58 2008-08-03 rsc jcacheflush("smugmug.users.getTree");
1806 18824b58 2008-08-03 rsc jcacheflush("smugmug.categories.get");
1807 18824b58 2008-08-03 rsc jcacheflush("smugmug.albums.get");
1808 18824b58 2008-08-03 rsc respond(r, nil);
1809 18824b58 2008-08-03 rsc }
1810 18824b58 2008-08-03 rsc return;
1811 18824b58 2008-08-03 rsc
1812 18824b58 2008-08-03 rsc case Qimage:
1813 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", sf->image);
1814 18824b58 2008-08-03 rsc v = ncsmug("smugmug.images.delete",
1815 18824b58 2008-08-03 rsc "ImageID", id, nil);
1816 18824b58 2008-08-03 rsc if(v == nil)
1817 18824b58 2008-08-03 rsc responderrstr(r);
1818 18824b58 2008-08-03 rsc else{
1819 18824b58 2008-08-03 rsc jclose(v);
1820 18824b58 2008-08-03 rsc snprint(id, sizeof id, "ImageID=%lld&", sf->image);
1821 18824b58 2008-08-03 rsc jcacheflush(id);
1822 18824b58 2008-08-03 rsc jcacheflush("smugmug.images.get&");
1823 18824b58 2008-08-03 rsc respond(r, nil);
1824 18824b58 2008-08-03 rsc }
1825 18824b58 2008-08-03 rsc return;
1826 18824b58 2008-08-03 rsc }
1827 18824b58 2008-08-03 rsc }
1828 18824b58 2008-08-03 rsc
1829 18824b58 2008-08-03 rsc void
1830 18824b58 2008-08-03 rsc xflush(Req *r)
1831 18824b58 2008-08-03 rsc {
1832 18824b58 2008-08-03 rsc rpclogflush(r->oldreq);
1833 18824b58 2008-08-03 rsc respond(r, nil);
1834 18824b58 2008-08-03 rsc }
1835 18824b58 2008-08-03 rsc
1836 18824b58 2008-08-03 rsc Srv xsrv;
1837 18824b58 2008-08-03 rsc
1838 18824b58 2008-08-03 rsc void
1839 18824b58 2008-08-03 rsc xinit(void)
1840 18824b58 2008-08-03 rsc {
1841 18824b58 2008-08-03 rsc xsrv.attach = xattach;
1842 18824b58 2008-08-03 rsc xsrv.open = xopen;
1843 18824b58 2008-08-03 rsc xsrv.create = xcreate;
1844 18824b58 2008-08-03 rsc xsrv.read = xread;
1845 18824b58 2008-08-03 rsc xsrv.stat = xstat;
1846 18824b58 2008-08-03 rsc xsrv.walk1 = xwalk1;
1847 18824b58 2008-08-03 rsc xsrv.clone = xclone;
1848 18824b58 2008-08-03 rsc xsrv.destroyfid = xdestroyfid;
1849 18824b58 2008-08-03 rsc xsrv.remove = xremove;
1850 18824b58 2008-08-03 rsc xsrv.write = xwrite;
1851 18824b58 2008-08-03 rsc xsrv.flush = xflush;
1852 18824b58 2008-08-03 rsc xsrv.wstat = xwstat;
1853 18824b58 2008-08-03 rsc }