1 18824b58 2008-08-03 rsc #include "a.h"
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
28 18824b58 2008-08-03 rsc mylock(Lock *lk)
31 18824b58 2008-08-03 rsc fprint(2, "locked from %p\n", getcallerpc(&lk));
35 18824b58 2008-08-03 rsc myunlock(Lock *lk)
38 18824b58 2008-08-03 rsc fprint(2, "unlocked from %p\n", getcallerpc(&lk));
41 18824b58 2008-08-03 rsc //#define lock mylock
42 18824b58 2008-08-03 rsc //#define unlock myunlock
44 18824b58 2008-08-03 rsc typedef struct Upload Upload;
46 18824b58 2008-08-03 rsc typedef struct SmugFid SmugFid;
47 18824b58 2008-08-03 rsc struct SmugFid
51 18824b58 2008-08-03 rsc vlong category; // -1 for "albums"
53 18824b58 2008-08-03 rsc char *albumkey;
55 18824b58 2008-08-03 rsc char *imagekey;
56 18824b58 2008-08-03 rsc Upload *upload;
57 18824b58 2008-08-03 rsc int upwriter;
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))
67 18824b58 2008-08-03 rsc struct Upload
74 18824b58 2008-08-03 rsc vlong length;
75 18824b58 2008-08-03 rsc char *albumkey;
78 18824b58 2008-08-03 rsc int nwriters;
79 18824b58 2008-08-03 rsc int uploaded;
81 18824b58 2008-08-03 rsc int uploading;
86 18824b58 2008-08-03 rsc QLock uploadlock;
87 18824b58 2008-08-03 rsc Rendez uploadrendez;
89 18824b58 2008-08-03 rsc void uploader(void*);
92 18824b58 2008-08-03 rsc newupload(SmugFid *sf, char *name)
96 18824b58 2008-08-03 rsc char tmp[] = "/var/tmp/smugfs.XXXXXX";
98 18824b58 2008-08-03 rsc if((fd = opentemp(tmp, ORDWR)) < 0)
100 18824b58 2008-08-03 rsc qlock(&uploadlock);
101 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
103 18824b58 2008-08-03 rsc lock(&u->lk);
104 18824b58 2008-08-03 rsc if(u->ref == 0){
108 18824b58 2008-08-03 rsc unlock(&u->lk);
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);
114 18824b58 2008-08-03 rsc u = emalloc(sizeof *u);
115 18824b58 2008-08-03 rsc lock(&u->lk);
117 18824b58 2008-08-03 rsc up = erealloc(up, (nup+1)*sizeof up[0]);
118 18824b58 2008-08-03 rsc up[nup++] = u;
120 18824b58 2008-08-03 rsc qunlock(&uploadlock);
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);
132 18824b58 2008-08-03 rsc closeupload(Upload *u)
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);
140 18824b58 2008-08-03 rsc if(u->ref < 0)
142 18824b58 2008-08-03 rsc if(u->fd >= 0){
143 18824b58 2008-08-03 rsc close(u->fd);
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;
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;
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;
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);
170 18824b58 2008-08-03 rsc getuploadindex(SmugFid *sf, int *index)
175 18824b58 2008-08-03 rsc qlock(&uploadlock);
176 18824b58 2008-08-03 rsc for(i=0; i<nup; 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);
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);
186 18824b58 2008-08-03 rsc unlock(&u->lk);
188 18824b58 2008-08-03 rsc qunlock(&uploadlock);
193 18824b58 2008-08-03 rsc getuploadname(SmugFid *sf, char *name)
198 18824b58 2008-08-03 rsc qlock(&uploadlock);
199 18824b58 2008-08-03 rsc for(i=0; i<nup; 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);
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);
209 18824b58 2008-08-03 rsc unlock(&u->lk);
211 18824b58 2008-08-03 rsc qunlock(&uploadlock);
215 18824b58 2008-08-03 rsc void doupload(Upload*);
218 18824b58 2008-08-03 rsc uploader(void *v)
223 18824b58 2008-08-03 rsc qlock(&uploadlock);
226 18824b58 2008-08-03 rsc for(i=0; i<nup; 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);
237 18824b58 2008-08-03 rsc qlock(&uploadlock);
239 18824b58 2008-08-03 rsc unlock(&u->lk);
242 18824b58 2008-08-03 rsc rsleep(&uploadrendez);
247 18824b58 2008-08-03 rsc kickupload(Upload *u)
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);
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);
266 18824b58 2008-08-03 rsc doupload(Upload *u)
269 18824b58 2008-08-03 rsc vlong datalen;
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;
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);
282 18824b58 2008-08-03 rsc if((d = dirfstat(u->fd)) == nil){
283 18824b58 2008-08-03 rsc fprint(2, "fstat: %r\n");
286 18824b58 2008-08-03 rsc datalen = d->length;
289 18824b58 2008-08-03 rsc memset(&ds, 0, sizeof ds);
290 18824b58 2008-08-03 rsc seek(u->fd, 0, 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);
296 18824b58 2008-08-03 rsc if(total != datalen){
297 18824b58 2008-08-03 rsc fprint(2, "bad total: %lld %lld\n", total, datalen);
300 18824b58 2008-08-03 rsc md5(nil, 0, digest, &ds);
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);
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);
318 18824b58 2008-08-03 rsc if(jv == nil){
319 18824b58 2008-08-03 rsc fprint(2, "upload: %r\n");
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;
328 18824b58 2008-08-03 rsc u->uploaded = 1;
329 18824b58 2008-08-03 rsc rpclog("uploaded: %J", jv);
334 18824b58 2008-08-03 rsc nickindex(char *name)
339 18824b58 2008-08-03 rsc for(i=0; i<nnick; i++)
340 18824b58 2008-08-03 rsc if(strcmp(nick[i], name) == 0)
342 18824b58 2008-08-03 rsc v = smug("smugmug.users.getTree", "NickName", name, nil);
343 18824b58 2008-08-03 rsc if(v == nil)
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++;
351 18824b58 2008-08-03 rsc nickname(int i)
353 18824b58 2008-08-03 rsc if(i < 0 || i >= nnick)
355 18824b58 2008-08-03 rsc return nick[i];
359 18824b58 2008-08-03 rsc responderrstr(Req *r)
361 18824b58 2008-08-03 rsc char err[ERRMAX];
363 18824b58 2008-08-03 rsc rerrstr(err, sizeof err);
364 18824b58 2008-08-03 rsc respond(r, err);
367 18824b58 2008-08-03 rsc static char*
368 18824b58 2008-08-03 rsc xclone(Fid *oldfid, Fid *newfid)
370 18824b58 2008-08-03 rsc SmugFid *sf;
372 18824b58 2008-08-03 rsc if(oldfid->aux == nil)
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;
388 18824b58 2008-08-03 rsc xdestroyfid(Fid *fid)
390 18824b58 2008-08-03 rsc SmugFid *sf;
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);
400 18824b58 2008-08-03 rsc closeupload(sf->upload);
401 18824b58 2008-08-03 rsc sf->upload = nil;
406 18824b58 2008-08-03 rsc static Json*
407 18824b58 2008-08-03 rsc getcategories(SmugFid *sf)
409 18824b58 2008-08-03 rsc Json *v, *w;
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"));
417 18824b58 2008-08-03 rsc static Json*
418 18824b58 2008-08-03 rsc getcategorytree(SmugFid *sf)
420 18824b58 2008-08-03 rsc Json *v, *w;
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"));
428 18824b58 2008-08-03 rsc static Json*
429 18824b58 2008-08-03 rsc getcategory(SmugFid *sf, vlong id)
432 18824b58 2008-08-03 rsc Json *v, *w;
434 18824b58 2008-08-03 rsc v = getcategorytree(sf);
435 18824b58 2008-08-03 rsc if(v == 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]);
448 18824b58 2008-08-03 rsc static vlong
449 18824b58 2008-08-03 rsc getcategoryid(SmugFid *sf, char *name)
455 18824b58 2008-08-03 rsc v = getcategories(sf);
456 18824b58 2008-08-03 rsc if(v == nil)
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"));
473 18824b58 2008-08-03 rsc static vlong
474 18824b58 2008-08-03 rsc getcategoryindex(SmugFid *sf, int i)
479 18824b58 2008-08-03 rsc v = getcategories(sf);
480 18824b58 2008-08-03 rsc if(v == nil)
482 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
486 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
491 18824b58 2008-08-03 rsc static Json*
492 18824b58 2008-08-03 rsc getalbum(SmugFid *sf, vlong albumid, char *albumkey)
494 18824b58 2008-08-03 rsc char id[50];
495 18824b58 2008-08-03 rsc Json *v, *w;
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"));
506 18824b58 2008-08-03 rsc static Json*
507 18824b58 2008-08-03 rsc getalbums(SmugFid *sf)
509 18824b58 2008-08-03 rsc Json *v, *w;
511 18824b58 2008-08-03 rsc if(sf->category >= 0)
512 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
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"));
521 18824b58 2008-08-03 rsc static vlong
522 18824b58 2008-08-03 rsc getalbumid(SmugFid *sf, char *name, char **keyp)
529 18824b58 2008-08-03 rsc v = getalbums(sf);
530 18824b58 2008-08-03 rsc if(v == nil)
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){
541 18824b58 2008-08-03 rsc *keyp = estrdup(key);
550 18824b58 2008-08-03 rsc static vlong
551 18824b58 2008-08-03 rsc getalbumindex(SmugFid *sf, int i, char **keyp)
557 18824b58 2008-08-03 rsc v = getalbums(sf);
558 18824b58 2008-08-03 rsc if(v == nil)
560 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
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){
571 18824b58 2008-08-03 rsc *keyp = estrdup(key);
576 18824b58 2008-08-03 rsc static Json*
577 18824b58 2008-08-03 rsc getimages(SmugFid *sf, vlong albumid, char *albumkey)
579 18824b58 2008-08-03 rsc char id[50];
580 18824b58 2008-08-03 rsc Json *v, *w;
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"));
591 18824b58 2008-08-03 rsc static vlong
592 18824b58 2008-08-03 rsc getimageid(SmugFid *sf, char *name, char **keyp)
600 18824b58 2008-08-03 rsc id = strtol(name, &p, 10);
601 18824b58 2008-08-03 rsc if(*p != 0 || *name == 0)
604 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
605 18824b58 2008-08-03 rsc if(v == nil)
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){
615 18824b58 2008-08-03 rsc *keyp = estrdup(key);
624 18824b58 2008-08-03 rsc static Json*
625 18824b58 2008-08-03 rsc getimageinfo(SmugFid *sf, vlong imageid, char *imagekey)
627 18824b58 2008-08-03 rsc char id[50];
628 18824b58 2008-08-03 rsc Json *v, *w;
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"));
639 18824b58 2008-08-03 rsc static Json*
640 18824b58 2008-08-03 rsc getimageexif(SmugFid *sf, vlong imageid, char *imagekey)
642 18824b58 2008-08-03 rsc char id[50];
643 18824b58 2008-08-03 rsc Json *v, *w;
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"));
654 18824b58 2008-08-03 rsc static vlong
655 18824b58 2008-08-03 rsc getimageindex(SmugFid *sf, int i, char **keyp)
661 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
662 18824b58 2008-08-03 rsc if(v == nil)
664 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
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){
675 18824b58 2008-08-03 rsc *keyp = estrdup(key);
680 18824b58 2008-08-03 rsc static char*
681 18824b58 2008-08-03 rsc categoryname(SmugFid *sf)
686 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
687 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "Name"));
689 18824b58 2008-08-03 rsc s = estrdup(s);
694 18824b58 2008-08-03 rsc static char*
695 18824b58 2008-08-03 rsc albumname(SmugFid *sf)
700 18824b58 2008-08-03 rsc v = getalbum(sf, sf->album, sf->albumkey);
701 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "Title"));
703 18824b58 2008-08-03 rsc s = estrdup(s);
708 18824b58 2008-08-03 rsc static char*
709 18824b58 2008-08-03 rsc imagename(SmugFid *sf)
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);
719 18824b58 2008-08-03 rsc s = smprint("%lld.jpg", sf->image); // TODO: use Format
724 18824b58 2008-08-03 rsc static vlong
725 18824b58 2008-08-03 rsc imagelength(SmugFid *sf)
727 18824b58 2008-08-03 rsc vlong length;
730 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
731 18824b58 2008-08-03 rsc length = jint(jwalk(v, "Size"));
733 18824b58 2008-08-03 rsc return length;
736 18824b58 2008-08-03 rsc static struct {
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",
752 18824b58 2008-08-03 rsc static char*
753 18824b58 2008-08-03 rsc imageurl(SmugFid *sf)
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);
771 18824b58 2008-08-03 rsc static char* imagestrings[] =
774 18824b58 2008-08-03 rsc "LastUpdated",
777 18824b58 2008-08-03 rsc "Watermark",
785 18824b58 2008-08-03 rsc "MediumURL",
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",
794 18824b58 2008-08-03 rsc static char* albumbools[] =
797 18824b58 2008-08-03 rsc "Printable",
798 18824b58 2008-08-03 rsc "Filenames",
801 18824b58 2008-08-03 rsc "Originals",
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",
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",
818 18824b58 2008-08-03 rsc static char* albumstrings[] =
820 18824b58 2008-08-03 rsc "Description"
823 18824b58 2008-08-03 rsc "PasswordHint",
824 18824b58 2008-08-03 rsc "SortMethod",
825 18824b58 2008-08-03 rsc "LastUpdated",
828 18824b58 2008-08-03 rsc static char*
829 18824b58 2008-08-03 rsc readctl(SmugFid *sf)
834 18824b58 2008-08-03 rsc Json *v, *vv;
838 18824b58 2008-08-03 rsc switch(sf->type){
840 18824b58 2008-08-03 rsc return smprint("%#J\n", userinfo);
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++){
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);
852 18824b58 2008-08-03 rsc qunlock(&uploadlock);
853 18824b58 2008-08-03 rsc return fmtstrflush(&fmt);
855 18824b58 2008-08-03 rsc case Qnickctl:
856 18824b58 2008-08-03 rsc v = getcategories(sf);
859 18824b58 2008-08-03 rsc case Qcategoryctl:
860 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
863 18824b58 2008-08-03 rsc case Qalbumctl:
864 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
867 18824b58 2008-08-03 rsc case Qalbumsctl:
868 18824b58 2008-08-03 rsc v = getalbums(sf);
871 18824b58 2008-08-03 rsc case Qimagectl:
872 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
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);
882 18824b58 2008-08-03 rsc return fmtstrflush(&fmt);
884 18824b58 2008-08-03 rsc case Qimageexif:
885 18824b58 2008-08-03 rsc v = getimageexif(sf, sf->image, sf->imagekey);
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]);
902 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%J\n", albumbools[i], vv);
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]));
907 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%s\n", albumstrings[i], s);
909 18824b58 2008-08-03 rsc s = fmtstrflush(&fmt);
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]));
929 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%s\n", imagestrings[i], s);
931 18824b58 2008-08-03 rsc s = fmtstrflush(&fmt);
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);
945 18824b58 2008-08-03 rsc dostat(SmugFid *sf, Qid *qid, Dir *dir)
949 18824b58 2008-08-03 rsc int freename;
953 18824b58 2008-08-03 rsc vlong length;
955 18824b58 2008-08-03 rsc memset(&q, 0, sizeof q);
957 18824b58 2008-08-03 rsc freename = 0;
958 18824b58 2008-08-03 rsc uid = "smugfs";
961 18824b58 2008-08-03 rsc q.path = QPATH(sf->type, sf->nickid);
963 18824b58 2008-08-03 rsc mode = 0444;
965 18824b58 2008-08-03 rsc switch(sf->type){
968 18824b58 2008-08-03 rsc q.type = QTDIR;
971 18824b58 2008-08-03 rsc name = "ctl";
972 18824b58 2008-08-03 rsc mode |= 0222;
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);
978 18824b58 2008-08-03 rsc length = strlen(s);
982 18824b58 2008-08-03 rsc case Qrpclog:
983 18824b58 2008-08-03 rsc name = "rpclog";
986 18824b58 2008-08-03 rsc name = nickname(sf->nickid);
987 18824b58 2008-08-03 rsc q.type = QTDIR;
989 18824b58 2008-08-03 rsc case Qnickctl:
990 18824b58 2008-08-03 rsc name = "ctl";
991 18824b58 2008-08-03 rsc mode |= 0222;
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;
997 18824b58 2008-08-03 rsc case Qalbumsctl:
998 18824b58 2008-08-03 rsc name = "ctl";
999 18824b58 2008-08-03 rsc mode |= 0222;
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;
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);
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;
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);
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);
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){
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);
1036 18824b58 2008-08-03 rsc length = dd->length;
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;
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;
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);
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);
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);
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);
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);
1076 18824b58 2008-08-03 rsc name = "?egreg";
1077 18824b58 2008-08-03 rsc q.path = 0;
1081 18824b58 2008-08-03 rsc if(name == nil){
1082 18824b58 2008-08-03 rsc name = "???";
1083 18824b58 2008-08-03 rsc freename = 0;
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;
1101 18824b58 2008-08-03 rsc if(freename)
1102 18824b58 2008-08-03 rsc free(name);
1105 18824b58 2008-08-03 rsc static char*
1106 18824b58 2008-08-03 rsc xwalk1(Fid *fid, char *name, Qid *qid)
1108 18824b58 2008-08-03 rsc int dotdot, i;
1111 18824b58 2008-08-03 rsc SmugFid *sf;
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){
1120 18824b58 2008-08-03 rsc return "file not found";
1122 18824b58 2008-08-03 rsc case Qroot:
1125 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1126 18824b58 2008-08-03 rsc sf->type = Qctl;
1129 18824b58 2008-08-03 rsc if(strcmp(name, "uploads") == 0){
1130 18824b58 2008-08-03 rsc sf->type = Quploads;
1133 18824b58 2008-08-03 rsc if(strcmp(name, "rpclog") == 0){
1134 18824b58 2008-08-03 rsc sf->type = Qrpclog;
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;
1142 18824b58 2008-08-03 rsc goto NotFound;
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;
1150 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1151 18824b58 2008-08-03 rsc sf->type = Qnickctl;
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;
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;
1164 18824b58 2008-08-03 rsc goto NotFound;
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;
1173 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1174 18824b58 2008-08-03 rsc sf->type++;
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;
1183 18824b58 2008-08-03 rsc goto NotFound;
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;
1193 18824b58 2008-08-03 rsc sf->type = Qcategory;
1196 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1197 18824b58 2008-08-03 rsc sf->type = Qalbumctl;
1200 18824b58 2008-08-03 rsc if(strcmp(name, "settings") == 0){
1201 18824b58 2008-08-03 rsc sf->type = Qalbumsettings;
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;
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;
1215 18824b58 2008-08-03 rsc goto NotFound;
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;
1225 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1226 18824b58 2008-08-03 rsc sf->type = Qimagectl;
1229 18824b58 2008-08-03 rsc if(strcmp(name, "url") == 0){
1230 18824b58 2008-08-03 rsc sf->type = Qimageurl;
1233 18824b58 2008-08-03 rsc if(strcmp(name, "settings") == 0){
1234 18824b58 2008-08-03 rsc sf->type = Qimagesettings;
1237 18824b58 2008-08-03 rsc if(strcmp(name, "exif") == 0){
1238 18824b58 2008-08-03 rsc sf->type = Qimageexif;
1241 18824b58 2008-08-03 rsc x = imagename(sf);
1242 18824b58 2008-08-03 rsc if(x && strcmp(name, x) == 0){
1244 18824b58 2008-08-03 rsc sf->type = Qimagefile;
1248 18824b58 2008-08-03 rsc goto NotFound;
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;
1256 18824b58 2008-08-03 rsc dodirgen(int i, Dir *d, void *v)
1258 18824b58 2008-08-03 rsc SmugFid *sf, xsf;
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);
1271 18824b58 2008-08-03 rsc switch(sf->type){
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);
1281 18824b58 2008-08-03 rsc if(i < 0 || i >= nnick)
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);
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);
1294 18824b58 2008-08-03 rsc if((id = getcategoryindex(sf, i)) < 0)
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);
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)
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);
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);
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);
1325 18824b58 2008-08-03 rsc if((id = getimageindex(sf, i, &key)) < 0)
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);
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);
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);
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);
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);
1359 18824b58 2008-08-03 rsc static void
1360 18824b58 2008-08-03 rsc xstat(Req *r)
1362 18824b58 2008-08-03 rsc dostat(r->fid->aux, nil, &r->d);
1363 18824b58 2008-08-03 rsc respond(r, nil);
1366 18824b58 2008-08-03 rsc static void
1367 18824b58 2008-08-03 rsc xwstat(Req *r)
1369 18824b58 2008-08-03 rsc SmugFid *sf;
1372 18824b58 2008-08-03 rsc char strid[50];
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");
1380 18824b58 2008-08-03 rsc if(r->d.name[0]){
1381 18824b58 2008-08-03 rsc switch(sf->type){
1383 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
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);
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);
1397 18824b58 2008-08-03 rsc jcacheflush("smugmug.albums.get&");
1401 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1404 18824b58 2008-08-03 rsc static void
1405 18824b58 2008-08-03 rsc xattach(Req *r)
1407 18824b58 2008-08-03 rsc SmugFid *sf;
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);
1418 18824b58 2008-08-03 rsc xopen(Req *r)
1420 18824b58 2008-08-03 rsc SmugFid *sf;
1422 18824b58 2008-08-03 rsc if((r->ifcall.mode&~OTRUNC) > 2){
1423 18824b58 2008-08-03 rsc respond(r, "permission denied");
1427 18824b58 2008-08-03 rsc sf = r->fid->aux;
1428 18824b58 2008-08-03 rsc switch(sf->type){
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:
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");
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);
1454 18824b58 2008-08-03 rsc if(r->ifcall.mode != OREAD){
1455 18824b58 2008-08-03 rsc respond(r, "permission denied");
1461 18824b58 2008-08-03 rsc r->ofcall.qid = r->fid->qid;
1462 18824b58 2008-08-03 rsc respond(r, nil);
1466 18824b58 2008-08-03 rsc xcreate(Req *r)
1468 18824b58 2008-08-03 rsc SmugFid *sf;
1471 18824b58 2008-08-03 rsc char strid[50], *key;
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))
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);
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);
1490 18824b58 2008-08-03 rsc responderrstr(r);
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);
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))
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",
1514 18824b58 2008-08-03 rsc if(v == nil){
1515 18824b58 2008-08-03 rsc responderrstr(r);
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);
1523 18824b58 2008-08-03 rsc responderrstr(r);
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);
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);
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)
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);
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);
1551 18824b58 2008-08-03 rsc respond(r, "permission denied");
1555 18824b58 2008-08-03 rsc writetofd(Req *r, int fd)
1557 18824b58 2008-08-03 rsc int total, n;
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);
1564 18824b58 2008-08-03 rsc total += n;
1566 18824b58 2008-08-03 rsc r->ofcall.count = r->ifcall.count;
1570 18824b58 2008-08-03 rsc static void
1571 18824b58 2008-08-03 rsc readfromfd(Req *r, int fd)
1574 18824b58 2008-08-03 rsc n = pread(fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
1577 18824b58 2008-08-03 rsc r->ofcall.count = n;
1581 18824b58 2008-08-03 rsc xread(Req *r)
1583 18824b58 2008-08-03 rsc SmugFid *sf;
1584 18824b58 2008-08-03 rsc char *data;
1586 18824b58 2008-08-03 rsc HTTPHeader hdr;
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){
1593 18824b58 2008-08-03 rsc respond(r, "not implemented");
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);
1603 18824b58 2008-08-03 rsc case Qrpclog:
1604 18824b58 2008-08-03 rsc rpclogread(r);
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);
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){
1625 18824b58 2008-08-03 rsc responderrstr(r);
1628 18824b58 2008-08-03 rsc readfromfd(r, fd);
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);
1637 18824b58 2008-08-03 rsc respond(r, nil);
1641 18824b58 2008-08-03 rsc xwrite(Req *r)
1644 18824b58 2008-08-03 rsc char *s, *t, *p;
1646 18824b58 2008-08-03 rsc char strid[50];
1647 18824b58 2008-08-03 rsc SmugFid *sf;
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){
1655 18824b58 2008-08-03 rsc jcacheflush(nil);
1656 18824b58 2008-08-03 rsc respond(r, nil);
1660 18824b58 2008-08-03 rsc case Qnickctl:
1662 18824b58 2008-08-03 rsc s = smprint("&NickName=%s&", nickname(sf->nickid));
1663 18824b58 2008-08-03 rsc jcacheflush(s);
1665 18824b58 2008-08-03 rsc respond(r, nil);
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");
1673 18824b58 2008-08-03 rsc case Qalbumctl:
1675 18824b58 2008-08-03 rsc s = smprint("&AlbumID=%lld&", sf->album);
1676 18824b58 2008-08-03 rsc jcacheflush(s);
1678 18824b58 2008-08-03 rsc respond(r, nil);
1682 18824b58 2008-08-03 rsc case Qimagectl:
1684 18824b58 2008-08-03 rsc s = smprint("&ImageID=%lld&", sf->image);
1685 18824b58 2008-08-03 rsc jcacheflush(s);
1687 18824b58 2008-08-03 rsc respond(r, nil);
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);
1697 18824b58 2008-08-03 rsc respond(r, nil);
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)
1709 18824b58 2008-08-03 rsc while(*t == ' ' || *t == '\r' || *t == '\t' || *t == '\n')
1712 18824b58 2008-08-03 rsc p = strchr(t, '\n');
1713 18824b58 2008-08-03 rsc if(p && p[1] == 0)
1715 18824b58 2008-08-03 rsc else if(p){
1716 18824b58 2008-08-03 rsc respond(r, "newline in argument");
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);
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);
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);
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);
1746 18824b58 2008-08-03 rsc respond(r, "invalid control message");
1751 18824b58 2008-08-03 rsc xremove(Req *r)
1753 18824b58 2008-08-03 rsc char id[100];
1754 18824b58 2008-08-03 rsc SmugFid *sf;
1757 18824b58 2008-08-03 rsc sf = r->fid->aux;
1758 18824b58 2008-08-03 rsc switch(sf->type){
1760 18824b58 2008-08-03 rsc respond(r, "permission denied");
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);
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");
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);
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);
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");
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);
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);
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);
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);
1830 18824b58 2008-08-03 rsc xflush(Req *r)
1832 18824b58 2008-08-03 rsc rpclogflush(r->oldreq);
1833 18824b58 2008-08-03 rsc respond(r, nil);
1839 18824b58 2008-08-03 rsc xinit(void)
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;