+const folder *GetRESTFolder(int IgnoreFloor, HashList *Subfolders)
+{
+ wcsession *WCC = WC;
+ void *vFolder;
+ const folder *ThisFolder = NULL;
+ const folder *FoundFolder = NULL;
+ const folder *BestGuess = NULL;
+ int nBestGuess = 0;
+ HashPos *itd, *itfl;
+ StrBuf * Dir;
+ void *vDir;
+ long len;
+ const char *Key;
+ int iRoom, jURL, urlp;
+ int delta;
+
+/*
+ * Guess room: if the full URL matches a room, list thats it. We also need to remember direct sub rooms.
+ * if the URL is longer, we need to find the "best guess" so we can find the room we're in, and the rest of the URL will be uids and so on.
+ */
+ itfl = GetNewHashPos(WCC->Floors, 0);
+ urlp = GetCount(WCC->Directory);
+
+ while (GetNextHashPos(WCC->Floors, itfl, &len, &Key, &vFolder) &&
+ (ThisFolder == NULL))
+ {
+ ThisFolder = vFolder;
+ if (!IgnoreFloor && /* so we can handle legacy URLS... */
+ (ThisFolder->Floor != WCC->CurrentFloor))
+ continue;
+
+
+ if (ThisFolder->nRoomNameParts > 1)
+ {
+ /*TODO: is that number all right? */
+// if (urlp - ThisFolder->nRoomNameParts != 2) {
+// if (BestGuess != NULL)
+// 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?
+
+ for (iRoom = 0, /* Fast forward the floorname as we checked it above: */ jURL = IgnoreFloor;
+
+ (iRoom <= ThisFolder->nRoomNameParts) && (jURL <= urlp);
+
+ iRoom++, jURL++, GetNextHashPos(WCC->Directory, itd, &len, &Key, &vDir))
+ {
+ Dir = (StrBuf*)vDir;
+ if (strcmp(ChrPtr(ThisFolder->RoomNameParts[iRoom]),
+ ChrPtr(Dir)) != 0)
+ {
+ DeleteHashPos(&itd);
+ continue;
+ }
+ }
+ DeleteHashPos(&itd);
+ /* Gotcha? */
+ if ((iRoom == ThisFolder->nRoomNameParts) && (jURL == urlp))
+ {
+ FoundFolder = ThisFolder;
+ }
+ /* URL got more parts then this room, so we remember it for the best guess*/
+ else if ((jURL <= urlp) &&
+ (ThisFolder->nRoomNameParts <= nBestGuess))
+ {
+ BestGuess = ThisFolder;
+ nBestGuess = jURL - 1;
+ }
+ /* 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),
+ /* Cast away const, its a reference. */
+ (void*)ThisFolder, reference_free_handler);
+ }
+ }
+ else {
+ delta = GetCount(WCC->Directory) - ThisFolder->nRoomNameParts;
+ if ((delta != 2) && (nBestGuess > 1))
+ continue;
+
+ itd = GetNewHashPos(WCC->Directory, 0);
+
+ if (!GetNextHashPos(WCC->Directory,
+ itd, &len, &Key, &vDir) ||
+ (vDir == NULL))
+ {
+ DeleteHashPos(&itd);
+
+ syslog(0, "5\n");
+ continue;
+ }
+ DeleteHashPos(&itd);
+ Dir = (StrBuf*) vDir;
+ if (strcmp(ChrPtr(ThisFolder->name),
+ ChrPtr(Dir))
+ != 0)
+ {
+ DeleteHashPos(&itd);
+
+ syslog(0, "5\n");
+ continue;
+ }
+ DeleteHashPos(&itfl);
+ DeleteHashPos(&itd);
+ if (delta != 2) {
+ nBestGuess = 1;
+ BestGuess = ThisFolder;
+ }
+ else
+ FoundFolder = ThisFolder;
+ }
+ }
+
+/* TODO: Subfolders: remove patterns not matching the best guess or thisfolder */
+ DeleteHashPos(&itfl);
+ if (FoundFolder != NULL)
+ return FoundFolder;
+ else
+ return BestGuess;
+}
+
+
+
+
+long GotoRestRoom(HashList *SubRooms)
+{
+ int IgnoreFloor = 0; /* deprecated... */
+ wcsession *WCC = WC;
+ long Count;
+ long State;
+ const folder *ThisFolder;
+
+ State = REST_TOPLEVEL;
+
+ if (WCC->Hdr->HR.Handler != NULL)
+ State |= REST_IN_NAMESPACE;
+
+ Count = GetCount(WCC->Directory);
+
+ if (Count == 0) return State;
+
+ if (Count >= 1) State |=REST_IN_FLOOR;
+ if (Count == 1) 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)
+ {
+ IgnoreFloor = 0;
+ State |= REST_IN_FLOOR;
+
+ ThisFolder = GetRESTFolder(IgnoreFloor, SubRooms);
+ if (ThisFolder != NULL)
+ {
+ if (WCC->ThisRoom != NULL)
+ if (CompareRooms(WCC->ThisRoom, ThisFolder) != 0)
+ gotoroom(ThisFolder->name);
+ State |= REST_IN_ROOM;
+
+ }
+ 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;
+ }
+
+
+ }
+ return State;
+}
+
+
+
+/*
+ * List rooms (or "collections" in DAV terminology) which contain
+ * interesting groupware objects.
+ */
+void groupdav_collection_list(void)
+{
+ wcsession *WCC = WC;
+ char buf[256];
+ char roomname[256];