Blame


1 18824b58 2008-08-03 rsc #include "a.h"
2 18824b58 2008-08-03 rsc
3 18824b58 2008-08-03 rsc enum
4 18824b58 2008-08-03 rsc {
5 18824b58 2008-08-03 rsc Qroot = 0, // /smug/
6 18824b58 2008-08-03 rsc Qctl, // /smug/ctl
7 18824b58 2008-08-03 rsc Qrpclog, // /smug/rpclog
8 18824b58 2008-08-03 rsc Quploads, // /smug/uploads
9 18824b58 2008-08-03 rsc Qnick, // /smug/nick/
10 18824b58 2008-08-03 rsc Qnickctl, // /smug/nick/ctl
11 18824b58 2008-08-03 rsc Qalbums, // /smug/nick/albums/
12 18824b58 2008-08-03 rsc Qalbumsctl, // /smug/nick/albums/ctl
13 18824b58 2008-08-03 rsc Qcategory, // /smug/nick/Category/
14 18824b58 2008-08-03 rsc Qcategoryctl, // /smug/nick/Category/ctl
15 18824b58 2008-08-03 rsc Qalbum, // /smug/nick/Category/Album/
16 18824b58 2008-08-03 rsc Qalbumctl, // /smug/nick/Category/Album/ctl
17 18824b58 2008-08-03 rsc Qalbumsettings, // /smug/nick/Category/Album/settings
18 18824b58 2008-08-03 rsc Quploadfile, // /smug/nick/Category/Album/upload/file.jpg
19 18824b58 2008-08-03 rsc Qimage, // /smug/nick/Category/Album/Image/
20 18824b58 2008-08-03 rsc Qimagectl, // /smug/nick/Category/Album/Image/ctl
21 18824b58 2008-08-03 rsc Qimageexif, // /smug/nick/Category/Album/Image/exif
22 18824b58 2008-08-03 rsc Qimagesettings, // /smug/nick/Category/Album/Image/settings
23 18824b58 2008-08-03 rsc Qimageurl, // /smug/nick/Category/Album/Image/url
24 18824b58 2008-08-03 rsc Qimagefile, // /smug/nick/Category/Album/Image/file.jpg
25 18824b58 2008-08-03 rsc };
26 18824b58 2008-08-03 rsc
27 18824b58 2008-08-03 rsc void
28 18824b58 2008-08-03 rsc mylock(Lock *lk)
29 18824b58 2008-08-03 rsc {
30 18824b58 2008-08-03 rsc lock(lk);
31 18824b58 2008-08-03 rsc fprint(2, "locked from %p\n", getcallerpc(&lk));
32 18824b58 2008-08-03 rsc }
33 18824b58 2008-08-03 rsc
34 18824b58 2008-08-03 rsc void
35 18824b58 2008-08-03 rsc myunlock(Lock *lk)
36 18824b58 2008-08-03 rsc {
37 18824b58 2008-08-03 rsc unlock(lk);
38 18824b58 2008-08-03 rsc fprint(2, "unlocked from %p\n", getcallerpc(&lk));
39 18824b58 2008-08-03 rsc }
40 18824b58 2008-08-03 rsc
41 18824b58 2008-08-03 rsc //#define lock mylock
42 18824b58 2008-08-03 rsc //#define unlock myunlock
43 18824b58 2008-08-03 rsc
44 18824b58 2008-08-03 rsc typedef struct Upload Upload;
45 18824b58 2008-08-03 rsc
46 18824b58 2008-08-03 rsc typedef struct SmugFid SmugFid;
47 18824b58 2008-08-03 rsc struct SmugFid
48 18824b58 2008-08-03 rsc {
49 18824b58 2008-08-03 rsc int type;
50 18824b58 2008-08-03 rsc int nickid;
51 18824b58 2008-08-03 rsc vlong category; // -1 for "albums"
52 18824b58 2008-08-03 rsc vlong album;
53 18824b58 2008-08-03 rsc char *albumkey;
54 18824b58 2008-08-03 rsc vlong image;
55 18824b58 2008-08-03 rsc char *imagekey;
56 18824b58 2008-08-03 rsc Upload *upload;
57 18824b58 2008-08-03 rsc int upwriter;
58 18824b58 2008-08-03 rsc };
59 18824b58 2008-08-03 rsc
60 18824b58 2008-08-03 rsc #define QTYPE(p) ((p)&0xFF)
61 18824b58 2008-08-03 rsc #define QARG(p) ((p)>>8)
62 18824b58 2008-08-03 rsc #define QPATH(p, q) ((p)|((q)<<8))
63 18824b58 2008-08-03 rsc
64 18824b58 2008-08-03 rsc char **nick;
65 18824b58 2008-08-03 rsc int nnick;
66 18824b58 2008-08-03 rsc
67 18824b58 2008-08-03 rsc struct Upload
68 18824b58 2008-08-03 rsc {
69 18824b58 2008-08-03 rsc Lock lk;
70 18824b58 2008-08-03 rsc int fd;
71 18824b58 2008-08-03 rsc char *name;
72 18824b58 2008-08-03 rsc char *file;
73 18824b58 2008-08-03 rsc vlong album;
74 18824b58 2008-08-03 rsc vlong length;
75 18824b58 2008-08-03 rsc char *albumkey;
76 18824b58 2008-08-03 rsc int size;
77 18824b58 2008-08-03 rsc int ready;
78 18824b58 2008-08-03 rsc int nwriters;
79 18824b58 2008-08-03 rsc int uploaded;
80 18824b58 2008-08-03 rsc int ref;
81 18824b58 2008-08-03 rsc int uploading;
82 18824b58 2008-08-03 rsc };
83 18824b58 2008-08-03 rsc
84 18824b58 2008-08-03 rsc Upload **up;
85 18824b58 2008-08-03 rsc int nup;
86 18824b58 2008-08-03 rsc QLock uploadlock;
87 18824b58 2008-08-03 rsc Rendez uploadrendez;
88 18824b58 2008-08-03 rsc
89 18824b58 2008-08-03 rsc void uploader(void*);
90 18824b58 2008-08-03 rsc
91 18824b58 2008-08-03 rsc Upload*
92 18824b58 2008-08-03 rsc newupload(SmugFid *sf, char *name)
93 18824b58 2008-08-03 rsc {
94 18824b58 2008-08-03 rsc Upload *u;
95 18824b58 2008-08-03 rsc int fd, i;
96 18824b58 2008-08-03 rsc char tmp[] = "/var/tmp/smugfs.XXXXXX";
97 fa325e9b 2020-01-10 cross
98 18824b58 2008-08-03 rsc if((fd = opentemp(tmp, ORDWR)) < 0)
99 18824b58 2008-08-03 rsc return nil;
100 18824b58 2008-08-03 rsc qlock(&uploadlock);
101 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
102 18824b58 2008-08-03 rsc u = up[i];
103 18824b58 2008-08-03 rsc lock(&u->lk);
104 18824b58 2008-08-03 rsc if(u->ref == 0){
105 18824b58 2008-08-03 rsc u->ref = 1;
106 18824b58 2008-08-03 rsc goto Reuse;
107 18824b58 2008-08-03 rsc }
108 18824b58 2008-08-03 rsc unlock(&u->lk);
109 18824b58 2008-08-03 rsc }
110 18824b58 2008-08-03 rsc if(nup == 0){
111 18824b58 2008-08-03 rsc uploadrendez.l = &uploadlock;
112 18824b58 2008-08-03 rsc proccreate(uploader, nil, STACKSIZE);
113 18824b58 2008-08-03 rsc }
114 18824b58 2008-08-03 rsc u = emalloc(sizeof *u);
115 18824b58 2008-08-03 rsc lock(&u->lk);
116 18824b58 2008-08-03 rsc u->ref = 1;
117 18824b58 2008-08-03 rsc up = erealloc(up, (nup+1)*sizeof up[0]);
118 18824b58 2008-08-03 rsc up[nup++] = u;
119 18824b58 2008-08-03 rsc Reuse:
120 18824b58 2008-08-03 rsc qunlock(&uploadlock);
121 18824b58 2008-08-03 rsc u->fd = fd;
122 18824b58 2008-08-03 rsc u->name = estrdup(name);
123 18824b58 2008-08-03 rsc u->file = estrdup(tmp);
124 18824b58 2008-08-03 rsc u->album = sf->album;
125 18824b58 2008-08-03 rsc u->albumkey = estrdup(sf->albumkey);
126 18824b58 2008-08-03 rsc u->nwriters = 1;
127 18824b58 2008-08-03 rsc unlock(&u->lk);
128 18824b58 2008-08-03 rsc return u;
129 18824b58 2008-08-03 rsc }
130 18824b58 2008-08-03 rsc
131 18824b58 2008-08-03 rsc void
132 18824b58 2008-08-03 rsc closeupload(Upload *u)
133 18824b58 2008-08-03 rsc {
134 18824b58 2008-08-03 rsc lock(&u->lk);
135 18824b58 2008-08-03 rsc if(--u->ref > 0){
136 18824b58 2008-08-03 rsc unlock(&u->lk);
137 18824b58 2008-08-03 rsc return;
138 18824b58 2008-08-03 rsc }
139 18824b58 2008-08-03 rsc if(u->ref < 0)
140 18824b58 2008-08-03 rsc abort();
141 18824b58 2008-08-03 rsc if(u->fd >= 0){
142 18824b58 2008-08-03 rsc close(u->fd);
143 18824b58 2008-08-03 rsc u->fd = -1;
144 18824b58 2008-08-03 rsc }
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;
148 18824b58 2008-08-03 rsc }
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;
153 18824b58 2008-08-03 rsc }
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;
158 18824b58 2008-08-03 rsc }
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);
166 18824b58 2008-08-03 rsc }
167 18824b58 2008-08-03 rsc
168 18824b58 2008-08-03 rsc Upload*
169 18824b58 2008-08-03 rsc getuploadindex(SmugFid *sf, int *index)
170 18824b58 2008-08-03 rsc {
171 18824b58 2008-08-03 rsc int i;
172 18824b58 2008-08-03 rsc Upload *u;
173 18824b58 2008-08-03 rsc
174 18824b58 2008-08-03 rsc qlock(&uploadlock);
175 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
176 18824b58 2008-08-03 rsc u = up[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);
180 18824b58 2008-08-03 rsc u->ref++;
181 18824b58 2008-08-03 rsc unlock(&u->lk);
182 18824b58 2008-08-03 rsc return u;
183 18824b58 2008-08-03 rsc }
184 18824b58 2008-08-03 rsc unlock(&u->lk);
185 18824b58 2008-08-03 rsc }
186 18824b58 2008-08-03 rsc qunlock(&uploadlock);
187 18824b58 2008-08-03 rsc return nil;
188 18824b58 2008-08-03 rsc }
189 18824b58 2008-08-03 rsc
190 18824b58 2008-08-03 rsc Upload*
191 18824b58 2008-08-03 rsc getuploadname(SmugFid *sf, char *name)
192 18824b58 2008-08-03 rsc {
193 18824b58 2008-08-03 rsc int i;
194 18824b58 2008-08-03 rsc Upload *u;
195 fa325e9b 2020-01-10 cross
196 18824b58 2008-08-03 rsc qlock(&uploadlock);
197 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
198 18824b58 2008-08-03 rsc u = up[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);
202 18824b58 2008-08-03 rsc u->ref++;
203 18824b58 2008-08-03 rsc unlock(&u->lk);
204 18824b58 2008-08-03 rsc return u;
205 18824b58 2008-08-03 rsc }
206 18824b58 2008-08-03 rsc unlock(&u->lk);
207 18824b58 2008-08-03 rsc }
208 18824b58 2008-08-03 rsc qunlock(&uploadlock);
209 18824b58 2008-08-03 rsc return nil;
210 18824b58 2008-08-03 rsc }
211 18824b58 2008-08-03 rsc
212 18824b58 2008-08-03 rsc void doupload(Upload*);
213 18824b58 2008-08-03 rsc
214 18824b58 2008-08-03 rsc void
215 18824b58 2008-08-03 rsc uploader(void *v)
216 18824b58 2008-08-03 rsc {
217 18824b58 2008-08-03 rsc int i, did;
218 18824b58 2008-08-03 rsc Upload *u;
219 18824b58 2008-08-03 rsc
220 18824b58 2008-08-03 rsc qlock(&uploadlock);
221 18824b58 2008-08-03 rsc for(;;){
222 18824b58 2008-08-03 rsc did = 0;
223 18824b58 2008-08-03 rsc for(i=0; i<nup; i++){
224 18824b58 2008-08-03 rsc u = up[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);
232 18824b58 2008-08-03 rsc did = 1;
233 18824b58 2008-08-03 rsc qlock(&uploadlock);
234 18824b58 2008-08-03 rsc }else
235 18824b58 2008-08-03 rsc unlock(&u->lk);
236 18824b58 2008-08-03 rsc }
237 18824b58 2008-08-03 rsc if(!did)
238 18824b58 2008-08-03 rsc rsleep(&uploadrendez);
239 18824b58 2008-08-03 rsc }
240 18824b58 2008-08-03 rsc }
241 18824b58 2008-08-03 rsc
242 18824b58 2008-08-03 rsc void
243 18824b58 2008-08-03 rsc kickupload(Upload *u)
244 18824b58 2008-08-03 rsc {
245 18824b58 2008-08-03 rsc Dir *d;
246 18824b58 2008-08-03 rsc
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);
251 18824b58 2008-08-03 rsc u->fd = -1;
252 18824b58 2008-08-03 rsc u->ref++;
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);
258 18824b58 2008-08-03 rsc }
259 18824b58 2008-08-03 rsc
260 18824b58 2008-08-03 rsc void
261 18824b58 2008-08-03 rsc doupload(Upload *u)
262 18824b58 2008-08-03 rsc {
263 18824b58 2008-08-03 rsc Dir *d;
264 18824b58 2008-08-03 rsc vlong datalen;
265 18824b58 2008-08-03 rsc Fmt fmt;
266 18824b58 2008-08-03 rsc char *req;
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;
271 18824b58 2008-08-03 rsc Json *jv;
272 18824b58 2008-08-03 rsc
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);
275 18824b58 2008-08-03 rsc return;
276 18824b58 2008-08-03 rsc }
277 18824b58 2008-08-03 rsc if((d = dirfstat(u->fd)) == nil){
278 18824b58 2008-08-03 rsc fprint(2, "fstat: %r\n");
279 18824b58 2008-08-03 rsc return;
280 18824b58 2008-08-03 rsc }
281 18824b58 2008-08-03 rsc datalen = d->length;
282 18824b58 2008-08-03 rsc free(d);
283 fa325e9b 2020-01-10 cross
284 18824b58 2008-08-03 rsc memset(&ds, 0, sizeof ds);
285 18824b58 2008-08-03 rsc seek(u->fd, 0, 0);
286 18824b58 2008-08-03 rsc total = 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);
289 18824b58 2008-08-03 rsc total += n;
290 18824b58 2008-08-03 rsc }
291 18824b58 2008-08-03 rsc if(total != datalen){
292 18824b58 2008-08-03 rsc fprint(2, "bad total: %lld %lld\n", total, datalen);
293 18824b58 2008-08-03 rsc return;
294 18824b58 2008-08-03 rsc }
295 18824b58 2008-08-03 rsc md5(nil, 0, digest, &ds);
296 18824b58 2008-08-03 rsc
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);
309 fa325e9b 2020-01-10 cross
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);
312 18824b58 2008-08-03 rsc free(req);
313 18824b58 2008-08-03 rsc if(jv == nil){
314 18824b58 2008-08-03 rsc fprint(2, "upload: %r\n");
315 18824b58 2008-08-03 rsc return;
316 18824b58 2008-08-03 rsc }
317 18824b58 2008-08-03 rsc
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;
322 18824b58 2008-08-03 rsc u->fd = -1;
323 18824b58 2008-08-03 rsc u->uploaded = 1;
324 18824b58 2008-08-03 rsc rpclog("uploaded: %J", jv);
325 18824b58 2008-08-03 rsc jclose(jv);
326 18824b58 2008-08-03 rsc }
327 18824b58 2008-08-03 rsc
328 18824b58 2008-08-03 rsc int
329 18824b58 2008-08-03 rsc nickindex(char *name)
330 18824b58 2008-08-03 rsc {
331 18824b58 2008-08-03 rsc int i;
332 18824b58 2008-08-03 rsc Json *v;
333 fa325e9b 2020-01-10 cross
334 18824b58 2008-08-03 rsc for(i=0; i<nnick; i++)
335 18824b58 2008-08-03 rsc if(strcmp(nick[i], name) == 0)
336 18824b58 2008-08-03 rsc return i;
337 18824b58 2008-08-03 rsc v = smug("smugmug.users.getTree", "NickName", name, nil);
338 18824b58 2008-08-03 rsc if(v == nil)
339 18824b58 2008-08-03 rsc return -1;
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++;
343 18824b58 2008-08-03 rsc }
344 18824b58 2008-08-03 rsc
345 18824b58 2008-08-03 rsc char*
346 18824b58 2008-08-03 rsc nickname(int i)
347 18824b58 2008-08-03 rsc {
348 18824b58 2008-08-03 rsc if(i < 0 || i >= nnick)
349 18824b58 2008-08-03 rsc return nil;
350 18824b58 2008-08-03 rsc return nick[i];
351 18824b58 2008-08-03 rsc }
352 18824b58 2008-08-03 rsc
353 18824b58 2008-08-03 rsc void
354 18824b58 2008-08-03 rsc responderrstr(Req *r)
355 18824b58 2008-08-03 rsc {
356 18824b58 2008-08-03 rsc char err[ERRMAX];
357 fa325e9b 2020-01-10 cross
358 18824b58 2008-08-03 rsc rerrstr(err, sizeof err);
359 18824b58 2008-08-03 rsc respond(r, err);
360 18824b58 2008-08-03 rsc }
361 18824b58 2008-08-03 rsc
362 18824b58 2008-08-03 rsc static char*
363 18824b58 2008-08-03 rsc xclone(Fid *oldfid, Fid *newfid)
364 18824b58 2008-08-03 rsc {
365 18824b58 2008-08-03 rsc SmugFid *sf;
366 fa325e9b 2020-01-10 cross
367 18824b58 2008-08-03 rsc if(oldfid->aux == nil)
368 18824b58 2008-08-03 rsc return nil;
369 18824b58 2008-08-03 rsc
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;
379 18824b58 2008-08-03 rsc return nil;
380 18824b58 2008-08-03 rsc }
381 18824b58 2008-08-03 rsc
382 18824b58 2008-08-03 rsc static void
383 18824b58 2008-08-03 rsc xdestroyfid(Fid *fid)
384 18824b58 2008-08-03 rsc {
385 18824b58 2008-08-03 rsc SmugFid *sf;
386 18824b58 2008-08-03 rsc
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);
394 18824b58 2008-08-03 rsc }
395 18824b58 2008-08-03 rsc closeupload(sf->upload);
396 18824b58 2008-08-03 rsc sf->upload = nil;
397 18824b58 2008-08-03 rsc }
398 18824b58 2008-08-03 rsc free(sf);
399 18824b58 2008-08-03 rsc }
400 18824b58 2008-08-03 rsc
401 18824b58 2008-08-03 rsc static Json*
402 18824b58 2008-08-03 rsc getcategories(SmugFid *sf)
403 18824b58 2008-08-03 rsc {
404 18824b58 2008-08-03 rsc Json *v, *w;
405 fa325e9b 2020-01-10 cross
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"));
408 18824b58 2008-08-03 rsc jclose(v);
409 18824b58 2008-08-03 rsc return w;
410 18824b58 2008-08-03 rsc }
411 18824b58 2008-08-03 rsc
412 18824b58 2008-08-03 rsc static Json*
413 18824b58 2008-08-03 rsc getcategorytree(SmugFid *sf)
414 18824b58 2008-08-03 rsc {
415 18824b58 2008-08-03 rsc Json *v, *w;
416 fa325e9b 2020-01-10 cross
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"));
419 18824b58 2008-08-03 rsc jclose(v);
420 18824b58 2008-08-03 rsc return w;
421 18824b58 2008-08-03 rsc }
422 18824b58 2008-08-03 rsc
423 18824b58 2008-08-03 rsc static Json*
424 18824b58 2008-08-03 rsc getcategory(SmugFid *sf, vlong id)
425 18824b58 2008-08-03 rsc {
426 18824b58 2008-08-03 rsc int i;
427 18824b58 2008-08-03 rsc Json *v, *w;
428 fa325e9b 2020-01-10 cross
429 18824b58 2008-08-03 rsc v = getcategorytree(sf);
430 18824b58 2008-08-03 rsc if(v == nil)
431 18824b58 2008-08-03 rsc return 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]);
435 18824b58 2008-08-03 rsc jclose(v);
436 18824b58 2008-08-03 rsc return w;
437 18824b58 2008-08-03 rsc }
438 18824b58 2008-08-03 rsc }
439 18824b58 2008-08-03 rsc jclose(v);
440 18824b58 2008-08-03 rsc return nil;
441 18824b58 2008-08-03 rsc }
442 18824b58 2008-08-03 rsc
443 18824b58 2008-08-03 rsc static vlong
444 18824b58 2008-08-03 rsc getcategoryid(SmugFid *sf, char *name)
445 18824b58 2008-08-03 rsc {
446 18824b58 2008-08-03 rsc int i;
447 18824b58 2008-08-03 rsc vlong id;
448 18824b58 2008-08-03 rsc Json *v;
449 fa325e9b 2020-01-10 cross
450 18824b58 2008-08-03 rsc v = getcategories(sf);
451 18824b58 2008-08-03 rsc if(v == nil)
452 18824b58 2008-08-03 rsc return -1;
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"));
456 18824b58 2008-08-03 rsc if(id < 0){
457 18824b58 2008-08-03 rsc jclose(v);
458 18824b58 2008-08-03 rsc return -1;
459 18824b58 2008-08-03 rsc }
460 18824b58 2008-08-03 rsc jclose(v);
461 18824b58 2008-08-03 rsc return id;
462 18824b58 2008-08-03 rsc }
463 18824b58 2008-08-03 rsc }
464 18824b58 2008-08-03 rsc jclose(v);
465 18824b58 2008-08-03 rsc return -1;
466 18824b58 2008-08-03 rsc }
467 18824b58 2008-08-03 rsc
468 18824b58 2008-08-03 rsc static vlong
469 18824b58 2008-08-03 rsc getcategoryindex(SmugFid *sf, int i)
470 18824b58 2008-08-03 rsc {
471 18824b58 2008-08-03 rsc Json *v;
472 18824b58 2008-08-03 rsc vlong id;
473 fa325e9b 2020-01-10 cross
474 18824b58 2008-08-03 rsc v = getcategories(sf);
475 18824b58 2008-08-03 rsc if(v == nil)
476 18824b58 2008-08-03 rsc return -1;
477 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
478 18824b58 2008-08-03 rsc jclose(v);
479 18824b58 2008-08-03 rsc return -1;
480 18824b58 2008-08-03 rsc }
481 18824b58 2008-08-03 rsc id = jint(jwalk(v->value[i], "id"));
482 18824b58 2008-08-03 rsc jclose(v);
483 18824b58 2008-08-03 rsc return id;
484 18824b58 2008-08-03 rsc }
485 18824b58 2008-08-03 rsc
486 18824b58 2008-08-03 rsc static Json*
487 18824b58 2008-08-03 rsc getalbum(SmugFid *sf, vlong albumid, char *albumkey)
488 18824b58 2008-08-03 rsc {
489 18824b58 2008-08-03 rsc char id[50];
490 18824b58 2008-08-03 rsc Json *v, *w;
491 18824b58 2008-08-03 rsc
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"));
497 18824b58 2008-08-03 rsc jclose(v);
498 18824b58 2008-08-03 rsc return w;
499 18824b58 2008-08-03 rsc }
500 18824b58 2008-08-03 rsc
501 18824b58 2008-08-03 rsc static Json*
502 18824b58 2008-08-03 rsc getalbums(SmugFid *sf)
503 18824b58 2008-08-03 rsc {
504 18824b58 2008-08-03 rsc Json *v, *w;
505 18824b58 2008-08-03 rsc
506 18824b58 2008-08-03 rsc if(sf->category >= 0)
507 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
508 18824b58 2008-08-03 rsc else
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"));
512 18824b58 2008-08-03 rsc jclose(v);
513 fa325e9b 2020-01-10 cross return w;
514 18824b58 2008-08-03 rsc }
515 18824b58 2008-08-03 rsc
516 18824b58 2008-08-03 rsc static vlong
517 18824b58 2008-08-03 rsc getalbumid(SmugFid *sf, char *name, char **keyp)
518 18824b58 2008-08-03 rsc {
519 18824b58 2008-08-03 rsc int i;
520 18824b58 2008-08-03 rsc vlong id;
521 18824b58 2008-08-03 rsc Json *v;
522 18824b58 2008-08-03 rsc char *key;
523 fa325e9b 2020-01-10 cross
524 18824b58 2008-08-03 rsc v = getalbums(sf);
525 18824b58 2008-08-03 rsc if(v == nil)
526 18824b58 2008-08-03 rsc return -1;
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){
532 18824b58 2008-08-03 rsc jclose(v);
533 18824b58 2008-08-03 rsc return -1;
534 18824b58 2008-08-03 rsc }
535 18824b58 2008-08-03 rsc if(keyp)
536 18824b58 2008-08-03 rsc *keyp = estrdup(key);
537 18824b58 2008-08-03 rsc jclose(v);
538 18824b58 2008-08-03 rsc return id;
539 18824b58 2008-08-03 rsc }
540 18824b58 2008-08-03 rsc }
541 18824b58 2008-08-03 rsc jclose(v);
542 18824b58 2008-08-03 rsc return -1;
543 18824b58 2008-08-03 rsc }
544 18824b58 2008-08-03 rsc
545 18824b58 2008-08-03 rsc static vlong
546 18824b58 2008-08-03 rsc getalbumindex(SmugFid *sf, int i, char **keyp)
547 18824b58 2008-08-03 rsc {
548 18824b58 2008-08-03 rsc vlong id;
549 18824b58 2008-08-03 rsc Json *v;
550 18824b58 2008-08-03 rsc char *key;
551 fa325e9b 2020-01-10 cross
552 18824b58 2008-08-03 rsc v = getalbums(sf);
553 18824b58 2008-08-03 rsc if(v == nil)
554 18824b58 2008-08-03 rsc return -1;
555 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
556 18824b58 2008-08-03 rsc jclose(v);
557 18824b58 2008-08-03 rsc return -1;
558 18824b58 2008-08-03 rsc }
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){
562 18824b58 2008-08-03 rsc jclose(v);
563 18824b58 2008-08-03 rsc return -1;
564 18824b58 2008-08-03 rsc }
565 18824b58 2008-08-03 rsc if(keyp)
566 18824b58 2008-08-03 rsc *keyp = estrdup(key);
567 18824b58 2008-08-03 rsc jclose(v);
568 18824b58 2008-08-03 rsc return id;
569 18824b58 2008-08-03 rsc }
570 18824b58 2008-08-03 rsc
571 18824b58 2008-08-03 rsc static Json*
572 18824b58 2008-08-03 rsc getimages(SmugFid *sf, vlong albumid, char *albumkey)
573 18824b58 2008-08-03 rsc {
574 18824b58 2008-08-03 rsc char id[50];
575 18824b58 2008-08-03 rsc Json *v, *w;
576 18824b58 2008-08-03 rsc
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"));
582 18824b58 2008-08-03 rsc jclose(v);
583 18824b58 2008-08-03 rsc return w;
584 18824b58 2008-08-03 rsc }
585 18824b58 2008-08-03 rsc
586 18824b58 2008-08-03 rsc static vlong
587 18824b58 2008-08-03 rsc getimageid(SmugFid *sf, char *name, char **keyp)
588 18824b58 2008-08-03 rsc {
589 18824b58 2008-08-03 rsc int i;
590 18824b58 2008-08-03 rsc vlong id;
591 18824b58 2008-08-03 rsc Json *v;
592 18824b58 2008-08-03 rsc char *p;
593 18824b58 2008-08-03 rsc char *key;
594 fa325e9b 2020-01-10 cross
595 18824b58 2008-08-03 rsc id = strtol(name, &p, 10);
596 18824b58 2008-08-03 rsc if(*p != 0 || *name == 0)
597 18824b58 2008-08-03 rsc return -1;
598 18824b58 2008-08-03 rsc
599 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
600 18824b58 2008-08-03 rsc if(v == nil)
601 18824b58 2008-08-03 rsc return -1;
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){
606 18824b58 2008-08-03 rsc jclose(v);
607 18824b58 2008-08-03 rsc return -1;
608 18824b58 2008-08-03 rsc }
609 18824b58 2008-08-03 rsc if(keyp)
610 18824b58 2008-08-03 rsc *keyp = estrdup(key);
611 18824b58 2008-08-03 rsc jclose(v);
612 18824b58 2008-08-03 rsc return id;
613 18824b58 2008-08-03 rsc }
614 18824b58 2008-08-03 rsc }
615 18824b58 2008-08-03 rsc jclose(v);
616 18824b58 2008-08-03 rsc return -1;
617 18824b58 2008-08-03 rsc }
618 18824b58 2008-08-03 rsc
619 18824b58 2008-08-03 rsc static Json*
620 18824b58 2008-08-03 rsc getimageinfo(SmugFid *sf, vlong imageid, char *imagekey)
621 18824b58 2008-08-03 rsc {
622 18824b58 2008-08-03 rsc char id[50];
623 18824b58 2008-08-03 rsc Json *v, *w;
624 18824b58 2008-08-03 rsc
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"));
630 18824b58 2008-08-03 rsc jclose(v);
631 18824b58 2008-08-03 rsc return w;
632 18824b58 2008-08-03 rsc }
633 18824b58 2008-08-03 rsc
634 18824b58 2008-08-03 rsc static Json*
635 18824b58 2008-08-03 rsc getimageexif(SmugFid *sf, vlong imageid, char *imagekey)
636 18824b58 2008-08-03 rsc {
637 18824b58 2008-08-03 rsc char id[50];
638 18824b58 2008-08-03 rsc Json *v, *w;
639 18824b58 2008-08-03 rsc
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"));
645 18824b58 2008-08-03 rsc jclose(v);
646 18824b58 2008-08-03 rsc return w;
647 18824b58 2008-08-03 rsc }
648 18824b58 2008-08-03 rsc
649 18824b58 2008-08-03 rsc static vlong
650 18824b58 2008-08-03 rsc getimageindex(SmugFid *sf, int i, char **keyp)
651 18824b58 2008-08-03 rsc {
652 18824b58 2008-08-03 rsc vlong id;
653 18824b58 2008-08-03 rsc Json *v;
654 18824b58 2008-08-03 rsc char *key;
655 fa325e9b 2020-01-10 cross
656 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
657 18824b58 2008-08-03 rsc if(v == nil)
658 18824b58 2008-08-03 rsc return -1;
659 18824b58 2008-08-03 rsc if(i < 0 || i >= v->len){
660 18824b58 2008-08-03 rsc jclose(v);
661 18824b58 2008-08-03 rsc return -1;
662 18824b58 2008-08-03 rsc }
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){
666 18824b58 2008-08-03 rsc jclose(v);
667 18824b58 2008-08-03 rsc return -1;
668 18824b58 2008-08-03 rsc }
669 18824b58 2008-08-03 rsc if(keyp)
670 18824b58 2008-08-03 rsc *keyp = estrdup(key);
671 18824b58 2008-08-03 rsc jclose(v);
672 18824b58 2008-08-03 rsc return id;
673 18824b58 2008-08-03 rsc }
674 18824b58 2008-08-03 rsc
675 18824b58 2008-08-03 rsc static char*
676 18824b58 2008-08-03 rsc categoryname(SmugFid *sf)
677 18824b58 2008-08-03 rsc {
678 18824b58 2008-08-03 rsc Json *v;
679 18824b58 2008-08-03 rsc char *s;
680 fa325e9b 2020-01-10 cross
681 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
682 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "Name"));
683 18824b58 2008-08-03 rsc if(s)
684 18824b58 2008-08-03 rsc s = estrdup(s);
685 18824b58 2008-08-03 rsc jclose(v);
686 18824b58 2008-08-03 rsc return s;
687 18824b58 2008-08-03 rsc }
688 18824b58 2008-08-03 rsc
689 18824b58 2008-08-03 rsc static char*
690 18824b58 2008-08-03 rsc albumname(SmugFid *sf)
691 18824b58 2008-08-03 rsc {
692 18824b58 2008-08-03 rsc Json *v;
693 18824b58 2008-08-03 rsc char *s;
694 fa325e9b 2020-01-10 cross
695 18824b58 2008-08-03 rsc v = getalbum(sf, sf->album, sf->albumkey);
696 18824b58 2008-08-03 rsc s = jstring(jwalk(v, "Title"));
697 18824b58 2008-08-03 rsc if(s)
698 18824b58 2008-08-03 rsc s = estrdup(s);
699 18824b58 2008-08-03 rsc jclose(v);
700 18824b58 2008-08-03 rsc return s;
701 18824b58 2008-08-03 rsc }
702 18824b58 2008-08-03 rsc
703 18824b58 2008-08-03 rsc static char*
704 18824b58 2008-08-03 rsc imagename(SmugFid *sf)
705 18824b58 2008-08-03 rsc {
706 18824b58 2008-08-03 rsc char *s;
707 18824b58 2008-08-03 rsc Json *v;
708 fa325e9b 2020-01-10 cross
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);
713 18824b58 2008-08-03 rsc else
714 18824b58 2008-08-03 rsc s = smprint("%lld.jpg", sf->image); // TODO: use Format
715 18824b58 2008-08-03 rsc jclose(v);
716 18824b58 2008-08-03 rsc return s;
717 18824b58 2008-08-03 rsc }
718 18824b58 2008-08-03 rsc
719 18824b58 2008-08-03 rsc static vlong
720 18824b58 2008-08-03 rsc imagelength(SmugFid *sf)
721 18824b58 2008-08-03 rsc {
722 18824b58 2008-08-03 rsc vlong length;
723 18824b58 2008-08-03 rsc Json *v;
724 fa325e9b 2020-01-10 cross
725 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
726 18824b58 2008-08-03 rsc length = jint(jwalk(v, "Size"));
727 18824b58 2008-08-03 rsc jclose(v);
728 18824b58 2008-08-03 rsc return length;
729 18824b58 2008-08-03 rsc }
730 18824b58 2008-08-03 rsc
731 18824b58 2008-08-03 rsc static struct {
732 18824b58 2008-08-03 rsc char *key;
733 18824b58 2008-08-03 rsc char *name;
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",
745 18824b58 2008-08-03 rsc };
746 18824b58 2008-08-03 rsc
747 18824b58 2008-08-03 rsc static char*
748 18824b58 2008-08-03 rsc imageurl(SmugFid *sf)
749 18824b58 2008-08-03 rsc {
750 18824b58 2008-08-03 rsc Json *v;
751 18824b58 2008-08-03 rsc char *s;
752 18824b58 2008-08-03 rsc int i;
753 18824b58 2008-08-03 rsc
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);
758 18824b58 2008-08-03 rsc jclose(v);
759 18824b58 2008-08-03 rsc return s;
760 18824b58 2008-08-03 rsc }
761 18824b58 2008-08-03 rsc }
762 18824b58 2008-08-03 rsc jclose(v);
763 18824b58 2008-08-03 rsc return nil;
764 18824b58 2008-08-03 rsc }
765 18824b58 2008-08-03 rsc
766 fa325e9b 2020-01-10 cross static char* imagestrings[] =
767 18824b58 2008-08-03 rsc {
768 18824b58 2008-08-03 rsc "Caption",
769 18824b58 2008-08-03 rsc "LastUpdated",
770 18824b58 2008-08-03 rsc "FileName",
771 18824b58 2008-08-03 rsc "MD5Sum",
772 18824b58 2008-08-03 rsc "Watermark",
773 18824b58 2008-08-03 rsc "Format",
774 18824b58 2008-08-03 rsc "Keywords",
775 18824b58 2008-08-03 rsc "Date",
776 18824b58 2008-08-03 rsc "AlbumURL",
777 18824b58 2008-08-03 rsc "TinyURL",
778 18824b58 2008-08-03 rsc "ThumbURL",
779 18824b58 2008-08-03 rsc "SmallURL",
780 18824b58 2008-08-03 rsc "MediumURL",
781 18824b58 2008-08-03 rsc "LargeURL",
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",
786 18824b58 2008-08-03 rsc "Album",
787 18824b58 2008-08-03 rsc };
788 18824b58 2008-08-03 rsc
789 fa325e9b 2020-01-10 cross static char* albumbools[] =
790 18824b58 2008-08-03 rsc {
791 18824b58 2008-08-03 rsc "Public",
792 18824b58 2008-08-03 rsc "Printable",
793 18824b58 2008-08-03 rsc "Filenames",
794 18824b58 2008-08-03 rsc "Comments",
795 18824b58 2008-08-03 rsc "External",
796 18824b58 2008-08-03 rsc "Originals",
797 18824b58 2008-08-03 rsc "EXIF",
798 18824b58 2008-08-03 rsc "Share",
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",
803 18824b58 2008-08-03 rsc "CanRank",
804 18824b58 2008-08-03 rsc "Clean",
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",
809 18824b58 2008-08-03 rsc "X2Larges",
810 18824b58 2008-08-03 rsc "X3Larges",
811 18824b58 2008-08-03 rsc };
812 18824b58 2008-08-03 rsc
813 fa325e9b 2020-01-10 cross static char* albumstrings[] =
814 18824b58 2008-08-03 rsc {
815 18824b58 2008-08-03 rsc "Description"
816 18824b58 2008-08-03 rsc "Keywords",
817 18824b58 2008-08-03 rsc "Password",
818 18824b58 2008-08-03 rsc "PasswordHint",
819 18824b58 2008-08-03 rsc "SortMethod",
820 18824b58 2008-08-03 rsc "LastUpdated",
821 18824b58 2008-08-03 rsc };
822 18824b58 2008-08-03 rsc
823 18824b58 2008-08-03 rsc static char*
824 18824b58 2008-08-03 rsc readctl(SmugFid *sf)
825 18824b58 2008-08-03 rsc {
826 18824b58 2008-08-03 rsc int i;
827 18824b58 2008-08-03 rsc Upload *u;
828 18824b58 2008-08-03 rsc char *s;
829 18824b58 2008-08-03 rsc Json *v, *vv;
830 18824b58 2008-08-03 rsc Fmt fmt;
831 18824b58 2008-08-03 rsc
832 18824b58 2008-08-03 rsc v = nil;
833 18824b58 2008-08-03 rsc switch(sf->type){
834 18824b58 2008-08-03 rsc case Qctl:
835 18824b58 2008-08-03 rsc return smprint("%#J\n", userinfo);
836 18824b58 2008-08-03 rsc
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++){
841 18824b58 2008-08-03 rsc u = up[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);
846 18824b58 2008-08-03 rsc }
847 18824b58 2008-08-03 rsc qunlock(&uploadlock);
848 18824b58 2008-08-03 rsc return fmtstrflush(&fmt);
849 18824b58 2008-08-03 rsc
850 18824b58 2008-08-03 rsc case Qnickctl:
851 18824b58 2008-08-03 rsc v = getcategories(sf);
852 18824b58 2008-08-03 rsc break;
853 18824b58 2008-08-03 rsc
854 18824b58 2008-08-03 rsc case Qcategoryctl:
855 18824b58 2008-08-03 rsc v = getcategory(sf, sf->category);
856 18824b58 2008-08-03 rsc break;
857 18824b58 2008-08-03 rsc
858 18824b58 2008-08-03 rsc case Qalbumctl:
859 18824b58 2008-08-03 rsc v = getimages(sf, sf->album, sf->albumkey);
860 18824b58 2008-08-03 rsc break;
861 18824b58 2008-08-03 rsc
862 18824b58 2008-08-03 rsc case Qalbumsctl:
863 18824b58 2008-08-03 rsc v = getalbums(sf);
864 18824b58 2008-08-03 rsc break;
865 18824b58 2008-08-03 rsc
866 18824b58 2008-08-03 rsc case Qimagectl:
867 18824b58 2008-08-03 rsc v = getimageinfo(sf, sf->image, sf->imagekey);
868 18824b58 2008-08-03 rsc break;
869 fa325e9b 2020-01-10 cross
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);
876 18824b58 2008-08-03 rsc jclose(v);
877 18824b58 2008-08-03 rsc return fmtstrflush(&fmt);
878 fa325e9b 2020-01-10 cross
879 18824b58 2008-08-03 rsc case Qimageexif:
880 18824b58 2008-08-03 rsc v = getimageexif(sf, sf->image, sf->imagekey);
881 18824b58 2008-08-03 rsc break;
882 fa325e9b 2020-01-10 cross
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]);
896 18824b58 2008-08-03 rsc if(vv)
897 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%J\n", albumbools[i], vv);
898 18824b58 2008-08-03 rsc }
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]));
901 18824b58 2008-08-03 rsc if(s)
902 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%s\n", albumstrings[i], s);
903 18824b58 2008-08-03 rsc }
904 18824b58 2008-08-03 rsc s = fmtstrflush(&fmt);
905 18824b58 2008-08-03 rsc jclose(v);
906 18824b58 2008-08-03 rsc return s;
907 18824b58 2008-08-03 rsc
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]));
923 18824b58 2008-08-03 rsc if(s)
924 18824b58 2008-08-03 rsc fmtprint(&fmt, "%s\t%s\n", imagestrings[i], s);
925 18824b58 2008-08-03 rsc }
926 18824b58 2008-08-03 rsc s = fmtstrflush(&fmt);
927 18824b58 2008-08-03 rsc jclose(v);
928 18824b58 2008-08-03 rsc return s;
929 18824b58 2008-08-03 rsc }
930 18824b58 2008-08-03 rsc
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);
934 18824b58 2008-08-03 rsc jclose(v);
935 18824b58 2008-08-03 rsc return s;
936 18824b58 2008-08-03 rsc }
937 18824b58 2008-08-03 rsc
938 18824b58 2008-08-03 rsc
939 18824b58 2008-08-03 rsc static void
940 18824b58 2008-08-03 rsc dostat(SmugFid *sf, Qid *qid, Dir *dir)
941 18824b58 2008-08-03 rsc {
942 18824b58 2008-08-03 rsc Qid q;
943 18824b58 2008-08-03 rsc char *name;
944 18824b58 2008-08-03 rsc int freename;
945 18824b58 2008-08-03 rsc ulong mode;
946 18824b58 2008-08-03 rsc char *uid;
947 18824b58 2008-08-03 rsc char *s;
948 18824b58 2008-08-03 rsc vlong length;
949 fa325e9b 2020-01-10 cross
950 18824b58 2008-08-03 rsc memset(&q, 0, sizeof q);
951 18824b58 2008-08-03 rsc name = nil;
952 18824b58 2008-08-03 rsc freename = 0;
953 18824b58 2008-08-03 rsc uid = "smugfs";
954 18824b58 2008-08-03 rsc q.type = 0;
955 18824b58 2008-08-03 rsc q.vers = 0;
956 18824b58 2008-08-03 rsc q.path = QPATH(sf->type, sf->nickid);
957 18824b58 2008-08-03 rsc length = 0;
958 18824b58 2008-08-03 rsc mode = 0444;
959 18824b58 2008-08-03 rsc
960 18824b58 2008-08-03 rsc switch(sf->type){
961 18824b58 2008-08-03 rsc case Qroot:
962 18824b58 2008-08-03 rsc name = "/";
963 18824b58 2008-08-03 rsc q.type = QTDIR;
964 18824b58 2008-08-03 rsc break;
965 18824b58 2008-08-03 rsc case Qctl:
966 18824b58 2008-08-03 rsc name = "ctl";
967 18824b58 2008-08-03 rsc mode |= 0222;
968 18824b58 2008-08-03 rsc break;
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);
972 18824b58 2008-08-03 rsc if(s){
973 18824b58 2008-08-03 rsc length = strlen(s);
974 18824b58 2008-08-03 rsc free(s);
975 18824b58 2008-08-03 rsc }
976 18824b58 2008-08-03 rsc break;
977 18824b58 2008-08-03 rsc case Qrpclog:
978 18824b58 2008-08-03 rsc name = "rpclog";
979 18824b58 2008-08-03 rsc break;
980 18824b58 2008-08-03 rsc case Qnick:
981 18824b58 2008-08-03 rsc name = nickname(sf->nickid);
982 18824b58 2008-08-03 rsc q.type = QTDIR;
983 18824b58 2008-08-03 rsc break;
984 18824b58 2008-08-03 rsc case Qnickctl:
985 18824b58 2008-08-03 rsc name = "ctl";
986 18824b58 2008-08-03 rsc mode |= 0222;
987 18824b58 2008-08-03 rsc break;
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;
991 18824b58 2008-08-03 rsc break;
992 18824b58 2008-08-03 rsc case Qalbumsctl:
993 18824b58 2008-08-03 rsc name = "ctl";
994 18824b58 2008-08-03 rsc mode |= 0222;
995 18824b58 2008-08-03 rsc break;
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;
1001 18824b58 2008-08-03 rsc break;
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);
1006 18824b58 2008-08-03 rsc break;
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;
1012 18824b58 2008-08-03 rsc break;
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);
1017 18824b58 2008-08-03 rsc break;
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);
1022 18824b58 2008-08-03 rsc break;
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){
1026 18824b58 2008-08-03 rsc Dir *dd;
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);
1030 18824b58 2008-08-03 rsc if(dd){
1031 18824b58 2008-08-03 rsc length = dd->length;
1032 18824b58 2008-08-03 rsc free(dd);
1033 18824b58 2008-08-03 rsc }
1034 18824b58 2008-08-03 rsc }else
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;
1038 18824b58 2008-08-03 rsc }
1039 18824b58 2008-08-03 rsc break;
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;
1045 18824b58 2008-08-03 rsc break;
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);
1050 18824b58 2008-08-03 rsc break;
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);
1055 18824b58 2008-08-03 rsc break;
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);
1059 18824b58 2008-08-03 rsc break;
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);
1063 18824b58 2008-08-03 rsc break;
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);
1069 18824b58 2008-08-03 rsc break;
1070 18824b58 2008-08-03 rsc default:
1071 18824b58 2008-08-03 rsc name = "?egreg";
1072 18824b58 2008-08-03 rsc q.path = 0;
1073 18824b58 2008-08-03 rsc break;
1074 18824b58 2008-08-03 rsc }
1075 18824b58 2008-08-03 rsc
1076 18824b58 2008-08-03 rsc if(name == nil){
1077 18824b58 2008-08-03 rsc name = "???";
1078 18824b58 2008-08-03 rsc freename = 0;
1079 18824b58 2008-08-03 rsc }
1080 18824b58 2008-08-03 rsc
1081 18824b58 2008-08-03 rsc if(qid)
1082 18824b58 2008-08-03 rsc *qid = q;
1083 18824b58 2008-08-03 rsc if(dir){
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;
1095 18824b58 2008-08-03 rsc }
1096 18824b58 2008-08-03 rsc if(freename)
1097 18824b58 2008-08-03 rsc free(name);
1098 18824b58 2008-08-03 rsc }
1099 18824b58 2008-08-03 rsc
1100 18824b58 2008-08-03 rsc static char*
1101 18824b58 2008-08-03 rsc xwalk1(Fid *fid, char *name, Qid *qid)
1102 18824b58 2008-08-03 rsc {
1103 18824b58 2008-08-03 rsc int dotdot, i;
1104 18824b58 2008-08-03 rsc vlong id;
1105 18824b58 2008-08-03 rsc char *key;
1106 18824b58 2008-08-03 rsc SmugFid *sf;
1107 18824b58 2008-08-03 rsc char *x;
1108 18824b58 2008-08-03 rsc Upload *u;
1109 fa325e9b 2020-01-10 cross
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){
1113 18824b58 2008-08-03 rsc default:
1114 18824b58 2008-08-03 rsc NotFound:
1115 18824b58 2008-08-03 rsc return "file not found";
1116 18824b58 2008-08-03 rsc
1117 18824b58 2008-08-03 rsc case Qroot:
1118 18824b58 2008-08-03 rsc if(dotdot)
1119 18824b58 2008-08-03 rsc break;
1120 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1121 18824b58 2008-08-03 rsc sf->type = Qctl;
1122 18824b58 2008-08-03 rsc break;
1123 18824b58 2008-08-03 rsc }
1124 18824b58 2008-08-03 rsc if(strcmp(name, "uploads") == 0){
1125 18824b58 2008-08-03 rsc sf->type = Quploads;
1126 18824b58 2008-08-03 rsc break;
1127 18824b58 2008-08-03 rsc }
1128 18824b58 2008-08-03 rsc if(strcmp(name, "rpclog") == 0){
1129 18824b58 2008-08-03 rsc sf->type = Qrpclog;
1130 18824b58 2008-08-03 rsc break;
1131 18824b58 2008-08-03 rsc }
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;
1135 18824b58 2008-08-03 rsc break;
1136 18824b58 2008-08-03 rsc }
1137 18824b58 2008-08-03 rsc goto NotFound;
1138 18824b58 2008-08-03 rsc
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;
1143 18824b58 2008-08-03 rsc break;
1144 18824b58 2008-08-03 rsc }
1145 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1146 18824b58 2008-08-03 rsc sf->type = Qnickctl;
1147 18824b58 2008-08-03 rsc break;
1148 18824b58 2008-08-03 rsc }
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;
1152 18824b58 2008-08-03 rsc break;
1153 18824b58 2008-08-03 rsc }
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;
1157 18824b58 2008-08-03 rsc break;
1158 18824b58 2008-08-03 rsc }
1159 18824b58 2008-08-03 rsc goto NotFound;
1160 fa325e9b 2020-01-10 cross
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;
1166 18824b58 2008-08-03 rsc break;
1167 18824b58 2008-08-03 rsc }
1168 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1169 18824b58 2008-08-03 rsc sf->type++;
1170 18824b58 2008-08-03 rsc break;
1171 18824b58 2008-08-03 rsc }
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;
1176 18824b58 2008-08-03 rsc break;
1177 18824b58 2008-08-03 rsc }
1178 18824b58 2008-08-03 rsc goto NotFound;
1179 18824b58 2008-08-03 rsc
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;
1187 18824b58 2008-08-03 rsc else
1188 18824b58 2008-08-03 rsc sf->type = Qcategory;
1189 18824b58 2008-08-03 rsc break;
1190 18824b58 2008-08-03 rsc }
1191 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1192 18824b58 2008-08-03 rsc sf->type = Qalbumctl;
1193 18824b58 2008-08-03 rsc break;
1194 18824b58 2008-08-03 rsc }
1195 18824b58 2008-08-03 rsc if(strcmp(name, "settings") == 0){
1196 18824b58 2008-08-03 rsc sf->type = Qalbumsettings;
1197 18824b58 2008-08-03 rsc break;
1198 18824b58 2008-08-03 rsc }
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;
1203 18824b58 2008-08-03 rsc break;
1204 18824b58 2008-08-03 rsc }
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;
1208 18824b58 2008-08-03 rsc break;
1209 18824b58 2008-08-03 rsc }
1210 18824b58 2008-08-03 rsc goto NotFound;
1211 fa325e9b 2020-01-10 cross
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;
1218 18824b58 2008-08-03 rsc break;
1219 18824b58 2008-08-03 rsc }
1220 18824b58 2008-08-03 rsc if(strcmp(name, "ctl") == 0){
1221 18824b58 2008-08-03 rsc sf->type = Qimagectl;
1222 18824b58 2008-08-03 rsc break;
1223 18824b58 2008-08-03 rsc }
1224 18824b58 2008-08-03 rsc if(strcmp(name, "url") == 0){
1225 18824b58 2008-08-03 rsc sf->type = Qimageurl;
1226 18824b58 2008-08-03 rsc break;
1227 18824b58 2008-08-03 rsc }
1228 18824b58 2008-08-03 rsc if(strcmp(name, "settings") == 0){
1229 18824b58 2008-08-03 rsc sf->type = Qimagesettings;
1230 18824b58 2008-08-03 rsc break;
1231 18824b58 2008-08-03 rsc }
1232 18824b58 2008-08-03 rsc if(strcmp(name, "exif") == 0){
1233 18824b58 2008-08-03 rsc sf->type = Qimageexif;
1234 18824b58 2008-08-03 rsc break;
1235 18824b58 2008-08-03 rsc }
1236 18824b58 2008-08-03 rsc x = imagename(sf);
1237 18824b58 2008-08-03 rsc if(x && strcmp(name, x) == 0){
1238 18824b58 2008-08-03 rsc free(x);
1239 18824b58 2008-08-03 rsc sf->type = Qimagefile;
1240 18824b58 2008-08-03 rsc break;
1241 18824b58 2008-08-03 rsc }
1242 18824b58 2008-08-03 rsc free(x);
1243 18824b58 2008-08-03 rsc goto NotFound;
1244 18824b58 2008-08-03 rsc }
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;
1248 18824b58 2008-08-03 rsc }
1249 18824b58 2008-08-03 rsc
1250 18824b58 2008-08-03 rsc static int
1251 18824b58 2008-08-03 rsc dodirgen(int i, Dir *d, void *v)
1252 18824b58 2008-08-03 rsc {
1253 18824b58 2008-08-03 rsc SmugFid *sf, xsf;
1254 18824b58 2008-08-03 rsc char *key;
1255 18824b58 2008-08-03 rsc vlong id;
1256 18824b58 2008-08-03 rsc Upload *u;
1257 18824b58 2008-08-03 rsc
1258 18824b58 2008-08-03 rsc sf = v;
1259 18824b58 2008-08-03 rsc xsf = *sf;
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);
1263 18824b58 2008-08-03 rsc return 0;
1264 18824b58 2008-08-03 rsc }
1265 18824b58 2008-08-03 rsc
1266 18824b58 2008-08-03 rsc switch(sf->type){
1267 18824b58 2008-08-03 rsc default:
1268 18824b58 2008-08-03 rsc return -1;
1269 18824b58 2008-08-03 rsc
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);
1274 18824b58 2008-08-03 rsc return 0;
1275 18824b58 2008-08-03 rsc }
1276 18824b58 2008-08-03 rsc if(i < 0 || i >= nnick)
1277 18824b58 2008-08-03 rsc return -1;
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);
1281 18824b58 2008-08-03 rsc return 0;
1282 fa325e9b 2020-01-10 cross
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);
1287 18824b58 2008-08-03 rsc return 0;
1288 18824b58 2008-08-03 rsc }
1289 18824b58 2008-08-03 rsc if((id = getcategoryindex(sf, i)) < 0)
1290 18824b58 2008-08-03 rsc return -1;
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);
1294 18824b58 2008-08-03 rsc return 0;
1295 fa325e9b 2020-01-10 cross
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)
1299 18824b58 2008-08-03 rsc return -1;
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);
1304 18824b58 2008-08-03 rsc free(key);
1305 18824b58 2008-08-03 rsc return 0;
1306 fa325e9b 2020-01-10 cross
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);
1311 18824b58 2008-08-03 rsc return 0;
1312 18824b58 2008-08-03 rsc }
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);
1318 18824b58 2008-08-03 rsc return 0;
1319 18824b58 2008-08-03 rsc }
1320 18824b58 2008-08-03 rsc if((id = getimageindex(sf, i, &key)) < 0)
1321 18824b58 2008-08-03 rsc return -1;
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);
1326 18824b58 2008-08-03 rsc free(key);
1327 18824b58 2008-08-03 rsc return 0;
1328 fa325e9b 2020-01-10 cross
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);
1333 18824b58 2008-08-03 rsc return 0;
1334 18824b58 2008-08-03 rsc }
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);
1338 18824b58 2008-08-03 rsc return 0;
1339 18824b58 2008-08-03 rsc }
1340 18824b58 2008-08-03 rsc if(i-- == 0){
1341 18824b58 2008-08-03 rsc xsf.type = Qimagesettings;
1342 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1343 18824b58 2008-08-03 rsc return 0;
1344 18824b58 2008-08-03 rsc }
1345 18824b58 2008-08-03 rsc if(i-- == 0){
1346 18824b58 2008-08-03 rsc xsf.type = Qimageurl;
1347 18824b58 2008-08-03 rsc dostat(&xsf, nil, d);
1348 18824b58 2008-08-03 rsc return 0;
1349 18824b58 2008-08-03 rsc }
1350 18824b58 2008-08-03 rsc return -1;
1351 18824b58 2008-08-03 rsc }
1352 18824b58 2008-08-03 rsc }
1353 18824b58 2008-08-03 rsc
1354 18824b58 2008-08-03 rsc static void
1355 18824b58 2008-08-03 rsc xstat(Req *r)
1356 18824b58 2008-08-03 rsc {
1357 18824b58 2008-08-03 rsc dostat(r->fid->aux, nil, &r->d);
1358 18824b58 2008-08-03 rsc respond(r, nil);
1359 18824b58 2008-08-03 rsc }
1360 18824b58 2008-08-03 rsc
1361 18824b58 2008-08-03 rsc static void
1362 18824b58 2008-08-03 rsc xwstat(Req *r)
1363 18824b58 2008-08-03 rsc {
1364 18824b58 2008-08-03 rsc SmugFid *sf;
1365 18824b58 2008-08-03 rsc Json *v;
1366 18824b58 2008-08-03 rsc char *s;
1367 18824b58 2008-08-03 rsc char strid[50];
1368 18824b58 2008-08-03 rsc
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");
1373 18824b58 2008-08-03 rsc return;
1374 18824b58 2008-08-03 rsc }
1375 18824b58 2008-08-03 rsc if(r->d.name[0]){
1376 18824b58 2008-08-03 rsc switch(sf->type){
1377 18824b58 2008-08-03 rsc default:
1378 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1379 18824b58 2008-08-03 rsc return;
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);
1387 18824b58 2008-08-03 rsc else
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);
1391 18824b58 2008-08-03 rsc free(s);
1392 18824b58 2008-08-03 rsc jcacheflush("smugmug.albums.get&");
1393 18824b58 2008-08-03 rsc return;
1394 18824b58 2008-08-03 rsc }
1395 18824b58 2008-08-03 rsc }
1396 18824b58 2008-08-03 rsc respond(r, "invalid wstat");
1397 fa325e9b 2020-01-10 cross }
1398 18824b58 2008-08-03 rsc
1399 18824b58 2008-08-03 rsc static void
1400 18824b58 2008-08-03 rsc xattach(Req *r)
1401 18824b58 2008-08-03 rsc {
1402 18824b58 2008-08-03 rsc SmugFid *sf;
1403 fa325e9b 2020-01-10 cross
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);
1410 18824b58 2008-08-03 rsc }
1411 18824b58 2008-08-03 rsc
1412 18824b58 2008-08-03 rsc void
1413 18824b58 2008-08-03 rsc xopen(Req *r)
1414 18824b58 2008-08-03 rsc {
1415 18824b58 2008-08-03 rsc SmugFid *sf;
1416 18824b58 2008-08-03 rsc
1417 18824b58 2008-08-03 rsc if((r->ifcall.mode&~OTRUNC) > 2){
1418 18824b58 2008-08-03 rsc respond(r, "permission denied");
1419 18824b58 2008-08-03 rsc return;
1420 18824b58 2008-08-03 rsc }
1421 18824b58 2008-08-03 rsc
1422 18824b58 2008-08-03 rsc sf = r->fid->aux;
1423 18824b58 2008-08-03 rsc switch(sf->type){
1424 18824b58 2008-08-03 rsc case Qctl:
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:
1432 18824b58 2008-08-03 rsc break;
1433 fa325e9b 2020-01-10 cross
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");
1440 18824b58 2008-08-03 rsc return;
1441 18824b58 2008-08-03 rsc }
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);
1445 18824b58 2008-08-03 rsc }
1446 18824b58 2008-08-03 rsc break;
1447 fa325e9b 2020-01-10 cross
1448 18824b58 2008-08-03 rsc default:
1449 18824b58 2008-08-03 rsc if(r->ifcall.mode != OREAD){
1450 18824b58 2008-08-03 rsc respond(r, "permission denied");
1451 18824b58 2008-08-03 rsc return;
1452 18824b58 2008-08-03 rsc }
1453 18824b58 2008-08-03 rsc break;
1454 18824b58 2008-08-03 rsc }
1455 18824b58 2008-08-03 rsc
1456 18824b58 2008-08-03 rsc r->ofcall.qid = r->fid->qid;
1457 18824b58 2008-08-03 rsc respond(r, nil);
1458 18824b58 2008-08-03 rsc }
1459 18824b58 2008-08-03 rsc
1460 18824b58 2008-08-03 rsc void
1461 18824b58 2008-08-03 rsc xcreate(Req *r)
1462 18824b58 2008-08-03 rsc {
1463 18824b58 2008-08-03 rsc SmugFid *sf;
1464 18824b58 2008-08-03 rsc Json *v;
1465 18824b58 2008-08-03 rsc vlong id;
1466 18824b58 2008-08-03 rsc char strid[50], *key;
1467 18824b58 2008-08-03 rsc Upload *u;
1468 18824b58 2008-08-03 rsc
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))
1474 18824b58 2008-08-03 rsc break;
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);
1479 18824b58 2008-08-03 rsc return;
1480 18824b58 2008-08-03 rsc }
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);
1484 18824b58 2008-08-03 rsc jclose(v);
1485 18824b58 2008-08-03 rsc responderrstr(r);
1486 18824b58 2008-08-03 rsc return;
1487 18824b58 2008-08-03 rsc }
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);
1494 18824b58 2008-08-03 rsc return;
1495 fa325e9b 2020-01-10 cross
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))
1499 18824b58 2008-08-03 rsc break;
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",
1508 18824b58 2008-08-03 rsc nil);
1509 18824b58 2008-08-03 rsc if(v == nil){
1510 18824b58 2008-08-03 rsc responderrstr(r);
1511 18824b58 2008-08-03 rsc return;
1512 18824b58 2008-08-03 rsc }
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);
1517 18824b58 2008-08-03 rsc jclose(v);
1518 18824b58 2008-08-03 rsc responderrstr(r);
1519 18824b58 2008-08-03 rsc return;
1520 18824b58 2008-08-03 rsc }
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);
1524 18824b58 2008-08-03 rsc jclose(v);
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);
1528 18824b58 2008-08-03 rsc return;
1529 fa325e9b 2020-01-10 cross
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)
1533 18824b58 2008-08-03 rsc break;
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);
1537 18824b58 2008-08-03 rsc return;
1538 18824b58 2008-08-03 rsc }
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);
1544 18824b58 2008-08-03 rsc return;
1545 18824b58 2008-08-03 rsc }
1546 fa325e9b 2020-01-10 cross respond(r, "permission denied");
1547 18824b58 2008-08-03 rsc }
1548 18824b58 2008-08-03 rsc
1549 18824b58 2008-08-03 rsc static int
1550 18824b58 2008-08-03 rsc writetofd(Req *r, int fd)
1551 18824b58 2008-08-03 rsc {
1552 18824b58 2008-08-03 rsc int total, n;
1553 fa325e9b 2020-01-10 cross
1554 18824b58 2008-08-03 rsc total = 0;
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);
1557 18824b58 2008-08-03 rsc if(n <= 0)
1558 18824b58 2008-08-03 rsc return -1;
1559 18824b58 2008-08-03 rsc total += n;
1560 18824b58 2008-08-03 rsc }
1561 18824b58 2008-08-03 rsc r->ofcall.count = r->ifcall.count;
1562 18824b58 2008-08-03 rsc return 0;
1563 18824b58 2008-08-03 rsc }
1564 18824b58 2008-08-03 rsc
1565 18824b58 2008-08-03 rsc static void
1566 18824b58 2008-08-03 rsc readfromfd(Req *r, int fd)
1567 18824b58 2008-08-03 rsc {
1568 18824b58 2008-08-03 rsc int n;
1569 18824b58 2008-08-03 rsc n = pread(fd, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
1570 18824b58 2008-08-03 rsc if(n < 0)
1571 18824b58 2008-08-03 rsc n = 0;
1572 18824b58 2008-08-03 rsc r->ofcall.count = n;
1573 18824b58 2008-08-03 rsc }
1574 18824b58 2008-08-03 rsc
1575 18824b58 2008-08-03 rsc void
1576 18824b58 2008-08-03 rsc xread(Req *r)
1577 18824b58 2008-08-03 rsc {
1578 18824b58 2008-08-03 rsc SmugFid *sf;
1579 18824b58 2008-08-03 rsc char *data;
1580 18824b58 2008-08-03 rsc int fd;
1581 18824b58 2008-08-03 rsc HTTPHeader hdr;
1582 18824b58 2008-08-03 rsc char *url;
1583 fa325e9b 2020-01-10 cross
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){
1587 18824b58 2008-08-03 rsc default:
1588 18824b58 2008-08-03 rsc respond(r, "not implemented");
1589 18824b58 2008-08-03 rsc return;
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);
1597 18824b58 2008-08-03 rsc break;
1598 18824b58 2008-08-03 rsc case Qrpclog:
1599 18824b58 2008-08-03 rsc rpclogread(r);
1600 18824b58 2008-08-03 rsc return;
1601 18824b58 2008-08-03 rsc case Qctl:
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);
1615 18824b58 2008-08-03 rsc break;
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){
1619 18824b58 2008-08-03 rsc free(url);
1620 18824b58 2008-08-03 rsc responderrstr(r);
1621 18824b58 2008-08-03 rsc return;
1622 18824b58 2008-08-03 rsc }
1623 18824b58 2008-08-03 rsc readfromfd(r, fd);
1624 18824b58 2008-08-03 rsc free(url);
1625 18824b58 2008-08-03 rsc close(fd);
1626 18824b58 2008-08-03 rsc break;
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);
1630 18824b58 2008-08-03 rsc break;
1631 18824b58 2008-08-03 rsc }
1632 18824b58 2008-08-03 rsc respond(r, nil);
1633 18824b58 2008-08-03 rsc }
1634 18824b58 2008-08-03 rsc
1635 18824b58 2008-08-03 rsc void
1636 18824b58 2008-08-03 rsc xwrite(Req *r)
1637 18824b58 2008-08-03 rsc {
1638 18824b58 2008-08-03 rsc int sync;
1639 18824b58 2008-08-03 rsc char *s, *t, *p;
1640 18824b58 2008-08-03 rsc Json *v;
1641 18824b58 2008-08-03 rsc char strid[50];
1642 18824b58 2008-08-03 rsc SmugFid *sf;
1643 fa325e9b 2020-01-10 cross
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){
1648 18824b58 2008-08-03 rsc case Qctl:
1649 18824b58 2008-08-03 rsc if(sync){
1650 18824b58 2008-08-03 rsc jcacheflush(nil);
1651 18824b58 2008-08-03 rsc respond(r, nil);
1652 18824b58 2008-08-03 rsc return;
1653 18824b58 2008-08-03 rsc }
1654 18824b58 2008-08-03 rsc break;
1655 18824b58 2008-08-03 rsc case Qnickctl:
1656 18824b58 2008-08-03 rsc if(sync){
1657 18824b58 2008-08-03 rsc s = smprint("&NickName=%s&", nickname(sf->nickid));
1658 18824b58 2008-08-03 rsc jcacheflush(s);
1659 18824b58 2008-08-03 rsc free(s);
1660 18824b58 2008-08-03 rsc respond(r, nil);
1661 18824b58 2008-08-03 rsc return;
1662 18824b58 2008-08-03 rsc }
1663 fa325e9b 2020-01-10 cross break;
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");
1667 18824b58 2008-08-03 rsc break;
1668 18824b58 2008-08-03 rsc case Qalbumctl:
1669 18824b58 2008-08-03 rsc if(sync){
1670 18824b58 2008-08-03 rsc s = smprint("&AlbumID=%lld&", sf->album);
1671 18824b58 2008-08-03 rsc jcacheflush(s);
1672 18824b58 2008-08-03 rsc free(s);
1673 18824b58 2008-08-03 rsc respond(r, nil);
1674 18824b58 2008-08-03 rsc return;
1675 18824b58 2008-08-03 rsc }
1676 18824b58 2008-08-03 rsc break;
1677 18824b58 2008-08-03 rsc case Qimagectl:
1678 18824b58 2008-08-03 rsc if(sync){
1679 18824b58 2008-08-03 rsc s = smprint("&ImageID=%lld&", sf->image);
1680 18824b58 2008-08-03 rsc jcacheflush(s);
1681 18824b58 2008-08-03 rsc free(s);
1682 18824b58 2008-08-03 rsc respond(r, nil);
1683 18824b58 2008-08-03 rsc return;
1684 18824b58 2008-08-03 rsc }
1685 18824b58 2008-08-03 rsc break;
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);
1690 18824b58 2008-08-03 rsc return;
1691 18824b58 2008-08-03 rsc }
1692 18824b58 2008-08-03 rsc respond(r, nil);
1693 18824b58 2008-08-03 rsc return;
1694 18824b58 2008-08-03 rsc }
1695 18824b58 2008-08-03 rsc break;
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)
1701 18824b58 2008-08-03 rsc t = "";
1702 18824b58 2008-08-03 rsc else{
1703 18824b58 2008-08-03 rsc *t++ = 0;
1704 18824b58 2008-08-03 rsc while(*t == ' ' || *t == '\r' || *t == '\t' || *t == '\n')
1705 18824b58 2008-08-03 rsc t++;
1706 18824b58 2008-08-03 rsc }
1707 18824b58 2008-08-03 rsc p = strchr(t, '\n');
1708 18824b58 2008-08-03 rsc if(p && p[1] == 0)
1709 18824b58 2008-08-03 rsc *p = 0;
1710 18824b58 2008-08-03 rsc else if(p){
1711 18824b58 2008-08-03 rsc respond(r, "newline in argument");
1712 18824b58 2008-08-03 rsc return;
1713 18824b58 2008-08-03 rsc }
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);
1722 18824b58 2008-08-03 rsc else
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);
1726 18824b58 2008-08-03 rsc free(s);
1727 18824b58 2008-08-03 rsc return;
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);
1734 18824b58 2008-08-03 rsc else
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);
1738 18824b58 2008-08-03 rsc free(s);
1739 18824b58 2008-08-03 rsc return;
1740 18824b58 2008-08-03 rsc }
1741 18824b58 2008-08-03 rsc respond(r, "invalid control message");
1742 18824b58 2008-08-03 rsc return;
1743 fa325e9b 2020-01-10 cross }
1744 18824b58 2008-08-03 rsc
1745 18824b58 2008-08-03 rsc void
1746 18824b58 2008-08-03 rsc xremove(Req *r)
1747 18824b58 2008-08-03 rsc {
1748 18824b58 2008-08-03 rsc char id[100];
1749 18824b58 2008-08-03 rsc SmugFid *sf;
1750 18824b58 2008-08-03 rsc Json *v;
1751 18824b58 2008-08-03 rsc
1752 18824b58 2008-08-03 rsc sf = r->fid->aux;
1753 18824b58 2008-08-03 rsc switch(sf->type){
1754 18824b58 2008-08-03 rsc default:
1755 18824b58 2008-08-03 rsc respond(r, "permission denied");
1756 18824b58 2008-08-03 rsc return;
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);
1768 18824b58 2008-08-03 rsc return;
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");
1773 18824b58 2008-08-03 rsc return;
1774 18824b58 2008-08-03 rsc }
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);
1780 18824b58 2008-08-03 rsc else{
1781 18824b58 2008-08-03 rsc jclose(v);
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);
1785 18824b58 2008-08-03 rsc }
1786 18824b58 2008-08-03 rsc return;
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");
1791 18824b58 2008-08-03 rsc return;
1792 18824b58 2008-08-03 rsc }
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);
1798 18824b58 2008-08-03 rsc else{
1799 18824b58 2008-08-03 rsc jclose(v);
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);
1804 18824b58 2008-08-03 rsc }
1805 18824b58 2008-08-03 rsc return;
1806 fa325e9b 2020-01-10 cross
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);
1813 18824b58 2008-08-03 rsc else{
1814 18824b58 2008-08-03 rsc jclose(v);
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);
1819 18824b58 2008-08-03 rsc }
1820 18824b58 2008-08-03 rsc return;
1821 18824b58 2008-08-03 rsc }
1822 18824b58 2008-08-03 rsc }
1823 18824b58 2008-08-03 rsc
1824 18824b58 2008-08-03 rsc void
1825 18824b58 2008-08-03 rsc xflush(Req *r)
1826 18824b58 2008-08-03 rsc {
1827 18824b58 2008-08-03 rsc rpclogflush(r->oldreq);
1828 18824b58 2008-08-03 rsc respond(r, nil);
1829 18824b58 2008-08-03 rsc }
1830 18824b58 2008-08-03 rsc
1831 18824b58 2008-08-03 rsc Srv xsrv;
1832 18824b58 2008-08-03 rsc
1833 18824b58 2008-08-03 rsc void
1834 18824b58 2008-08-03 rsc xinit(void)
1835 fa325e9b 2020-01-10 cross {
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;
1848 18824b58 2008-08-03 rsc }