/*
- * $Id$
- *
* Handles GroupDAV PROPFIND requests.
*
* A few notes about our XML output:
* This makes it difficult to read, but we have discovered clients which
* crash when you try to pretty it up.
*
+ * Copyright (c) 2005-2010 by the citadel.org team
+ *
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "webcit.h"
#include "webserver.h"
#include "groupdav.h"
+extern int DisableGzip;
+
/*
* Given an encoded UID, translate that to an unencoded Citadel EUID and
* then search for it in the current room. Return a message number or -1
return(retval);
}
+
+/*
+ * IgnoreFloor: set to 0 or 1 _nothing else_
+ * Subfolders: direct child floors will be put here.
+ */
const folder *GetRESTFolder(int IgnoreFloor, HashList *Subfolders)
{
wcsession *WCC = WC;
if (ThisFolder->nRoomNameParts > 1)
{
/*TODO: is that number all right? */
- if (urlp - ThisFolder->nRoomNameParts != 2) {
+// if (urlp - ThisFolder->nRoomNameParts != 2) {
// if (BestGuess != NULL)
- continue;
+// continue;
//ThisFolder->name
// itd = GetNewHashPos(WCC->Directory, 0);
// GetNextHashPos(WCC->Directory, itd, &len, &Key, &vDir); //TODO: how many to fast forward?
- }
+// }
itd = GetNewHashPos(WCC->Directory, 0);
GetNextHashPos(WCC->Directory, itd, &len, &Key, &vDir); //TODO: how many to fast forward?
/* Room has more parts than the URL, it might be a sub-room? */
else if (iRoom <ThisFolder->nRoomNameParts)
{//// TODO: ThisFolder->nRoomNameParts == urlp - IgnoreFloor???
- Put(Subfolders, SKEY(ThisFolder->name), ThisFolder, reference_free_handler);
+ Put(Subfolders, SKEY(ThisFolder->name),
+ /* Cast away const, its a reference. */
+ (void*)ThisFolder, reference_free_handler);
}
}
else {
{
DeleteHashPos(&itd);
- lprintf(0, "5\n");
+ syslog(0, "5\n");
continue;
}
DeleteHashPos(&itd);
{
DeleteHashPos(&itd);
- lprintf(0, "5\n");
+ syslog(0, "5\n");
continue;
}
DeleteHashPos(&itfl);
BestGuess = ThisFolder;
}
else
- FoundFolder = ThisFolder;;
+ FoundFolder = ThisFolder;
}
}
+
+/* TODO: Subfolders: remove patterns not matching the best guess or thisfolder */
DeleteHashPos(&itfl);
if (FoundFolder != NULL)
return FoundFolder;
-long GotoRestRoom()
+long GotoRestRoom(HashList *SubRooms)
{
+ int IgnoreFloor = 0; /* deprecated... */
wcsession *WCC = WC;
long Count;
long State;
const folder *ThisFolder;
- HashList *SubRooms = NULL;
State = REST_TOPLEVEL;
if (Count >= 1) State |=REST_IN_FLOOR;
if (Count == 1) return State;
- if (Count >= 3) {
- State |= REST_IN_FLOOR;
- SubRooms = NewHash(1, Flathash);
- ThisFolder = GetRESTFolder(0, SubRooms);
- WCC->ThisRoom = ThisFolder;
- if (ThisFolder != NULL)
- {
- gotoroom(ThisFolder->name);
- State |= REST_IN_ROOM;
- return State;
- }
-
- }
-
-
/*
* More than 3 params and no floor found?
* -> fall back to old non-floored notation
*/
-
if ((Count >= 3) && (WCC->CurrentFloor == NULL))
+ IgnoreFloor = 1;
+ if (Count >= 3)
{
- SubRooms = NewHash(1, Flathash);
- ThisFolder = GetRESTFolder(1, SubRooms);
- WCC->ThisRoom = ThisFolder;
+ IgnoreFloor = 0;
+ State |= REST_IN_FLOOR;
+
+ ThisFolder = GetRESTFolder(IgnoreFloor, SubRooms);
if (ThisFolder != NULL)
{
- gotoroom(ThisFolder->name);
+ if (WCC->ThisRoom != NULL)
+ if (CompareRooms(WCC->ThisRoom, ThisFolder) != 0)
+ gotoroom(ThisFolder->name);
State |= REST_IN_ROOM;
- return State;
+
}
-
-
+ if (GetCount(SubRooms) > 0)
+ State |= REST_HAVE_SUB_ROOMS;
}
+ if ((WCC->ThisRoom != NULL) &&
+ (Count + IgnoreFloor > 3))
+ {
+ if (WCC->Hdr->HR.Handler->RID(ExistsID, IgnoreFloor))
+ {
+ State |= REST_GOT_LOCAL_PART;
+ }
+ else {
+ /// WHOOPS, not there???
+ State |= REST_NONEXIST;
+ }
- if (Count == 3) return State;
-
- /// TODO: ID detection
- /// TODO: File detection
-
-
+ }
return State;
}
groupdav_common_headers();
hprintf("Date: %s\r\n", datestring);
hprintf("Content-type: text/xml\r\n");
- hprintf("Content-encoding: identity\r\n");
+ if (DisableGzip || (!WCC->Hdr->HR.gzip_ok))
+ hprintf("Content-encoding: identity\r\n");
begin_burst();
*/
void groupdav_propfind(void)
{
+#ifdef DEV_RESTDAV
+ HashList *SubRooms = NULL;
+ long State;
+#endif
wcsession *WCC = WC;
StrBuf *dav_roomname;
StrBuf *dav_uid;
int i;
char datestring[256];
time_t now;
- long State;
now = time(NULL);
http_datestring(datestring, sizeof datestring, now);
* If the room name is blank, the client is requesting a
* folder list.
*/
- State = GotoRestRoom();
+ SubRooms = NewHash(1, Flathash);
+ State = GotoRestRoom(SubRooms);
if (((State & REST_IN_ROOM) == 0) ||
- (((State & (REST_GOT_EUID|REST_GOT_ID|REST_GOT_FILENAME)) == 0) &&
+ (((State & (REST_GOT_LOCAL_PART)) == 0) &&
(WCC->Hdr->HR.dav_depth == 0)))
{
now = time(NULL);
groupdav_common_headers();
hprintf("Date: %s\r\n", datestring);
hprintf("Content-type: text/xml\r\n");
- hprintf("Content-encoding: identity\r\n");
+ if (DisableGzip || (!WCC->Hdr->HR.gzip_ok))
+ hprintf("Content-encoding: identity\r\n");
begin_burst();
end_burst();
FreeStrBuf(&dav_roomname);
FreeStrBuf(&dav_uid);
+ FreeHashList(&SubRooms);
return;
}
- if ((State & (REST_GOT_EUID|REST_GOT_ID|REST_GOT_FILENAME)) == 0) {
+ if ((State & (REST_GOT_LOCAL_PART)) == 0) {
readloop(headers, eReadEUIDS);
+ FreeHashList(&SubRooms);
return;
}
+
+
+
+ FreeHashList(&SubRooms);
+
#endif
/*
groupdav_common_headers();
hprintf("Date: %s\r\n", datestring);
hprintf("Content-type: text/xml\r\n");
- hprintf("Content-encoding: identity\r\n");
+ if (DisableGzip || (!WCC->Hdr->HR.gzip_ok))
+ hprintf("Content-encoding: identity\r\n");
begin_burst();
groupdav_common_headers();
hprintf("Date: %s\r\n", datestring);
hprintf("Content-type: text/xml\r\n");
- hprintf("Content-encoding: identity\r\n");
+ if (DisableGzip || (!WCC->Hdr->HR.gzip_ok))
+ hprintf("Content-encoding: identity\r\n");
begin_burst();
StrBuf_ServGetln(MsgNum);
if (GetServerStatus(MsgNum, NULL) == 1)
- while (BufLen = StrBuf_ServGetln(MsgNum), strcmp(ChrPtr(MsgNum), "000")) {
+ while (BufLen = StrBuf_ServGetln(MsgNum),
+ ((BufLen >= 0) &&
+ ((BufLen != 3) || strcmp(ChrPtr(MsgNum), "000")) ))
+ {
msgs = realloc(msgs, ++num_msgs * sizeof(long));
msgs[num_msgs-1] = StrTol(MsgNum);
}
serv_printf("MSG0 %ld|3", msgs[i]);
StrBuf_ServGetln(MsgNum);
if (GetServerStatus(MsgNum, NULL) == 1)
- while (BufLen = StrBuf_ServGetln(MsgNum), strcmp(ChrPtr(MsgNum), "000"))
+ while (BufLen = StrBuf_ServGetln(MsgNum),
+ ((BufLen >= 0) &&
+ ((BufLen != 3) || strcmp(ChrPtr(MsgNum), "000")) ))
{
if (!strncasecmp(ChrPtr(MsgNum), "exti=", 5)) {
strcpy(uid, &ChrPtr(MsgNum)[5]);
{
Msg->euid = NewStrBuf();
StrBufExtract_NextToken(Msg->euid, Line, pos, '|');
+ Msg->date = StrBufExtractNext_long(Line, pos, '|');
+
return StrLength(Msg->euid) > 0;
}