00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "webcit.h"
00019 #include "webserver.h"
00020 #include "groupdav.h"
00021
00022
00023
00024
00025
00026
00027
00028 long locate_message_by_uid(char *uid) {
00029 char buf[256];
00030 char decoded_uid[1024];
00031 long retval = (-1L);
00032
00033
00034 euid_unescapize(decoded_uid, uid);
00035
00036
00037 serv_printf("EUID %s", decoded_uid);
00038 serv_getln(buf, sizeof buf);
00039 if (buf[0] == '2') {
00040 retval = atol(&buf[4]);
00041 }
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 return(retval);
00057 }
00058
00059
00060
00061
00062
00063
00064
00065 void groupdav_collection_list(char *dav_pathname, int dav_depth)
00066 {
00067 char buf[256];
00068 char roomname[256];
00069 int view;
00070 char datestring[256];
00071 time_t now;
00072 time_t mtime;
00073 int is_groupware_collection = 0;
00074 int starting_point = 1;
00076 if (!strcmp(dav_pathname, "/")) {
00077 starting_point = 0;
00078 }
00079 else if (!strcasecmp(dav_pathname, "/groupdav")) {
00080 starting_point = 1;
00081 }
00082 else if (!strcasecmp(dav_pathname, "/groupdav/")) {
00083 starting_point = 1;
00084 }
00085 else if ( (!strncasecmp(dav_pathname, "/groupdav/", 10)) && (strlen(dav_pathname) > 10) ) {
00086 starting_point = 2;
00087 }
00088
00089 now = time(NULL);
00090 http_datestring(datestring, sizeof datestring, now);
00091
00096 wprintf("HTTP/1.0 207 Multi-Status\r\n");
00097 groupdav_common_headers();
00098 wprintf("Date: %s\r\n", datestring);
00099 wprintf("Content-type: text/xml\r\n");
00100 wprintf("Content-encoding: identity\r\n");
00101
00102 begin_burst();
00103
00104 wprintf("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
00105 "<multistatus xmlns=\"DAV:\" xmlns:G=\"http://groupdav.org/\">"
00106 );
00107
00111 if (starting_point == 0) {
00112 wprintf("<response>");
00113 wprintf("<href>");
00114 groupdav_identify_host();
00115 wprintf("/");
00116 wprintf("</href>");
00117 wprintf("<propstat>");
00118 wprintf("<status>HTTP/1.1 200 OK</status>");
00119 wprintf("<prop>");
00120 wprintf("<displayname>/</displayname>");
00121 wprintf("<resourcetype><collection/></resourcetype>");
00122 wprintf("<getlastmodified>");
00123 escputs(datestring);
00124 wprintf("</getlastmodified>");
00125 wprintf("</prop>");
00126 wprintf("</propstat>");
00127 wprintf("</response>");
00128 }
00129
00133 if ((starting_point + dav_depth) >= 1) {
00134 wprintf("<response>");
00135 wprintf("<href>");
00136 groupdav_identify_host();
00137 wprintf("/groupdav");
00138 wprintf("</href>");
00139 wprintf("<propstat>");
00140 wprintf("<status>HTTP/1.1 200 OK</status>");
00141 wprintf("<prop>");
00142 wprintf("<displayname>GroupDAV</displayname>");
00143 wprintf("<resourcetype><collection/></resourcetype>");
00144 wprintf("<getlastmodified>");
00145 escputs(datestring);
00146 wprintf("</getlastmodified>");
00147 wprintf("</prop>");
00148 wprintf("</propstat>");
00149 wprintf("</response>");
00150 }
00151
00155 serv_puts("LKRA");
00156 serv_getln(buf, sizeof buf);
00157 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
00158
00159 extract_token(roomname, buf, 0, '|', sizeof roomname);
00160 view = extract_int(buf, 7);
00161 mtime = extract_long(buf, 8);
00162 http_datestring(datestring, sizeof datestring, mtime);
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 if ((view == VIEW_CALENDAR) || (view == VIEW_TASKS) || (view == VIEW_ADDRESSBOOK) ) {
00176 is_groupware_collection = 1;
00177 }
00178 else {
00179 is_groupware_collection = 0;
00180 }
00181
00182 if ( (is_groupware_collection) && ((starting_point + dav_depth) >= 2) ) {
00183 wprintf("<response>");
00184
00185 wprintf("<href>");
00186 groupdav_identify_host();
00187 wprintf("/groupdav/");
00188 urlescputs(roomname);
00189 wprintf("/</href>");
00190
00191 wprintf("<propstat>");
00192 wprintf("<status>HTTP/1.1 200 OK</status>");
00193 wprintf("<prop>");
00194 wprintf("<displayname>");
00195 escputs(roomname);
00196 wprintf("</displayname>");
00197 wprintf("<resourcetype><collection/>");
00198
00199 switch(view) {
00200 case VIEW_CALENDAR:
00201 wprintf("<G:vevent-collection />");
00202 break;
00203 case VIEW_TASKS:
00204 wprintf("<G:vtodo-collection />");
00205 break;
00206 case VIEW_ADDRESSBOOK:
00207 wprintf("<G:vcard-collection />");
00208 break;
00209 }
00210
00211 wprintf("</resourcetype>");
00212 wprintf("<getlastmodified>");
00213 escputs(datestring);
00214 wprintf("</getlastmodified>");
00215 wprintf("</prop>");
00216 wprintf("</propstat>");
00217 wprintf("</response>");
00218 }
00219 }
00220 wprintf("</multistatus>\n");
00221
00222 end_burst();
00223 }
00224
00225
00226
00227
00228
00229
00230 void groupdav_propfind(char *dav_pathname, int dav_depth, char *dav_content_type, char *dav_content) {
00231 char dav_roomname[256];
00232 char dav_uid[256];
00233 char msgnum[256];
00234 long dav_msgnum = (-1);
00235 char buf[256];
00236 char uid[256];
00237 char encoded_uid[256];
00238 long *msgs = NULL;
00239 int num_msgs = 0;
00240 int i;
00241 char datestring[256];
00242 time_t now;
00243
00244 now = time(NULL);
00245 http_datestring(datestring, sizeof datestring, now);
00246
00247 extract_token(dav_roomname, dav_pathname, 2, '/', sizeof dav_roomname);
00248 extract_token(dav_uid, dav_pathname, 3, '/', sizeof dav_uid);
00249
00250
00251
00252
00253
00254 if (strlen(dav_roomname) == 0) {
00255 groupdav_collection_list(dav_pathname, dav_depth);
00256 return;
00257 }
00258
00259
00260 if (strcasecmp(WC->wc_roomname, dav_roomname)) {
00261 gotoroom(dav_roomname);
00262 }
00263 if (strcasecmp(WC->wc_roomname, dav_roomname)) {
00264 wprintf("HTTP/1.1 404 not found\r\n");
00265 groupdav_common_headers();
00266 wprintf("Date: %s\r\n", datestring);
00267 wprintf(
00268 "Content-Type: text/plain\r\n"
00269 "\r\n"
00270 "There is no folder called \"%s\" on this server.\r\n",
00271 dav_roomname
00272 );
00273 return;
00274 }
00275
00276
00277
00278
00279
00280 if (strlen(dav_uid) > 0) {
00281
00282 dav_msgnum = locate_message_by_uid(dav_uid);
00283 if (dav_msgnum < 0) {
00284 wprintf("HTTP/1.1 404 not found\r\n");
00285 groupdav_common_headers();
00286 wprintf(
00287 "Content-Type: text/plain\r\n"
00288 "\r\n"
00289 "Object \"%s\" was not found in the \"%s\" folder.\r\n",
00290 dav_uid,
00291 dav_roomname
00292 );
00293 return;
00294 }
00295
00296
00297
00298
00299
00300 wprintf("HTTP/1.0 207 Multi-Status\r\n");
00301 groupdav_common_headers();
00302 wprintf("Date: %s\r\n", datestring);
00303 wprintf("Content-type: text/xml\r\n");
00304 wprintf("Content-encoding: identity\r\n");
00305
00306 begin_burst();
00307
00308 wprintf("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
00309 "<multistatus xmlns=\"DAV:\">"
00310 );
00311
00312 wprintf("<response>");
00313
00314 wprintf("<href>");
00315 groupdav_identify_host();
00316 wprintf("/groupdav/");
00317 urlescputs(WC->wc_roomname);
00318 euid_escapize(encoded_uid, dav_uid);
00319 wprintf("/%s", encoded_uid);
00320 wprintf("</href>");
00321 wprintf("<propstat>");
00322 wprintf("<status>HTTP/1.1 200 OK</status>");
00323 wprintf("<prop><getetag>\"%ld\"</getetag></prop>", dav_msgnum);
00324 wprintf("</propstat>");
00325
00326 wprintf("</response>\n");
00327 wprintf("</multistatus>\n");
00328 end_burst();
00329 return;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 wprintf("HTTP/1.0 207 Multi-Status\r\n");
00342 groupdav_common_headers();
00343 wprintf("Date: %s\r\n", datestring);
00344 wprintf("Content-type: text/xml\r\n");
00345 wprintf("Content-encoding: identity\r\n");
00346
00347 begin_burst();
00348
00349 wprintf("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
00350 "<multistatus xmlns=\"DAV:\" xmlns:G=\"http://groupdav.org/\">"
00351 );
00352
00353
00355 wprintf("<response>");
00356
00357 wprintf("<href>");
00358 groupdav_identify_host();
00359 wprintf("/groupdav/");
00360 urlescputs(WC->wc_roomname);
00361 wprintf("</href>");
00362
00363 wprintf("<propstat>");
00364 wprintf("<status>HTTP/1.1 200 OK</status>");
00365 wprintf("<prop>");
00366 wprintf("<displayname>");
00367 escputs(WC->wc_roomname);
00368 wprintf("</displayname>");
00369 wprintf("<resourcetype><collection/>");
00370
00371 switch(WC->wc_default_view) {
00372 case VIEW_CALENDAR:
00373 wprintf("<G:vevent-collection />");
00374 break;
00375 case VIEW_TASKS:
00376 wprintf("<G:vtodo-collection />");
00377 break;
00378 case VIEW_ADDRESSBOOK:
00379 wprintf("<G:vcard-collection />");
00380 break;
00381 }
00382
00383 wprintf("</resourcetype>");
00384
00385
00386
00387
00388
00389 wprintf("</prop>");
00390 wprintf("</propstat>");
00391 wprintf("</response>");
00392
00395 serv_puts("MSGS ALL");
00396 serv_getln(buf, sizeof buf);
00397 if (buf[0] == '1') while (serv_getln(msgnum, sizeof msgnum), strcmp(msgnum, "000")) {
00398 msgs = realloc(msgs, ++num_msgs * sizeof(long));
00399 msgs[num_msgs-1] = atol(msgnum);
00400 }
00401
00402 if (num_msgs > 0) for (i=0; i<num_msgs; ++i) {
00403
00404 strcpy(uid, "");
00405 serv_printf("MSG0 %ld|3", msgs[i]);
00406 serv_getln(buf, sizeof buf);
00407 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
00408 if (!strncasecmp(buf, "exti=", 5)) {
00409 strcpy(uid, &buf[5]);
00410 }
00411 }
00412
00413 if (strlen(uid) > 0) {
00414 wprintf("<response>");
00415 wprintf("<href>");
00416 groupdav_identify_host();
00417 wprintf("/groupdav/");
00418 urlescputs(WC->wc_roomname);
00419 euid_escapize(encoded_uid, uid);
00420 wprintf("/%s", encoded_uid);
00421 wprintf("</href>");
00422 switch(WC->wc_default_view) {
00423 case VIEW_CALENDAR:
00424 wprintf("<getcontenttype>text/x-ical</getcontenttype>");
00425 break;
00426 case VIEW_TASKS:
00427 wprintf("<getcontenttype>text/x-ical</getcontenttype>");
00428 break;
00429 case VIEW_ADDRESSBOOK:
00430 wprintf("<getcontenttype>text/x-vcard</getcontenttype>");
00431 break;
00432 }
00433 wprintf("<propstat>");
00434 wprintf("<status>HTTP/1.1 200 OK</status>");
00435 wprintf("<prop>");
00436 wprintf("<getetag>\"%ld\"</getetag>", msgs[i]);
00437 wprintf("</prop>");
00438 wprintf("</propstat>");
00439 wprintf("</response>");
00440 }
00441 }
00442
00443 wprintf("</multistatus>\n");
00444 end_burst();
00445
00446 if (msgs != NULL) {
00447 free(msgs);
00448 }
00449 }