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 if(--u->ref > 0){
136 18824b58 2008-08-03 rsc unlock(&u->lk);
139 18824b58 2008-08-03 rsc if(u->ref < 0)
141 18824b58 2008-08-03 rsc if(u->fd >= 0){
142 18824b58 2008-08-03 rsc close(u->fd);
145 18824b58 2008-08-03 rsc if(u->name){
146 18824b58 2008-08-03 rsc free(u->name);
147 18824b58 2008-08-03 rsc u->name = nil;
149 18824b58 2008-08-03 rsc if(u->file){
150 18824b58 2008-08-03 rsc remove(u->file);
151 18824b58 2008-08-03 rsc free(u->file);
152 18824b58 2008-08-03 rsc u->file = nil;
154 18824b58 2008-08-03 rsc u->album = 0;
155 18824b58 2008-08-03 rsc if(u->albumkey){
156 18824b58 2008-08-03 rsc free(u->albumkey);
157 18824b58 2008-08-03 rsc u->albumkey = nil;
159 18824b58 2008-08-03 rsc u->size = 0;
160 18824b58 2008-08-03 rsc u->ready = 0;
161 18824b58 2008-08-03 rsc u->nwriters = 0;
162 18824b58 2008-08-03 rsc u->uploaded = 0;
163 18824b58 2008-08-03 rsc u->uploading = 0;
164 18824b58 2008-08-03 rsc u->length = 0;
165 18824b58 2008-08-03 rsc unlock(&u->lk);
169 18824b58 2008-08-03 rsc getuploadindex(SmugFid *sf, int *index)
174 18824b58 2008-08-03 rsc qlock(&uploadlock);
175 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
177 18824b58 2008-08-03 rsc lock(&u->lk);
178 18824b58 2008-08-03 rsc if(u->ref > 0 && !u->uploaded && u->album == sf->album && (*index)-- == 0){
179 18824b58 2008-08-03 rsc qunlock(&uploadlock);
181 18824b58 2008-08-03 rsc unlock(&u->lk);
184 18824b58 2008-08-03 rsc unlock(&u->lk);
186 18824b58 2008-08-03 rsc qunlock(&uploadlock);
191 18824b58 2008-08-03 rsc getuploadname(SmugFid *sf, char *name)
196 18824b58 2008-08-03 rsc qlock(&uploadlock);
197 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
199 18824b58 2008-08-03 rsc lock(&u->lk);
200 18824b58 2008-08-03 rsc if(u->ref > 0 && !u->uploaded && u->album == sf->album && strcmp(name, u->name) == 0){
201 18824b58 2008-08-03 rsc qunlock(&uploadlock);
203 18824b58 2008-08-03 rsc unlock(&u->lk);
206 18824b58 2008-08-03 rsc unlock(&u->lk);
208 18824b58 2008-08-03 rsc qunlock(&uploadlock);
212 18824b58 2008-08-03 rsc void doupload(Upload*);
215 18824b58 2008-08-03 rsc uploader(void *v)
220 18824b58 2008-08-03 rsc qlock(&uploadlock);
223 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
225 18824b58 2008-08-03 rsc lock(&u->lk);
226 18824b58 2008-08-03 rsc if(u->ref > 0 && u->ready && !u->uploading && !u->uploaded){
227 18824b58 2008-08-03 rsc u->uploading = 1;
228 18824b58 2008-08-03 rsc unlock(&u->lk);
229 18824b58 2008-08-03 rsc qunlock(&uploadlock);
230 18824b58 2008-08-03 rsc doupload(u);
231 18824b58 2008-08-03 rsc closeupload(u);
233 18824b58 2008-08-03 rsc qlock(&uploadlock);
235 18824b58 2008-08-03 rsc unlock(&u->lk);
238 18824b58 2008-08-03 rsc rsleep(&uploadrendez);
243 18824b58 2008-08-03 rsc kickupload(Upload *u)
247 18824b58 2008-08-03 rsc lock(&u->lk);
248 18824b58 2008-08-03 rsc if((d = dirfstat(u->fd)) != nil)
249 18824b58 2008-08-03 rsc u->length = d->length;
250 18824b58 2008-08-03 rsc close(u->fd);
253 18824b58 2008-08-03 rsc u->ready = 1;
254 18824b58 2008-08-03 rsc unlock(&u->lk);
255 18824b58 2008-08-03 rsc qlock(&uploadlock);
256 18824b58 2008-08-03 rsc rwakeup(&uploadrendez);
257 18824b58 2008-08-03 rsc qunlock(&uploadlock);
261 18824b58 2008-08-03 rsc doupload(Upload *u)
264 18824b58 2008-08-03 rsc vlong datalen;
267 18824b58 2008-08-03 rsc char buf[8192];
268 18824b58 2008-08-03 rsc int n, total;
269 18824b58 2008-08-03 rsc uchar digest[MD5dlen];
270 18824b58 2008-08-03 rsc DigestState ds;
273 18824b58 2008-08-03 rsc if((u->fd = open(u->file, OREAD)) < 0){
274 18824b58 2008-08-03 rsc fprint(2, "cannot reopen temporary file %s: %r\n", u->file);
277 18824b58 2008-08-03 rsc if((d = dirfstat(u->fd)) == nil){
278 18824b58 2008-08-03 rsc fprint(2, "fstat: %r\n");
281 18824b58 2008-08-03 rsc datalen = d->length;
284 18824b58 2008-08-03 rsc memset(&ds, 0, sizeof ds);
285 18824b58 2008-08-03 rsc seek(u->fd, 0, 0);
287 18824b58 2008-08-03 rsc while((n = read(u->fd, buf, sizeof buf)) > 0){
288 18824b58 2008-08-03 rsc md5((uchar*)buf, n, nil, &ds);
291 18824b58 2008-08-03 rsc if(total != datalen){
292 18824b58 2008-08-03 rsc fprint(2, "bad total: %lld %lld\n", total, datalen);
295 18824b58 2008-08-03 rsc md5(nil, 0, digest, &ds);
297 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
298 18824b58 2008-08-03 rsc fmtprint(&fmt, "PUT /%s HTTP/1.0\r\n", u->name);
299 18824b58 2008-08-03 rsc fmtprint(&fmt, "Content-Length: %lld\r\n", datalen);
300 18824b58 2008-08-03 rsc fmtprint(&fmt, "Content-MD5: %.16lH\r\n", digest);
301 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-SessionID: %s\r\n", sessid);
302 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-Version: %s\r\n", API_VERSION);
303 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-ResponseType: JSON\r\n");
304 18824b58 2008-08-03 rsc // Can send X-Smug-ImageID instead to replace existing files.
305 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-AlbumID: %lld\r\n", u->album);
306 18824b58 2008-08-03 rsc fmtprint(&fmt, "X-Smug-FileName: %s\r\n", u->name);
307 18824b58 2008-08-03 rsc fmtprint(&fmt, "\r\n");
308 18824b58 2008-08-03 rsc req = fmtstrflush(&fmt);
310 18824b58 2008-08-03 rsc seek(u->fd, 0, 0);
311 18824b58 2008-08-03 rsc jv = jsonupload(&http, UPLOAD_HOST, req, u->fd, datalen);
313 18824b58 2008-08-03 rsc if(jv == nil){
314 18824b58 2008-08-03 rsc fprint(2, "upload: %r\n");
318 18824b58 2008-08-03 rsc close(u->fd);
319 18824b58 2008-08-03 rsc remove(u->file);
320 18824b58 2008-08-03 rsc free(u->file);
321 18824b58 2008-08-03 rsc u->file = nil;
323 18824b58 2008-08-03 rsc u->uploaded = 1;
324 18824b58 2008-08-03 rsc rpclog("uploaded: %J", jv);
329 18824b58 2008-08-03 rsc nickindex(char *name)
334 18824b58 2008-08-03 rsc for(i=0; i<nnick; i++)
335 18824b58 2008-08-03 rsc if(strcmp(nick[i], name) == 0)
337 18824b58 2008-08-03 rsc v = smug("smugmug.users.getTree", "NickName", name, nil);
338 18824b58 2008-08-03 rsc if(v == nil)
340 18824b58 2008-08-03 rsc nick = erealloc(nick, (nnick+1)*sizeof nick[0]);
341 18824b58 2008-08-03 rsc nick[nnick] = estrdup(name);
342 18824b58 2008-08-03 rsc return nnick++;
346 18824b58 2008-08-03 rsc nickname(int i)
348 18824b58 2008-08-03 rsc if(i < 0 || i >= nnick)
350 18824b58 2008-08-03 rsc return nick[i];
354 18824b58 2008-08-03 rsc responderrstr(Req *r)
356 18824b58 2008-08-03 rsc char err[ERRMAX];
358 18824b58 2008-08-03 rsc rerrstr(err, sizeof err);
359 18824b58 2008-08-03 rsc respond(r, err);
362 18824b58 2008-08-03 rsc static char*
363 18824b58 2008-08-03 rsc xclone(Fid *oldfid, Fid *newfid)
365 18824b58 2008-08-03 rsc SmugFid *sf;
367 18824b58 2008-08-03 rsc if(oldfid->aux == nil)
370 18824b58 2008-08-03 rsc sf = emalloc(sizeof *sf);
371 18824b58 2008-08-03 rsc *sf = *(SmugFid*)oldfid->aux;
372 18824b58 2008-08-03 rsc sf->upload = nil;
373 18824b58 2008-08-03 rsc sf->upwriter = 0;
374 18824b58 2008-08-03 rsc if(sf->albumkey)
375 18824b58 2008-08-03 rsc sf->albumkey = estrdup(sf->albumkey);
376 18824b58 2008-08-03 rsc if(sf->imagekey)
377 18824b58 2008-08-03 rsc sf->imagekey = estrdup(sf->imagekey);
378 18824b58 2008-08-03 rsc newfid->aux = sf;
383 18824b58 2008-08-03 rsc xdestroyfid(Fid *fid)
385 18824b58 2008-08-03 rsc SmugFid *sf;
387 18824b58 2008-08-03 rsc sf = fid->aux;
388 18824b58 2008-08-03 rsc free(sf->albumkey);
389 18824b58 2008-08-03 rsc free(sf->imagekey);
390 18824b58 2008-08-03 rsc if(sf->upload){
391 18824b58 2008-08-03 rsc if(sf->upwriter && --sf->upload->nwriters == 0){
392 18824b58 2008-08-03 rsc fprint(2, "should upload %s\n", sf->upload->name);
393 18824b58 2008-08-03 rsc kickupload(sf->upload);
395 18824b58 2008-08-03 rsc closeupload(sf->upload);
396 18824b58 2008-08-03 rsc sf->upload = nil;
401 18824b58 2008-08-03 rsc static Json*
402 18824b58 2008-08-03 rsc getcategories(SmugFid *sf)
404 18824b58 2008-08-03 rsc Json *v, *w;
406 18824b58 2008-08-03 rsc v = smug("smugmug.categories.get", "NickName", nickname(sf->nickid), nil);
407 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Categories"));
412 18824b58 2008-08-03 rsc static Json*
413 18824b58 2008-08-03 rsc getcategorytree(SmugFid *sf)
415 18824b58 2008-08-03 rsc Json *v, *w;
417 18824b58 2008-08-03 rsc v = smug("smugmug.users.getTree", "NickName", nickname(sf->nickid), nil);
418 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Categories"));
423 18824b58 2008-08-03 rsc static Json*
424 18824b58 2008-08-03 rsc getcategory(SmugFid *sf, vlong id)
427 18824b58 2008-08-03 rsc Json *v, *w;
429 18824b58 2008-08-03 rsc v = getcategorytree(sf);
430 18824b58 2008-08-03 rsc if(v == nil)
432 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
433 18824b58 2008-08-03 rsc if(jint(jwalk(v->value[i], "id")) == id){
434 18824b58 2008-08-03 rsc w = jincref(v->value[i]);
443 18824b58 2008-08-03 rsc static vlong
444 18824b58 2008-08-03 rsc getcategoryid(SmugFid *sf, char *name)
450 18824b58 2008-08-03 rsc v = getcategories(sf);
451 18824b58 2008-08-03 rsc if(v == nil)
453 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
454 18824b58 2008-08-03 rsc if(jstrcmp(jwalk(v->value[i], "Name"), name) == 0){
455 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
468 18824b58 2008-08-03 rsc static vlong
469 18824b58 2008-08-03 rsc getcategoryindex(SmugFid *sf, int i)
474 18824b58 2008-08-03 rsc v = getcategories(sf);
475 18824b58 2008-08-03 rsc if(v == nil)
477 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
481 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
486 18824b58 2008-08-03 rsc static Json*
487 18824b58 2008-08-03 rsc getalbum(SmugFid *sf, vlong albumid, char *albumkey)
489 18824b58 2008-08-03 rsc char id[50];
490 18824b58 2008-08-03 rsc Json *v, *w;
492 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", albumid);
493 18824b58 2008-08-03 rsc v = smug("smugmug.albums.getInfo",
494 18824b58 2008-08-03 rsc "AlbumID", id, "AlbumKey", albumkey,
495 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
496 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Album"));
501 18824b58 2008-08-03 rsc static Json*
502 18824b58 2008-08-03 rsc getalbums(SmugFid *sf)
504 18824b58 2008-08-03 rsc Json *v, *w;
506 18824b58 2008-08-03 rsc if(sf->category >= 0)
507 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
509 18824b58 2008-08-03 rsc v = smug("smugmug.albums.get",
510 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
511 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Albums"));
516 18824b58 2008-08-03 rsc static vlong
517 18824b58 2008-08-03 rsc getalbumid(SmugFid *sf, char *name, char **keyp)
524 18824b58 2008-08-03 rsc v = getalbums(sf);
525 18824b58 2008-08-03 rsc if(v == nil)
527 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
528 18824b58 2008-08-03 rsc if(jstrcmp(jwalk(v->value[i], "Title"), name) == 0){
529 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
530 18824b58 2008-08-03 rsc key = jstring(jwalk(v->value[i], "Key"));
531 18824b58 2008-08-03 rsc if(id < 0 || key == nil){
536 18824b58 2008-08-03 rsc *keyp = estrdup(key);
545 18824b58 2008-08-03 rsc static vlong
546 18824b58 2008-08-03 rsc getalbumindex(SmugFid *sf, int i, char **keyp)
552 18824b58 2008-08-03 rsc v = getalbums(sf);
553 18824b58 2008-08-03 rsc if(v == nil)
555 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
559 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
560 18824b58 2008-08-03 rsc key = jstring(jwalk(v->value[i], "Key"));
561 18824b58 2008-08-03 rsc if(id < 0 || key == nil){
566 18824b58 2008-08-03 rsc *keyp = estrdup(key);
571 18824b58 2008-08-03 rsc static Json*
572 18824b58 2008-08-03 rsc getimages(SmugFid *sf, vlong albumid, char *albumkey)
574 18824b58 2008-08-03 rsc char id[50];
575 18824b58 2008-08-03 rsc Json *v, *w;
577 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", albumid);
578 18824b58 2008-08-03 rsc v = smug("smugmug.images.get",
579 18824b58 2008-08-03 rsc "AlbumID", id, "AlbumKey", albumkey,
580 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
581 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Images"));
586 18824b58 2008-08-03 rsc static vlong
587 18824b58 2008-08-03 rsc getimageid(SmugFid *sf, char *name, char **keyp)
595 18824b58 2008-08-03 rsc id = strtol(name, &p, 10);
596 18824b58 2008-08-03 rsc if(*p != 0 || *name == 0)
599 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
600 18824b58 2008-08-03 rsc if(v == nil)
602 18824b58 2008-08-03 rsc for(i=0; i<v->len; i++){
603 18824b58 2008-08-03 rsc if(jint(jwalk(v->value[i], "id")) == id){
604 18824b58 2008-08-03 rsc key = jstring(jwalk(v->value[i], "Key"));
605 18824b58 2008-08-03 rsc if(key == nil){
610 18824b58 2008-08-03 rsc *keyp = estrdup(key);
619 18824b58 2008-08-03 rsc static Json*
620 18824b58 2008-08-03 rsc getimageinfo(SmugFid *sf, vlong imageid, char *imagekey)
622 18824b58 2008-08-03 rsc char id[50];
623 18824b58 2008-08-03 rsc Json *v, *w;
625 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", imageid);
626 18824b58 2008-08-03 rsc v = smug("smugmug.images.getInfo",
627 18824b58 2008-08-03 rsc "ImageID", id, "ImageKey", imagekey,
628 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
629 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Image"));
634 18824b58 2008-08-03 rsc static Json*
635 18824b58 2008-08-03 rsc getimageexif(SmugFid *sf, vlong imageid, char *imagekey)
637 18824b58 2008-08-03 rsc char id[50];
638 18824b58 2008-08-03 rsc Json *v, *w;
640 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", imageid);
641 18824b58 2008-08-03 rsc v = smug("smugmug.images.getEXIF",
642 18824b58 2008-08-03 rsc "ImageID", id, "ImageKey", imagekey,
643 18824b58 2008-08-03 rsc "NickName", nickname(sf->nickid), nil);
644 18824b58 2008-08-03 rsc w = jincref(jwalk(v, "Image"));
649 18824b58 2008-08-03 rsc static vlong
650 18824b58 2008-08-03 rsc getimageindex(SmugFid *sf, int i, char **keyp)
656 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
657 18824b58 2008-08-03 rsc if(v == nil)
659 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
663 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
664 18824b58 2008-08-03 rsc key = jstring(jwalk(v->value[i], "Key"));
665 18824b58 2008-08-03 rsc if(id < 0 || key == nil){
670 18824b58 2008-08-03 rsc *keyp = estrdup(key);
675 18824b58 2008-08-03 rsc static char*
676 18824b58 2008-08-03 rsc categoryname(SmugFid *sf)
681 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
682 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "Name"));
684 18824b58 2008-08-03 rsc s = estrdup(s);
689 18824b58 2008-08-03 rsc static char*
690 18824b58 2008-08-03 rsc albumname(SmugFid *sf)
695 18824b58 2008-08-03 rsc v = getalbum(sf, sf->album, sf->albumkey);
696 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "Title"));
698 18824b58 2008-08-03 rsc s = estrdup(s);
703 18824b58 2008-08-03 rsc static char*
704 18824b58 2008-08-03 rsc imagename(SmugFid *sf)
709 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
710 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "FileName"));
711 18824b58 2008-08-03 rsc if(s && s[0])
712 18824b58 2008-08-03 rsc s = estrdup(s);
714 18824b58 2008-08-03 rsc s = smprint("%lld.jpg", sf->image); // TODO: use Format
719 18824b58 2008-08-03 rsc static vlong
720 18824b58 2008-08-03 rsc imagelength(SmugFid *sf)
722 18824b58 2008-08-03 rsc vlong length;
725 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
726 18824b58 2008-08-03 rsc length = jint(jwalk(v, "Size"));
728 18824b58 2008-08-03 rsc return length;
731 18824b58 2008-08-03 rsc static struct {
734 18824b58 2008-08-03 rsc } urls[] = {
735 18824b58 2008-08-03 rsc "AlbumURL", "album",
736 18824b58 2008-08-03 rsc "TinyURL", "tiny",
737 18824b58 2008-08-03 rsc "ThumbURL", "thumb",
738 18824b58 2008-08-03 rsc "SmallURL", "small",
739 18824b58 2008-08-03 rsc "MediumURL", "medium",
740 18824b58 2008-08-03 rsc "LargeURL", "large",
741 18824b58 2008-08-03 rsc "XLargeURL", "xlarge",
742 18824b58 2008-08-03 rsc "X2LargeURL", "xxlarge",
743 18824b58 2008-08-03 rsc "X3LargeURL", "xxxlarge",
744 18824b58 2008-08-03 rsc "OriginalURL", "original",
747 18824b58 2008-08-03 rsc static char*
748 18824b58 2008-08-03 rsc imageurl(SmugFid *sf)
754 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
755 18824b58 2008-08-03 rsc for(i=nelem(urls)-1; i>=0; i--){
756 18824b58 2008-08-03 rsc if((s = jstring(jwalk(v, urls[i].key))) != nil){
757 18824b58 2008-08-03 rsc s = estrdup(s);
766 fa325e9b 2020-01-10 cross static char* imagestrings[] =
769 18824b58 2008-08-03 rsc "LastUpdated",
772 18824b58 2008-08-03 rsc "Watermark",
780 18824b58 2008-08-03 rsc "MediumURL",
782 18824b58 2008-08-03 rsc "XLargeURL",
783 18824b58 2008-08-03 rsc "X2LargeURL",
784 18824b58 2008-08-03 rsc "X3LargeURL",
785 18824b58 2008-08-03 rsc "OriginalURL",
789 fa325e9b 2020-01-10 cross static char* albumbools[] =
792 18824b58 2008-08-03 rsc "Printable",
793 18824b58 2008-08-03 rsc "Filenames",
796 18824b58 2008-08-03 rsc "Originals",
799 18824b58 2008-08-03 rsc "SortDirection",
800 18824b58 2008-08-03 rsc "FamilyEdit",
801 18824b58 2008-08-03 rsc "FriendEdit",
802 18824b58 2008-08-03 rsc "HideOwner",
805 18824b58 2008-08-03 rsc "Geography",
806 18824b58 2008-08-03 rsc "SmugSearchable",
807 18824b58 2008-08-03 rsc "WorldSearchable",
808 18824b58 2008-08-03 rsc "SquareThumbs",
813 fa325e9b 2020-01-10 cross static char* albumstrings[] =
815 18824b58 2008-08-03 rsc "Description"
818 18824b58 2008-08-03 rsc "PasswordHint",
819 18824b58 2008-08-03 rsc "SortMethod",
820 18824b58 2008-08-03 rsc "LastUpdated",
823 18824b58 2008-08-03 rsc static char*
824 18824b58 2008-08-03 rsc readctl(SmugFid *sf)
829 18824b58 2008-08-03 rsc Json *v, *vv;
833 18824b58 2008-08-03 rsc switch(sf->type){
835 18824b58 2008-08-03 rsc return smprint("%#J\n", userinfo);
837 18824b58 2008-08-03 rsc case Quploads:
838 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
839 18824b58 2008-08-03 rsc qlock(&uploadlock);
840 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
842 18824b58 2008-08-03 rsc lock(&u->lk);
843 18824b58 2008-08-03 rsc if(u->ready && !u->uploaded && u->ref > 0)
844 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s %s%s\n", u->name, u->file, u->uploading ? " [uploading]" : "");
845 18824b58 2008-08-03 rsc unlock(&u->lk);
847 18824b58 2008-08-03 rsc qunlock(&uploadlock);
848 18824b58 2008-08-03 rsc return fmtstrflush(&fmt);
850 18824b58 2008-08-03 rsc case Qnickctl:
851 18824b58 2008-08-03 rsc v = getcategories(sf);
854 18824b58 2008-08-03 rsc case Qcategoryctl:
855 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
858 18824b58 2008-08-03 rsc case Qalbumctl:
859 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
862 18824b58 2008-08-03 rsc case Qalbumsctl:
863 18824b58 2008-08-03 rsc v = getalbums(sf);
866 18824b58 2008-08-03 rsc case Qimagectl:
867 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
870 18824b58 2008-08-03 rsc case Qimageurl:
871 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
872 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
873 18824b58 2008-08-03 rsc for(i=0; i<nelem(urls); i++)
874 18824b58 2008-08-03 rsc if((s = jstring(jwalk(v, urls[i].key))) != nil)
875 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s %s\n", urls[i].name, s);
877 18824b58 2008-08-03 rsc return fmtstrflush(&fmt);
879 18824b58 2008-08-03 rsc case Qimageexif:
880 18824b58 2008-08-03 rsc v = getimageexif(sf, sf->image, sf->imagekey);
883 18824b58 2008-08-03 rsc case Qalbumsettings:
884 18824b58 2008-08-03 rsc v = getalbum(sf, sf->album, sf->albumkey);
885 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
886 18824b58 2008-08-03 rsc fmtprint(&fmt, "id\t%lld\n", jint(jwalk(v, "id")));
887 18824b58 2008-08-03 rsc // TODO: Category/id
888 18824b58 2008-08-03 rsc // TODO: SubCategory/id
889 18824b58 2008-08-03 rsc // TODO: Community/id
890 18824b58 2008-08-03 rsc // TODO: Template/id
891 18824b58 2008-08-03 rsc fmtprint(&fmt, "Highlight\t%lld\n", jint(jwalk(v, "Highlight/id")));
892 18824b58 2008-08-03 rsc fmtprint(&fmt, "Position\t%lld\n", jint(jwalk(v, "Position")));
893 18824b58 2008-08-03 rsc fmtprint(&fmt, "ImageCount\t%lld\n", jint(jwalk(v, "ImageCount")));
894 18824b58 2008-08-03 rsc for(i=0; i<nelem(albumbools); i++){
895 18824b58 2008-08-03 rsc vv = jwalk(v, albumbools[i]);
897 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%J\n", albumbools[i], vv);
899 18824b58 2008-08-03 rsc for(i=0; i<nelem(albumstrings); i++){
900 18824b58 2008-08-03 rsc s = jstring(jwalk(v, albumstrings[i]));
902 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%s\n", albumstrings[i], s);
904 18824b58 2008-08-03 rsc s = fmtstrflush(&fmt);
908 18824b58 2008-08-03 rsc case Qimagesettings:
909 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
910 18824b58 2008-08-03 rsc fmtstrinit(&fmt);
911 18824b58 2008-08-03 rsc fmtprint(&fmt, "id\t%lld\n", jint(jwalk(v, "id")));
912 18824b58 2008-08-03 rsc fmtprint(&fmt, "Position\t%lld\n", jint(jwalk(v, "Position")));
913 18824b58 2008-08-03 rsc fmtprint(&fmt, "Serial\t%lld\n", jint(jwalk(v, "Serial")));
914 18824b58 2008-08-03 rsc fmtprint(&fmt, "Size\t%lld\t%lldx%lld\n",
915 18824b58 2008-08-03 rsc jint(jwalk(v, "Size")),
916 18824b58 2008-08-03 rsc jint(jwalk(v, "Width")),
917 18824b58 2008-08-03 rsc jint(jwalk(v, "Height")));
918 18824b58 2008-08-03 rsc vv = jwalk(v, "Hidden");
919 18824b58 2008-08-03 rsc fmtprint(&fmt, "Hidden\t%J\n", vv);
920 18824b58 2008-08-03 rsc // TODO: Album/id
921 18824b58 2008-08-03 rsc for(i=0; i<nelem(imagestrings); i++){
922 18824b58 2008-08-03 rsc s = jstring(jwalk(v, imagestrings[i]));
924 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%s\n", imagestrings[i], s);
926 18824b58 2008-08-03 rsc s = fmtstrflush(&fmt);
931 18824b58 2008-08-03 rsc if(v == nil)
932 18824b58 2008-08-03 rsc return estrdup("");
933 18824b58 2008-08-03 rsc s = smprint("%#J\n", v);
940 18824b58 2008-08-03 rsc dostat(SmugFid *sf, Qid *qid, Dir *dir)
944 18824b58 2008-08-03 rsc int freename;
948 18824b58 2008-08-03 rsc vlong length;
950 18824b58 2008-08-03 rsc memset(&q, 0, sizeof q);
952 18824b58 2008-08-03 rsc freename = 0;
953 18824b58 2008-08-03 rsc uid = "smugfs";
956 18824b58 2008-08-03 rsc q.path = QPATH(sf->type, sf->nickid);
958 18824b58 2008-08-03 rsc mode = 0444;
960 18824b58 2008-08-03 rsc switch(sf->type){
963 18824b58 2008-08-03 rsc q.type = QTDIR;
966 18824b58 2008-08-03 rsc name = "ctl";
967 18824b58 2008-08-03 rsc mode |= 0222;
969 18824b58 2008-08-03 rsc case Quploads:
970 18824b58 2008-08-03 rsc name = "uploads";
971 18824b58 2008-08-03 rsc s = readctl(sf);
973 18824b58 2008-08-03 rsc length = strlen(s);
977 18824b58 2008-08-03 rsc case Qrpclog:
978 18824b58 2008-08-03 rsc name = "rpclog";
981 18824b58 2008-08-03 rsc name = nickname(sf->nickid);
982 18824b58 2008-08-03 rsc q.type = QTDIR;
984 18824b58 2008-08-03 rsc case Qnickctl:
985 18824b58 2008-08-03 rsc name = "ctl";
986 18824b58 2008-08-03 rsc mode |= 0222;
988 18824b58 2008-08-03 rsc case Qalbums:
989 18824b58 2008-08-03 rsc name = "albums";
990 18824b58 2008-08-03 rsc q.type = QTDIR;
992 18824b58 2008-08-03 rsc case Qalbumsctl:
993 18824b58 2008-08-03 rsc name = "ctl";
994 18824b58 2008-08-03 rsc mode |= 0222;
996 18824b58 2008-08-03 rsc case Qcategory:
997 18824b58 2008-08-03 rsc name = categoryname(sf);
998 18824b58 2008-08-03 rsc freename = 1;
999 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->category << 8);
1000 18824b58 2008-08-03 rsc q.type = QTDIR;
1002 18824b58 2008-08-03 rsc case Qcategoryctl:
1003 18824b58 2008-08-03 rsc name = "ctl";
1004 18824b58 2008-08-03 rsc mode |= 0222;
1005 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->category << 8);
1007 18824b58 2008-08-03 rsc case Qalbum:
1008 18824b58 2008-08-03 rsc name = albumname(sf);
1009 18824b58 2008-08-03 rsc freename = 1;
1010 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->album << 8);
1011 18824b58 2008-08-03 rsc q.type = QTDIR;
1013 18824b58 2008-08-03 rsc case Qalbumctl:
1014 18824b58 2008-08-03 rsc name = "ctl";
1015 18824b58 2008-08-03 rsc mode |= 0222;
1016 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->album << 8);
1018 18824b58 2008-08-03 rsc case Qalbumsettings:
1019 18824b58 2008-08-03 rsc name = "settings";
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 Quploadfile:
1024 18824b58 2008-08-03 rsc q.path |= QPATH(0, (uintptr)sf->upload << 8);
1025 18824b58 2008-08-03 rsc if(sf->upload){
1027 18824b58 2008-08-03 rsc name = sf->upload->name;
1028 18824b58 2008-08-03 rsc if(sf->upload->fd >= 0){
1029 18824b58 2008-08-03 rsc dd = dirfstat(sf->upload->fd);
1031 18824b58 2008-08-03 rsc length = dd->length;
1035 18824b58 2008-08-03 rsc length = sf->upload->length;
1036 18824b58 2008-08-03 rsc if(!sf->upload->ready)
1037 18824b58 2008-08-03 rsc mode |= 0222;
1040 18824b58 2008-08-03 rsc case Qimage:
1041 18824b58 2008-08-03 rsc name = smprint("%lld", sf->image);
1042 18824b58 2008-08-03 rsc freename = 1;
1043 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1044 18824b58 2008-08-03 rsc q.type = QTDIR;
1046 18824b58 2008-08-03 rsc case Qimagectl:
1047 18824b58 2008-08-03 rsc name = "ctl";
1048 18824b58 2008-08-03 rsc mode |= 0222;
1049 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1051 18824b58 2008-08-03 rsc case Qimagesettings:
1052 18824b58 2008-08-03 rsc name = "settings";
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 Qimageexif:
1057 18824b58 2008-08-03 rsc name = "exif";
1058 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1060 18824b58 2008-08-03 rsc case Qimageurl:
1061 18824b58 2008-08-03 rsc name = "url";
1062 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1064 18824b58 2008-08-03 rsc case Qimagefile:
1065 18824b58 2008-08-03 rsc name = imagename(sf);
1066 18824b58 2008-08-03 rsc freename = 1;
1067 18824b58 2008-08-03 rsc q.path |= QPATH(0, sf->image << 8);
1068 18824b58 2008-08-03 rsc length = imagelength(sf);
1071 18824b58 2008-08-03 rsc name = "?egreg";
1072 18824b58 2008-08-03 rsc q.path = 0;
1076 18824b58 2008-08-03 rsc if(name == nil){
1077 18824b58 2008-08-03 rsc name = "???";
1078 18824b58 2008-08-03 rsc freename = 0;
1084 18824b58 2008-08-03 rsc memset(dir, 0, sizeof *dir);
1085 18824b58 2008-08-03 rsc dir->name = estrdup9p(name);
1086 18824b58 2008-08-03 rsc dir->muid = estrdup9p("muid");
1087 18824b58 2008-08-03 rsc mode |= q.type<<24;
1088 18824b58 2008-08-03 rsc if(mode & DMDIR)
1089 00d2ebe9 2009-04-30 rsc mode |= 0755;
1090 18824b58 2008-08-03 rsc dir->mode = mode;
1091 18824b58 2008-08-03 rsc dir->uid = estrdup9p(uid);
1092 18824b58 2008-08-03 rsc dir->gid = estrdup9p("smugfs");
1093 18824b58 2008-08-03 rsc dir->qid = q;
1094 18824b58 2008-08-03 rsc dir->length = length;
1096 18824b58 2008-08-03 rsc if(freename)
1097 18824b58 2008-08-03 rsc free(name);
1100 18824b58 2008-08-03 rsc static char*
1101 18824b58 2008-08-03 rsc xwalk1(Fid *fid, char *name, Qid *qid)
1103 18824b58 2008-08-03 rsc int dotdot, i;
1106 18824b58 2008-08-03 rsc SmugFid *sf;
1110 18824b58 2008-08-03 rsc dotdot = strcmp(name, "..") == 0;
1111 18824b58 2008-08-03 rsc sf = fid->aux;
1112 18824b58 2008-08-03 rsc switch(sf->type){
1115 18824b58 2008-08-03 rsc return "file not found";
1117 18824b58 2008-08-03 rsc case Qroot:
1120 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1121 18824b58 2008-08-03 rsc sf->type = Qctl;
1124 18824b58 2008-08-03 rsc if(strcmp(name, "uploads") == 0){
1125 18824b58 2008-08-03 rsc sf->type = Quploads;
1128 18824b58 2008-08-03 rsc if(strcmp(name, "rpclog") == 0){
1129 18824b58 2008-08-03 rsc sf->type = Qrpclog;
1132 18824b58 2008-08-03 rsc if((i = nickindex(name)) >= 0){
1133 18824b58 2008-08-03 rsc sf->nickid = i;
1134 18824b58 2008-08-03 rsc sf->type = Qnick;
1137 18824b58 2008-08-03 rsc goto NotFound;
1139 18824b58 2008-08-03 rsc case Qnick:
1140 18824b58 2008-08-03 rsc if(dotdot){
1141 18824b58 2008-08-03 rsc sf->type = Qroot;
1142 18824b58 2008-08-03 rsc sf->nickid = 0;
1145 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1146 18824b58 2008-08-03 rsc sf->type = Qnickctl;
1149 18824b58 2008-08-03 rsc if(strcmp(name, "albums") == 0){
1150 18824b58 2008-08-03 rsc sf->category = -1;
1151 18824b58 2008-08-03 rsc sf->type = Qalbums;
1154 18824b58 2008-08-03 rsc if((id = getcategoryid(sf, name)) >= 0){
1155 18824b58 2008-08-03 rsc sf->category = id;
1156 18824b58 2008-08-03 rsc sf->type = Qcategory;
1159 18824b58 2008-08-03 rsc goto NotFound;
1161 18824b58 2008-08-03 rsc case Qalbums:
1162 18824b58 2008-08-03 rsc case Qcategory:
1163 18824b58 2008-08-03 rsc if(dotdot){
1164 18824b58 2008-08-03 rsc sf->category = 0;
1165 18824b58 2008-08-03 rsc sf->type = Qnick;
1168 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1169 18824b58 2008-08-03 rsc sf->type++;
1172 18824b58 2008-08-03 rsc if((id = getalbumid(sf, name, &key)) >= 0){
1173 18824b58 2008-08-03 rsc sf->album = id;
1174 18824b58 2008-08-03 rsc sf->albumkey = key;
1175 18824b58 2008-08-03 rsc sf->type = Qalbum;
1178 18824b58 2008-08-03 rsc goto NotFound;
1180 18824b58 2008-08-03 rsc case Qalbum:
1181 18824b58 2008-08-03 rsc if(dotdot){
1182 18824b58 2008-08-03 rsc free(sf->albumkey);
1183 18824b58 2008-08-03 rsc sf->albumkey = nil;
1184 18824b58 2008-08-03 rsc sf->album = 0;
1185 18824b58 2008-08-03 rsc if(sf->category == -1)
1186 18824b58 2008-08-03 rsc sf->type = Qalbums;
1188 18824b58 2008-08-03 rsc sf->type = Qcategory;
1191 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1192 18824b58 2008-08-03 rsc sf->type = Qalbumctl;
1195 18824b58 2008-08-03 rsc if(strcmp(name, "settings") == 0){
1196 18824b58 2008-08-03 rsc sf->type = Qalbumsettings;
1199 18824b58 2008-08-03 rsc if((id = getimageid(sf, name, &key)) >= 0){
1200 18824b58 2008-08-03 rsc sf->image = id;
1201 18824b58 2008-08-03 rsc sf->imagekey = key;
1202 18824b58 2008-08-03 rsc sf->type = Qimage;
1205 18824b58 2008-08-03 rsc if((u = getuploadname(sf, name)) != nil){
1206 18824b58 2008-08-03 rsc sf->upload = u;
1207 18824b58 2008-08-03 rsc sf->type = Quploadfile;
1210 18824b58 2008-08-03 rsc goto NotFound;
1212 18824b58 2008-08-03 rsc case Qimage:
1213 18824b58 2008-08-03 rsc if(dotdot){
1214 18824b58 2008-08-03 rsc free(sf->imagekey);
1215 18824b58 2008-08-03 rsc sf->imagekey = nil;
1216 18824b58 2008-08-03 rsc sf->image = 0;
1217 18824b58 2008-08-03 rsc sf->type = Qalbum;
1220 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1221 18824b58 2008-08-03 rsc sf->type = Qimagectl;
1224 18824b58 2008-08-03 rsc if(strcmp(name, "url") == 0){
1225 18824b58 2008-08-03 rsc sf->type = Qimageurl;
1228 18824b58 2008-08-03 rsc if(strcmp(name, "settings") == 0){
1229 18824b58 2008-08-03 rsc sf->type = Qimagesettings;
1232 18824b58 2008-08-03 rsc if(strcmp(name, "exif") == 0){
1233 18824b58 2008-08-03 rsc sf->type = Qimageexif;
1236 18824b58 2008-08-03 rsc x = imagename(sf);
1237 18824b58 2008-08-03 rsc if(x && strcmp(name, x) == 0){
1239 18824b58 2008-08-03 rsc sf->type = Qimagefile;
1243 18824b58 2008-08-03 rsc goto NotFound;
1245 18824b58 2008-08-03 rsc dostat(sf, qid, nil);
1246 18824b58 2008-08-03 rsc fid->qid = *qid;
1247 18824b58 2008-08-03 rsc return nil;
1251 18824b58 2008-08-03 rsc dodirgen(int i, Dir *d, void *v)
1253 18824b58 2008-08-03 rsc SmugFid *sf, xsf;
1260 18824b58 2008-08-03 rsc if(i-- == 0){
1261 18824b58 2008-08-03 rsc xsf.type++; // ctl in every directory
1262 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1266 18824b58 2008-08-03 rsc switch(sf->type){
1270 18824b58 2008-08-03 rsc case Qroot:
1271 18824b58 2008-08-03 rsc if(i-- == 0){
1272 18824b58 2008-08-03 rsc xsf.type = Qrpclog;
1273 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1276 18824b58 2008-08-03 rsc if(i < 0 || i >= nnick)
1278 18824b58 2008-08-03 rsc xsf.type = Qnick;
1279 18824b58 2008-08-03 rsc xsf.nickid = i;
1280 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1283 18824b58 2008-08-03 rsc case Qnick:
1284 18824b58 2008-08-03 rsc if(i-- == 0){
1285 18824b58 2008-08-03 rsc xsf.type = Qalbums;
1286 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1289 18824b58 2008-08-03 rsc if((id = getcategoryindex(sf, i)) < 0)
1291 18824b58 2008-08-03 rsc xsf.type = Qcategory;
1292 18824b58 2008-08-03 rsc xsf.category = id;
1293 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1296 18824b58 2008-08-03 rsc case Qalbums:
1297 18824b58 2008-08-03 rsc case Qcategory:
1298 18824b58 2008-08-03 rsc if((id = getalbumindex(sf, i, &key)) < 0)
1300 18824b58 2008-08-03 rsc xsf.type = Qalbum;
1301 18824b58 2008-08-03 rsc xsf.album = id;
1302 18824b58 2008-08-03 rsc xsf.albumkey = key;
1303 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1307 18824b58 2008-08-03 rsc case Qalbum:
1308 18824b58 2008-08-03 rsc if(i-- == 0){
1309 18824b58 2008-08-03 rsc xsf.type = Qalbumsettings;
1310 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1313 18824b58 2008-08-03 rsc if((u = getuploadindex(sf, &i)) != nil){
1314 18824b58 2008-08-03 rsc xsf.upload = u;
1315 18824b58 2008-08-03 rsc xsf.type = Quploadfile;
1316 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1317 18824b58 2008-08-03 rsc closeupload(u);
1320 18824b58 2008-08-03 rsc if((id = getimageindex(sf, i, &key)) < 0)
1322 18824b58 2008-08-03 rsc xsf.type = Qimage;
1323 18824b58 2008-08-03 rsc xsf.image = id;
1324 18824b58 2008-08-03 rsc xsf.imagekey = key;
1325 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1329 18824b58 2008-08-03 rsc case Qimage:
1330 18824b58 2008-08-03 rsc if(i-- == 0){
1331 18824b58 2008-08-03 rsc xsf.type = Qimagefile;
1332 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1335 18824b58 2008-08-03 rsc if(i-- == 0){
1336 18824b58 2008-08-03 rsc xsf.type = Qimageexif;
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 = Qimagesettings;
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 = Qimageurl;
1347 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1354 18824b58 2008-08-03 rsc static void
1355 18824b58 2008-08-03 rsc xstat(Req *r)
1357 18824b58 2008-08-03 rsc dostat(r->fid->aux, nil, &r->d);
1358 18824b58 2008-08-03 rsc respond(r, nil);
1361 18824b58 2008-08-03 rsc static void
1362 18824b58 2008-08-03 rsc xwstat(Req *r)
1364 18824b58 2008-08-03 rsc SmugFid *sf;
1367 18824b58 2008-08-03 rsc char strid[50];
1369 18824b58 2008-08-03 rsc sf = r->fid->aux;
1370 18824b58 2008-08-03 rsc if(r->d.uid[0] || r->d.gid[0] || r->d.muid[0] || ~r->d.mode != 0
1371 18824b58 2008-08-03 rsc || ~r->d.atime != 0 || ~r->d.mtime != 0 || ~r->d.length != 0){
1372 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1375 18824b58 2008-08-03 rsc if(r->d.name[0]){
1376 18824b58 2008-08-03 rsc switch(sf->type){
1378 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1380 18824b58 2008-08-03 rsc // TODO: rename category
1381 18824b58 2008-08-03 rsc case Qalbum:
1382 18824b58 2008-08-03 rsc snprint(strid, sizeof strid, "%lld", sf->album);
1383 18824b58 2008-08-03 rsc v = ncsmug("smugmug.albums.changeSettings",
1384 18824b58 2008-08-03 rsc "AlbumID", strid, "Title", r->d.name, nil);
1385 18824b58 2008-08-03 rsc if(v == nil)
1386 18824b58 2008-08-03 rsc responderrstr(r);
1388 18824b58 2008-08-03 rsc respond(r, nil);
1389 18824b58 2008-08-03 rsc s = smprint("&AlbumID=%lld&", sf->album);
1390 18824b58 2008-08-03 rsc jcacheflush(s);
1392 18824b58 2008-08-03 rsc jcacheflush("smugmug.albums.get&");
1396 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1399 18824b58 2008-08-03 rsc static void
1400 18824b58 2008-08-03 rsc xattach(Req *r)
1402 18824b58 2008-08-03 rsc SmugFid *sf;
1404 18824b58 2008-08-03 rsc sf = emalloc(sizeof *sf);
1405 18824b58 2008-08-03 rsc r->fid->aux = sf;
1406 18824b58 2008-08-03 rsc sf->type = Qroot;
1407 18824b58 2008-08-03 rsc dostat(sf, &r->ofcall.qid, nil);
1408 18824b58 2008-08-03 rsc r->fid->qid = r->ofcall.qid;
1409 18824b58 2008-08-03 rsc respond(r, nil);
1413 18824b58 2008-08-03 rsc xopen(Req *r)
1415 18824b58 2008-08-03 rsc SmugFid *sf;
1417 18824b58 2008-08-03 rsc if((r->ifcall.mode&~OTRUNC) > 2){
1418 18824b58 2008-08-03 rsc respond(r, "permission denied");
1422 18824b58 2008-08-03 rsc sf = r->fid->aux;
1423 18824b58 2008-08-03 rsc switch(sf->type){
1425 18824b58 2008-08-03 rsc case Qnickctl:
1426 18824b58 2008-08-03 rsc case Qalbumsctl:
1427 18824b58 2008-08-03 rsc case Qcategoryctl:
1428 18824b58 2008-08-03 rsc case Qalbumctl:
1429 18824b58 2008-08-03 rsc case Qimagectl:
1430 18824b58 2008-08-03 rsc case Qalbumsettings:
1431 18824b58 2008-08-03 rsc case Qimagesettings:
1434 18824b58 2008-08-03 rsc case Quploadfile:
1435 18824b58 2008-08-03 rsc if(r->ifcall.mode != OREAD){
1436 18824b58 2008-08-03 rsc lock(&sf->upload->lk);
1437 18824b58 2008-08-03 rsc if(sf->upload->ready){
1438 18824b58 2008-08-03 rsc unlock(&sf->upload->lk);
1439 18824b58 2008-08-03 rsc respond(r, "permission denied");
1442 18824b58 2008-08-03 rsc sf->upwriter = 1;
1443 18824b58 2008-08-03 rsc sf->upload->nwriters++;
1444 18824b58 2008-08-03 rsc unlock(&sf->upload->lk);
1449 18824b58 2008-08-03 rsc if(r->ifcall.mode != OREAD){
1450 18824b58 2008-08-03 rsc respond(r, "permission denied");
1456 18824b58 2008-08-03 rsc r->ofcall.qid = r->fid->qid;
1457 18824b58 2008-08-03 rsc respond(r, nil);
1461 18824b58 2008-08-03 rsc xcreate(Req *r)
1463 18824b58 2008-08-03 rsc SmugFid *sf;
1466 18824b58 2008-08-03 rsc char strid[50], *key;
1469 18824b58 2008-08-03 rsc sf = r->fid->aux;
1470 18824b58 2008-08-03 rsc switch(sf->type){
1471 18824b58 2008-08-03 rsc case Qnick:
1472 18824b58 2008-08-03 rsc // Create new category.
1473 18824b58 2008-08-03 rsc if(!(r->ifcall.perm&DMDIR))
1475 18824b58 2008-08-03 rsc v = ncsmug("smugmug.categories.create",
1476 18824b58 2008-08-03 rsc "Name", r->ifcall.name, nil);
1477 18824b58 2008-08-03 rsc if(v == nil){
1478 18824b58 2008-08-03 rsc responderrstr(r);
1481 18824b58 2008-08-03 rsc id = jint(jwalk(v, "Category/id"));
1482 18824b58 2008-08-03 rsc if(id < 0){
1483 18824b58 2008-08-03 rsc fprint(2, "Create category: %J\n", v);
1485 18824b58 2008-08-03 rsc responderrstr(r);
1488 18824b58 2008-08-03 rsc sf->type = Qcategory;
1489 18824b58 2008-08-03 rsc sf->category = id;
1490 18824b58 2008-08-03 rsc jcacheflush("method=smugmug.users.getTree&");
1491 18824b58 2008-08-03 rsc jcacheflush("method=smugmug.categories.get&");
1492 18824b58 2008-08-03 rsc dostat(sf, &r->ofcall.qid, nil);
1493 18824b58 2008-08-03 rsc respond(r, nil);
1496 18824b58 2008-08-03 rsc case Qcategory:
1497 18824b58 2008-08-03 rsc // Create new album.
1498 18824b58 2008-08-03 rsc if(!(r->ifcall.perm&DMDIR))
1500 18824b58 2008-08-03 rsc snprint(strid, sizeof strid, "%lld", sf->category);
1501 18824b58 2008-08-03 rsc // Start with most restrictive settings.
1502 18824b58 2008-08-03 rsc v = ncsmug("smugmug.albums.create",
1503 fa325e9b 2020-01-10 cross "Title", r->ifcall.name,
1504 18824b58 2008-08-03 rsc "CategoryID", strid,
1505 18824b58 2008-08-03 rsc "Public", "0",
1506 18824b58 2008-08-03 rsc "WorldSearchable", "0",
1507 18824b58 2008-08-03 rsc "SmugSearchable", "0",
1509 18824b58 2008-08-03 rsc if(v == nil){
1510 18824b58 2008-08-03 rsc responderrstr(r);
1513 18824b58 2008-08-03 rsc id = jint(jwalk(v, "Album/id"));
1514 18824b58 2008-08-03 rsc key = jstring(jwalk(v, "Album/Key"));
1515 18824b58 2008-08-03 rsc if(id < 0 || key == nil){
1516 18824b58 2008-08-03 rsc fprint(2, "Create album: %J\n", v);
1518 18824b58 2008-08-03 rsc responderrstr(r);
1521 18824b58 2008-08-03 rsc sf->type = Qalbum;
1522 18824b58 2008-08-03 rsc sf->album = id;
1523 18824b58 2008-08-03 rsc sf->albumkey = estrdup(key);
1525 18824b58 2008-08-03 rsc jcacheflush("method=smugmug.users.getTree&");
1526 18824b58 2008-08-03 rsc dostat(sf, &r->ofcall.qid, nil);
1527 18824b58 2008-08-03 rsc respond(r, nil);
1530 18824b58 2008-08-03 rsc case Qalbum:
1531 18824b58 2008-08-03 rsc // Upload image to album.
1532 18824b58 2008-08-03 rsc if(r->ifcall.perm&DMDIR)
1534 18824b58 2008-08-03 rsc u = newupload(sf, r->ifcall.name);
1535 18824b58 2008-08-03 rsc if(u == nil){
1536 18824b58 2008-08-03 rsc responderrstr(r);
1539 18824b58 2008-08-03 rsc sf->upload = u;
1540 18824b58 2008-08-03 rsc sf->upwriter = 1;
1541 18824b58 2008-08-03 rsc sf->type = Quploadfile;
1542 18824b58 2008-08-03 rsc dostat(sf, &r->ofcall.qid, nil);
1543 18824b58 2008-08-03 rsc respond(r, nil);
1546 fa325e9b 2020-01-10 cross respond(r, "permission denied");
1550 18824b58 2008-08-03 rsc writetofd(Req *r, int fd)
1552 18824b58 2008-08-03 rsc int total, n;
1555 18824b58 2008-08-03 rsc while(total < r->ifcall.count){
1556 18824b58 2008-08-03 rsc n = pwrite(fd, (char*)r->ifcall.data+total, r->ifcall.count-total, r->ifcall.offset+total);
1559 18824b58 2008-08-03 rsc total += n;
1561 18824b58 2008-08-03 rsc r->ofcall.count = r->ifcall.count;
1565 18824b58 2008-08-03 rsc static void
1566 18824b58 2008-08-03 rsc readfromfd(Req *r, int fd)
1569 18824b58 2008-08-03 rsc n = pread(fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
1572 18824b58 2008-08-03 rsc r->ofcall.count = n;
1576 18824b58 2008-08-03 rsc xread(Req *r)
1578 18824b58 2008-08-03 rsc SmugFid *sf;
1579 18824b58 2008-08-03 rsc char *data;
1581 18824b58 2008-08-03 rsc HTTPHeader hdr;
1584 18824b58 2008-08-03 rsc sf = r->fid->aux;
1585 18824b58 2008-08-03 rsc r->ofcall.count = 0;
1586 18824b58 2008-08-03 rsc switch(sf->type){
1588 18824b58 2008-08-03 rsc respond(r, "not implemented");
1590 18824b58 2008-08-03 rsc case Qroot:
1591 18824b58 2008-08-03 rsc case Qnick:
1592 18824b58 2008-08-03 rsc case Qalbums:
1593 18824b58 2008-08-03 rsc case Qcategory:
1594 18824b58 2008-08-03 rsc case Qalbum:
1595 18824b58 2008-08-03 rsc case Qimage:
1596 18824b58 2008-08-03 rsc dirread9p(r, dodirgen, sf);
1598 18824b58 2008-08-03 rsc case Qrpclog:
1599 18824b58 2008-08-03 rsc rpclogread(r);
1602 18824b58 2008-08-03 rsc case Qnickctl:
1603 18824b58 2008-08-03 rsc case Qalbumsctl:
1604 18824b58 2008-08-03 rsc case Qcategoryctl:
1605 18824b58 2008-08-03 rsc case Qalbumctl:
1606 18824b58 2008-08-03 rsc case Qimagectl:
1607 18824b58 2008-08-03 rsc case Qimageurl:
1608 18824b58 2008-08-03 rsc case Qimageexif:
1609 18824b58 2008-08-03 rsc case Quploads:
1610 18824b58 2008-08-03 rsc case Qimagesettings:
1611 18824b58 2008-08-03 rsc case Qalbumsettings:
1612 18824b58 2008-08-03 rsc data = readctl(sf);
1613 18824b58 2008-08-03 rsc readstr(r, data);
1614 18824b58 2008-08-03 rsc free(data);
1616 18824b58 2008-08-03 rsc case Qimagefile:
1617 18824b58 2008-08-03 rsc url = imageurl(sf);
1618 18824b58 2008-08-03 rsc if(url == nil || (fd = download(url, &hdr)) < 0){
1620 18824b58 2008-08-03 rsc responderrstr(r);
1623 18824b58 2008-08-03 rsc readfromfd(r, fd);
1627 18824b58 2008-08-03 rsc case Quploadfile:
1628 18824b58 2008-08-03 rsc if(sf->upload)
1629 18824b58 2008-08-03 rsc readfromfd(r, sf->upload->fd);
1632 18824b58 2008-08-03 rsc respond(r, nil);
1636 18824b58 2008-08-03 rsc xwrite(Req *r)
1639 18824b58 2008-08-03 rsc char *s, *t, *p;
1641 18824b58 2008-08-03 rsc char strid[50];
1642 18824b58 2008-08-03 rsc SmugFid *sf;
1644 18824b58 2008-08-03 rsc sf = r->fid->aux;
1645 18824b58 2008-08-03 rsc r->ofcall.count = r->ifcall.count;
1646 18824b58 2008-08-03 rsc sync = (r->ifcall.count==4 && memcmp(r->ifcall.data, "sync", 4) == 0);
1647 18824b58 2008-08-03 rsc switch(sf->type){
1650 18824b58 2008-08-03 rsc jcacheflush(nil);
1651 18824b58 2008-08-03 rsc respond(r, nil);
1655 18824b58 2008-08-03 rsc case Qnickctl:
1657 18824b58 2008-08-03 rsc s = smprint("&NickName=%s&", nickname(sf->nickid));
1658 18824b58 2008-08-03 rsc jcacheflush(s);
1660 18824b58 2008-08-03 rsc respond(r, nil);
1664 18824b58 2008-08-03 rsc case Qalbumsctl:
1665 18824b58 2008-08-03 rsc case Qcategoryctl:
1666 18824b58 2008-08-03 rsc jcacheflush("smugmug.categories.get");
1668 18824b58 2008-08-03 rsc case Qalbumctl:
1670 18824b58 2008-08-03 rsc s = smprint("&AlbumID=%lld&", sf->album);
1671 18824b58 2008-08-03 rsc jcacheflush(s);
1673 18824b58 2008-08-03 rsc respond(r, nil);
1677 18824b58 2008-08-03 rsc case Qimagectl:
1679 18824b58 2008-08-03 rsc s = smprint("&ImageID=%lld&", sf->image);
1680 18824b58 2008-08-03 rsc jcacheflush(s);
1682 18824b58 2008-08-03 rsc respond(r, nil);
1686 18824b58 2008-08-03 rsc case Quploadfile:
1687 18824b58 2008-08-03 rsc if(sf->upload){
1688 18824b58 2008-08-03 rsc if(writetofd(r, sf->upload->fd) < 0){
1689 18824b58 2008-08-03 rsc responderrstr(r);
1692 18824b58 2008-08-03 rsc respond(r, nil);
1696 18824b58 2008-08-03 rsc case Qimagesettings:
1697 18824b58 2008-08-03 rsc case Qalbumsettings:
1698 18824b58 2008-08-03 rsc s = (char*)r->ifcall.data; // lib9p nul-terminated it
1699 18824b58 2008-08-03 rsc t = strpbrk(s, " \r\t\n");
1700 18824b58 2008-08-03 rsc if(t == nil)
1704 18824b58 2008-08-03 rsc while(*t == ' ' || *t == '\r' || *t == '\t' || *t == '\n')
1707 18824b58 2008-08-03 rsc p = strchr(t, '\n');
1708 18824b58 2008-08-03 rsc if(p && p[1] == 0)
1710 18824b58 2008-08-03 rsc else if(p){
1711 18824b58 2008-08-03 rsc respond(r, "newline in argument");
1714 18824b58 2008-08-03 rsc if(sf->type == Qalbumsettings)
1715 18824b58 2008-08-03 rsc goto Albumsettings;
1716 18824b58 2008-08-03 rsc snprint(strid, sizeof strid, "%lld", sf->image);
1717 18824b58 2008-08-03 rsc v = ncsmug("smugmug.images.changeSettings",
1718 18824b58 2008-08-03 rsc "ImageID", strid,
1719 18824b58 2008-08-03 rsc s, t, nil);
1720 18824b58 2008-08-03 rsc if(v == nil)
1721 18824b58 2008-08-03 rsc responderrstr(r);
1723 18824b58 2008-08-03 rsc respond(r, nil);
1724 18824b58 2008-08-03 rsc s = smprint("&ImageID=%lld&", sf->image);
1725 18824b58 2008-08-03 rsc jcacheflush(s);
1728 18824b58 2008-08-03 rsc Albumsettings:
1729 18824b58 2008-08-03 rsc snprint(strid, sizeof strid, "%lld", sf->album);
1730 18824b58 2008-08-03 rsc v = ncsmug("smugmug.albums.changeSettings",
1731 18824b58 2008-08-03 rsc "AlbumID", strid, s, t, nil);
1732 18824b58 2008-08-03 rsc if(v == nil)
1733 18824b58 2008-08-03 rsc responderrstr(r);
1735 18824b58 2008-08-03 rsc respond(r, nil);
1736 18824b58 2008-08-03 rsc s = smprint("&AlbumID=%lld&", sf->album);
1737 18824b58 2008-08-03 rsc jcacheflush(s);
1741 18824b58 2008-08-03 rsc respond(r, "invalid control message");
1746 18824b58 2008-08-03 rsc xremove(Req *r)
1748 18824b58 2008-08-03 rsc char id[100];
1749 18824b58 2008-08-03 rsc SmugFid *sf;
1752 18824b58 2008-08-03 rsc sf = r->fid->aux;
1753 18824b58 2008-08-03 rsc switch(sf->type){
1755 18824b58 2008-08-03 rsc respond(r, "permission denied");
1757 18824b58 2008-08-03 rsc case Qcategoryctl:
1758 18824b58 2008-08-03 rsc case Qalbumctl:
1759 18824b58 2008-08-03 rsc case Qalbumsettings:
1760 18824b58 2008-08-03 rsc case Qimagectl:
1761 18824b58 2008-08-03 rsc case Qimagesettings:
1762 18824b58 2008-08-03 rsc case Qimageexif:
1763 18824b58 2008-08-03 rsc case Qimageurl:
1764 18824b58 2008-08-03 rsc case Qimagefile:
1765 18824b58 2008-08-03 rsc /* ignore remove request, but no error, so rm -r works */
1766 18824b58 2008-08-03 rsc /* you can pretend they get removed and immediately grow back! */
1767 18824b58 2008-08-03 rsc respond(r, nil);
1769 18824b58 2008-08-03 rsc case Qcategory:
1770 18824b58 2008-08-03 rsc v = getalbums(sf);
1771 18824b58 2008-08-03 rsc if(v && v->len > 0){
1772 18824b58 2008-08-03 rsc respond(r, "directory not empty");
1775 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", sf->category);
1776 18824b58 2008-08-03 rsc v = ncsmug("smugmug.categories.delete",
1777 18824b58 2008-08-03 rsc "CategoryID", id, nil);
1778 18824b58 2008-08-03 rsc if(v == nil)
1779 18824b58 2008-08-03 rsc responderrstr(r);
1782 18824b58 2008-08-03 rsc jcacheflush("smugmug.users.getTree");
1783 18824b58 2008-08-03 rsc jcacheflush("smugmug.categories.get");
1784 18824b58 2008-08-03 rsc respond(r, nil);
1787 18824b58 2008-08-03 rsc case Qalbum:
1788 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
1789 18824b58 2008-08-03 rsc if(v && v->len > 0){
1790 18824b58 2008-08-03 rsc respond(r, "directory not empty");
1793 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", sf->album);
1794 18824b58 2008-08-03 rsc v = ncsmug("smugmug.albums.delete",
1795 18824b58 2008-08-03 rsc "AlbumID", id, nil);
1796 18824b58 2008-08-03 rsc if(v == nil)
1797 18824b58 2008-08-03 rsc responderrstr(r);
1800 18824b58 2008-08-03 rsc jcacheflush("smugmug.users.getTree");
1801 18824b58 2008-08-03 rsc jcacheflush("smugmug.categories.get");
1802 18824b58 2008-08-03 rsc jcacheflush("smugmug.albums.get");
1803 18824b58 2008-08-03 rsc respond(r, nil);
1807 18824b58 2008-08-03 rsc case Qimage:
1808 18824b58 2008-08-03 rsc snprint(id, sizeof id, "%lld", sf->image);
1809 18824b58 2008-08-03 rsc v = ncsmug("smugmug.images.delete",
1810 18824b58 2008-08-03 rsc "ImageID", id, nil);
1811 18824b58 2008-08-03 rsc if(v == nil)
1812 18824b58 2008-08-03 rsc responderrstr(r);
1815 18824b58 2008-08-03 rsc snprint(id, sizeof id, "ImageID=%lld&", sf->image);
1816 18824b58 2008-08-03 rsc jcacheflush(id);
1817 18824b58 2008-08-03 rsc jcacheflush("smugmug.images.get&");
1818 18824b58 2008-08-03 rsc respond(r, nil);
1825 18824b58 2008-08-03 rsc xflush(Req *r)
1827 18824b58 2008-08-03 rsc rpclogflush(r->oldreq);
1828 18824b58 2008-08-03 rsc respond(r, nil);
1834 18824b58 2008-08-03 rsc xinit(void)
1836 18824b58 2008-08-03 rsc xsrv.attach = xattach;
1837 18824b58 2008-08-03 rsc xsrv.open = xopen;
1838 18824b58 2008-08-03 rsc xsrv.create = xcreate;
1839 18824b58 2008-08-03 rsc xsrv.read = xread;
1840 18824b58 2008-08-03 rsc xsrv.stat = xstat;
1841 18824b58 2008-08-03 rsc xsrv.walk1 = xwalk1;
1842 18824b58 2008-08-03 rsc xsrv.clone = xclone;
1843 18824b58 2008-08-03 rsc xsrv.destroyfid = xdestroyfid;
1844 18824b58 2008-08-03 rsc xsrv.remove = xremove;
1845 18824b58 2008-08-03 rsc xsrv.write = xwrite;
1846 18824b58 2008-08-03 rsc xsrv.flush = xflush;
1847 18824b58 2008-08-03 rsc xsrv.wstat = xwstat;