groupdav_get.c

00001 /*
00002  * $Id: groupdav_get.c 5147 2007-05-08 15:36:22Z ajc $
00003  *
00004  * Handles GroupDAV GET requests.
00005  *
00006  */
00007 
00008 #include "webcit.h"
00009 #include "webserver.h"
00010 #include "groupdav.h"
00011 #include "mime_parser.h"
00012 
00013 
00014 /*
00015  * Fetch the entire contents of the room as one big ics file.
00016  * This is for "webcal://" type access.
00017  */     
00018 void groupdav_get_big_ics(void) {
00019         char buf[1024];
00020 
00021         serv_puts("ICAL getics");
00022         serv_getln(buf, sizeof buf);
00023         if (buf[0] != '1') {
00024                 wprintf("HTTP/1.1 404 not found\r\n");
00025                 groupdav_common_headers();
00026                 wprintf(
00027                         "Content-Type: text/plain\r\n"
00028                         "\r\n"
00029                         "%s\r\n",
00030                         &buf[4]
00031                 );
00032                 return;
00033         }
00034 
00035         wprintf("HTTP/1.1 200 OK\r\n");
00036         groupdav_common_headers();
00037         wprintf("Content-type: text/calendar; charset=UTF-8\r\n");
00038         begin_burst();
00039         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
00040                 wprintf("%s\r\n", buf);
00041         }
00042         end_burst();
00043 }
00044 
00045 
00046 /* 
00047  * MIME parser callback function for groupdav_get()
00048  * Helps identify the relevant section of a multipart message
00049  */
00050 void extract_preferred(char *name, char *filename, char *partnum, char *disp,
00051                         void *content, char *cbtype, char *cbcharset,
00052                         size_t length, char *encoding, void *userdata)
00053 {
00054         struct epdata *epdata = (struct epdata *)userdata;
00055         int hit = 0;
00056 
00057         /* We only want the first one that we found */
00058         if (strlen(epdata->found_section) > 0) return;
00059 
00060         /* Check for a content type match */
00061         if (strlen(epdata->desired_content_type_1) > 0) {
00062                 if (!strcasecmp(epdata->desired_content_type_1, cbtype)) {
00063                         hit = 1;
00064                 }
00065         }
00066         if (strlen(epdata->desired_content_type_2) > 0) {
00067                 if (!strcasecmp(epdata->desired_content_type_2, cbtype)) {
00068                         hit = 1;
00069                 }
00070         }
00071 
00072         /* Is this the one?  If so, output it. */
00073         if (hit) {
00074                 safestrncpy(epdata->found_section, partnum, sizeof epdata->found_section);
00075                 if (strlen(cbcharset) > 0) {
00076                         safestrncpy(epdata->charset, cbcharset, sizeof epdata->charset);
00077                 }
00078                 wprintf("Content-type: %s; charset=%s\r\n", cbtype, epdata->charset);
00079                 begin_burst();
00080                 client_write(content, length);
00081                 end_burst();
00082         }
00083 }
00084 
00085 
00086 
00087 /*
00088  * The pathname is always going to take one of two formats:
00089  * /groupdav/room_name/euid     (GroupDAV)
00090  * /groupdav/room_name          (webcal)
00091  */
00092 void groupdav_get(char *dav_pathname) {
00093         char dav_roomname[1024];
00094         char dav_uid[1024];
00095         long dav_msgnum = (-1);
00096         char buf[1024];
00097         int in_body = 0;
00098         int found_content_type = 0;
00099         char *ptr;
00100         char *endptr;
00101         char *msgtext = NULL;
00102         size_t msglen = 0;
00103         size_t msgalloc = 0;
00104         int linelen;
00105         char content_type[128];
00106         char charset[128];
00107         char date[128];
00108         struct epdata epdata;
00109 
00110         if (num_tokens(dav_pathname, '/') < 3) {
00111                 wprintf("HTTP/1.1 404 not found\r\n");
00112                 groupdav_common_headers();
00113                 wprintf(
00114                         "Content-Type: text/plain\r\n"
00115                         "\r\n"
00116                         "The object you requested was not found.\r\n"
00117                 );
00118                 return;
00119         }
00120 
00121         extract_token(dav_roomname, dav_pathname, 2, '/', sizeof dav_roomname);
00122         extract_token(dav_uid, dav_pathname, 3, '/', sizeof dav_uid);
00123         if ((!strcasecmp(dav_uid, "ics")) || (!strcasecmp(dav_uid, "calendar.ics"))) {
00124                 strcpy(dav_uid, "");
00125         }
00126 
00127         /* Go to the correct room. */
00128         if (strcasecmp(WC->wc_roomname, dav_roomname)) {
00129                 gotoroom(dav_roomname);
00130         }
00131         if (strcasecmp(WC->wc_roomname, dav_roomname)) {
00132                 wprintf("HTTP/1.1 404 not found\r\n");
00133                 groupdav_common_headers();
00134                 wprintf(
00135                         "Content-Type: text/plain\r\n"
00136                         "\r\n"
00137                         "There is no folder called \"%s\" on this server.\r\n",
00138                         dav_roomname
00139                 );
00140                 return;
00141         }
00142 
00145         if (!strcasecmp(dav_uid, "")) {
00146                 groupdav_get_big_ics();
00147                 return;
00148         }
00149 
00150         dav_msgnum = locate_message_by_uid(dav_uid);
00151         serv_printf("MSG2 %ld", dav_msgnum);
00152         serv_getln(buf, sizeof buf);
00153         if (buf[0] != '1') {
00154                 wprintf("HTTP/1.1 404 not found\r\n");
00155                 groupdav_common_headers();
00156                 wprintf(
00157                         "Content-Type: text/plain\r\n"
00158                         "\r\n"
00159                         "Object \"%s\" was not found in the \"%s\" folder.\r\n",
00160                         dav_uid,
00161                         dav_roomname
00162                 );
00163                 return;
00164         }
00165 
00166         /* We got it; a message is now arriving from the server.  Read it in. */
00167 
00168         in_body = 0;
00169         found_content_type = 0;
00170         strcpy(charset, "UTF-8");
00171         strcpy(content_type, "text/plain");
00172         strcpy(date, "");
00173         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
00174                 linelen = strlen(buf);
00175 
00176                 /* Append it to the buffer */
00177                 if ((msglen + linelen + 3) > msgalloc) {
00178                         msgalloc = ( (msgalloc > 0) ? (msgalloc * 2) : 1024 );
00179                         msgtext = realloc(msgtext, msgalloc);
00180                 }
00181                 strcpy(&msgtext[msglen], buf);
00182                 msglen += linelen;
00183                 strcpy(&msgtext[msglen], "\n");
00184                 msglen += 1;
00185 
00186                 /* Also learn some things about the message */
00187                 if (linelen == 0) {
00188                         in_body = 1;
00189                 }
00190                 if (!in_body) {
00191                         if (!strncasecmp(buf, "Date:", 5)) {
00192                                 safestrncpy(date, &buf[5], sizeof date);
00193                                 striplt(date);
00194                         }
00195                         if (!strncasecmp(buf, "Content-type:", 13)) {
00196                                 safestrncpy(content_type, &buf[13], sizeof content_type);
00197                                 striplt(content_type);
00198                                 ptr = bmstrcasestr(&buf[13], "charset=");
00199                                 if (ptr) {
00200                                         safestrncpy(charset, ptr+8, sizeof charset);
00201                                         striplt(charset);
00202                                         endptr = strchr(charset, ';');
00203                                         if (endptr != NULL) strcpy(endptr, "");
00204                                 }
00205                                 endptr = strchr(content_type, ';');
00206                                 if (endptr != NULL) strcpy(endptr, "");
00207                         }
00208                 }
00209         }
00210         msgtext[msglen] = 0;
00211 
00212         /* Output headers common to single or multi part messages */
00213 
00214         wprintf("HTTP/1.1 200 OK\r\n");
00215         groupdav_common_headers();
00216         wprintf("etag: \"%ld\"\r\n", dav_msgnum);
00217         wprintf("Date: %s\r\n", date);
00218 
00219         memset(&epdata, 0, sizeof(struct epdata));
00220         safestrncpy(epdata.charset, charset, sizeof epdata.charset);
00221 
00222         /* If we have a multipart message on our hands, and we are in a groupware room,
00223          * strip it down to only the relevant part.
00224          */
00225         if (!strncasecmp(content_type, "multipart/", 10)) {
00226 
00227                 if ( (WC->wc_default_view == VIEW_CALENDAR) || (WC->wc_default_view == VIEW_TASKS) ) {
00228                         strcpy(epdata.desired_content_type_1, "text/calendar");
00229                 }
00230 
00231                 else if (WC->wc_default_view == VIEW_ADDRESSBOOK) {
00232                         strcpy(epdata.desired_content_type_1, "text/vcard");
00233                         strcpy(epdata.desired_content_type_2, "text/x-vcard");
00234                 }
00235 
00236                 mime_parser(msgtext, &msgtext[msglen], extract_preferred, NULL, NULL, (void *)&epdata, 0);
00237         }
00238 
00239         /* If epdata.found_section is empty, we haven't output anything yet, so output the whole thing */
00240 
00241         if (strlen(epdata.found_section) == 0) {
00242                 ptr = msgtext;
00243                 endptr = &msgtext[msglen];
00244         
00245                 wprintf("Content-type: %s; charset=%s\r\n", content_type, charset);
00246         
00247                 in_body = 0;
00248                 do {
00249                         ptr = memreadline(ptr, buf, sizeof buf);
00250         
00251                         if (in_body) {
00252                                 wprintf("%s\r\n", buf);
00253                         }
00254                         else if ((buf[0] == 0) && (in_body == 0)) {
00255                                 in_body = 1;
00256                                 begin_burst();
00257                         }
00258                 } while (ptr < endptr);
00259         
00260                 end_burst();
00261         }
00262 
00263         free(msgtext);
00264 }

Generated on Wed Jun 20 23:13:08 2007 for webcit by  doxygen 1.5.2