/*
* $Id$
+ * Lots of different room-related operations.
*/
-/**
- * \defgroup RoomOps Lots of different room-related operations.
- * \ingroup CitadelCommunitacion
- */
-/*@{*/
+
#include "webcit.h"
char floorlist[128][SIZ]; /**< list of our floor names */
char *viewdefs[9]; /**< the different kinds of available views */
-/**
- * \brief initialize the viewdefs with localized strings
+/*
+ * Initialize the viewdefs with localized strings
*/
void initialize_viewdefs(void) {
viewdefs[0] = _("Bulletin Board");
viewdefs[8] = _("Journal");
}
-/**
- * \brief Determine which views are allowed as the default for creating a new room.
- *
- * \param which_view The view ID being queried.
+/*
+ * Determine which views are allowed as the default for creating a new room.
*/
int is_view_allowed_as_default(int which_view)
{
}
-/**
- * \brief load the list of floors
+/*
+ * load the list of floors
*/
void load_floorlist(void)
{
}
-/**
- * \brief Free a session's march list
- *
- * \param wcf Pointer to session being cleared
+/*
+ * Free a session's march list
*/
void free_march_list(struct wcsession *wcf)
{
-/**
- * \brief remove a room from the march list
+/*
+ * remove a room from the march list
*/
void remove_march(char *aaa)
{
-/**
- * \brief display rooms in tree structure???
- * \param rp the roomlist to build a tree from
+/*
+ * display rooms in tree structure
*/
void room_tree_list(struct roomlisting *rp)
{
"type=\"text\" name=\"query\" size=\"15\" maxlength=\"128\" "
"id=\"search_name\" class=\"inputbox\">\n"
);
- wprintf("</select></form>\n");
+ wprintf("</form>\n");
}
void embed_room_banner(char *got, int navbar_style) {
char buf[256];
+ char buf2[1024];
char sanitized_roomname[256];
-
+ char with_files[256];
+ int file_count=0;
+
/**
* We need to have the information returned by a GOTO server command.
* If it isn't supplied, we fake it by issuing our own GOTO.
WC->new_mail = extract_int(&got[4], 9);
WC->wc_view = extract_int(&got[4], 11);
+ /* Is this a directory room and does it contain files and how many? */
+ if ((WC->room_flags & QR_DIRECTORY) && (WC->room_flags & QR_VISDIR))
+ {
+ serv_puts("RDIR");
+ serv_getln(buf2, sizeof buf2);
+ if (buf2[0] == '1') while (serv_getln(buf2, sizeof buf2), strcmp(buf2, "000"))
+ file_count++;
+ snprintf (with_files, sizeof with_files,
+ "; <a href=\"display_room_directory\"> %d %s </a>",
+ file_count,
+ ((file_count>1) || (file_count == 0) ? _("files") : _("file")));
+ }
+ else
+ strcpy (with_files, "");
+
stresc(sanitized_roomname, 256, WC->wc_roomname, 1, 1);
svprintf("ROOMNAME", WCS_STRING, "%s", sanitized_roomname);
svprintf("NUMMSGS", WCS_STRING,
- _("%d new of %d messages"),
+ _("%d new of %d messages%s"),
extract_int(&got[4], 1),
- extract_int(&got[4], 2)
+ extract_int(&got[4], 2),
+ with_files
);
svcallback("ROOMPIC", embed_room_graphic);
svcallback("ROOMINFO", readinfo);
smart_goto(buf);
}
+typedef struct __room_states {
+ char password[SIZ];
+ char dirname[SIZ];
+ char name[SIZ];
+ int flags;
+ int floor;
+ int order;
+ int view;
+ int flags2;
+}room_states;
char name[SIZ];
char password[SIZ];
char dirname[SIZ];
- int flags, floor, order, view, flags2;
+ int flags, floor, order, view, flags2;
serv_puts("GETR");
serv_getln(buf, sizeof buf);
}
+int
+is_selflist(room_states *RoomFlags)
+{
+ return ((RoomFlags->flags2 & QR2_SELFLIST) != 0);
+}
+
+int
+is_publiclist(room_states *RoomFlags)
+{
+ return ((RoomFlags->flags2 & QR2_SMTP_PUBLIC) != 0);
+}
+
+int
+is_moderatedlist(room_states *RoomFlags)
+{
+ return ((RoomFlags->flags2 & QR2_MODERATED) != 0);
+}
+
+/**
+ * \brief Set/clear/read the "self-service list subscribe" flag for a room
+ *
+ * \param newval set to 0 to clear, 1 to set, any other value to leave unchanged.
+ * \return return the new value.
+ */
+
+int get_roomflags(room_states *RoomOps)
+{
+ char buf[SIZ];
+
+ serv_puts("GETR");
+ serv_getln(buf, sizeof buf);
+ if (buf[0] != '2') return(0);
+
+ extract_token(RoomOps->name, &buf[4], 0, '|', sizeof RoomOps->name);
+ extract_token(RoomOps->password, &buf[4], 1, '|', sizeof RoomOps->password);
+ extract_token(RoomOps->dirname, &buf[4], 2, '|', sizeof RoomOps->dirname);
+ RoomOps->flags = extract_int(&buf[4], 3);
+ RoomOps->floor = extract_int(&buf[4], 4);
+ RoomOps->order = extract_int(&buf[4], 5);
+ RoomOps->view = extract_int(&buf[4], 6);
+ RoomOps->flags2 = extract_int(&buf[4], 7);
+ return (1);
+}
+
+int set_roomflags(room_states *RoomOps)
+{
+ char buf[SIZ];
+
+ serv_printf("SETR %s|%s|%s|%d|0|%d|%d|%d|%d",
+ RoomOps->name,
+ RoomOps->password,
+ RoomOps->dirname,
+ RoomOps->flags,
+ RoomOps->floor,
+ RoomOps->order,
+ RoomOps->view,
+ RoomOps->flags2);
+ serv_getln(buf, sizeof buf);
+ return (1);
+}
+
int floorvalue = 0;
char pop3_host[128];
char pop3_user[32];
+ int bg = 0;
tab = bstr("tab");
if (IsEmptyStr(tab)) tab = "admin";
wprintf("<li>");
wprintf(_("Resides on floor: "));
- wprintf("<select NAME=\"er_floor\" SIZE=\"1\">\n");
+ wprintf("<select NAME=\"er_floor\" SIZE=\"1\"");
+ if (er_flags & QR_MAILBOX)
+ wprintf("disabled >\n");
for (i = 0; i < 128; ++i)
if (!IsEmptyStr(floorlist[i])) {
wprintf("<OPTION ");
- if (i == er_floor)
+ if (i == er_floor )
wprintf("SELECTED ");
wprintf("VALUE=\"%d\">", i);
escputs(floorlist[i]);
wprintf("</OPTION>\n");
}
wprintf("</select>\n");
-
+
wprintf("<li>");
wprintf(_("Type of room:"));
wprintf("<ul>\n");
wprintf("<li><input type=\"radio\" NAME=\"type\" VALUE=\"public\" ");
- if ((er_flags & QR_PRIVATE) == 0)
- wprintf("CHECKED ");
- wprintf("> ");
+ if ((er_flags & (QR_PRIVATE + QR_MAILBOX)) == 0)
+ wprintf("CHECKED ");
+ wprintf("OnChange=\""
+ " if (this.form.type[0].checked == true) { "
+ " this.form.er_floor.disabled = false; "
+ " } "
+ "\"> ");
wprintf(_("Public (automatically appears to everyone)"));
wprintf("\n");
if ((er_flags & QR_PRIVATE) &&
(er_flags & QR_GUESSNAME))
wprintf("CHECKED ");
- wprintf("> ");
+ wprintf(" OnChange=\""
+ " if (this.form.type[1].checked == true) { "
+ " this.form.er_floor.disabled = false; "
+ " } "
+ "\"> ");
wprintf(_("Private - hidden (accessible to anyone who knows its name)"));
wprintf("\n<li><input type=\"radio\" NAME=\"type\" VALUE=\"passworded\" ");
if ((er_flags & QR_PRIVATE) &&
(er_flags & QR_PASSWORDED))
wprintf("CHECKED ");
- wprintf("> ");
+ wprintf(" OnChange=\""
+ " if (this.form.type[2].checked == true) { "
+ " this.form.er_floor.disabled = false; "
+ " } "
+ "\"> ");
wprintf(_("Private - require password: "));
wprintf("\n<input type=\"text\" NAME=\"er_password\" VALUE=\"%s\" MAXLENGTH=\"9\">\n",
er_password);
&& ((er_flags & QR_GUESSNAME) == 0)
&& ((er_flags & QR_PASSWORDED) == 0))
wprintf("CHECKED ");
- wprintf("> ");
+ wprintf(" OnChange=\""
+ " if (this.form.type[3].checked == true) { "
+ " this.form.er_floor.disabled = false; "
+ " } "
+ "\"> ");
wprintf(_("Private - invitation only"));
+ wprintf("\n<li><input type=\"radio\" NAME=\"type\" VALUE=\"personal\" ");
+ if (er_flags & QR_MAILBOX)
+ wprintf("CHECKED ");
+ wprintf (" OnChange=\""
+ " if (this.form.type[4].checked == true) { "
+ " this.form.er_floor.disabled = true; "
+ " } "
+ "\"> ");
+ wprintf(_("Personal (mailbox for you only)"));
+
wprintf("\n<li><input type=\"checkbox\" NAME=\"bump\" VALUE=\"yes\" ");
wprintf("> ");
wprintf(_("If private, cause current users to forget room"));
/** Mailing list management */
if (!strcmp(tab, "listserv")) {
+ room_states RoomFlags;
wprintf("<div class=\"tabcontent\">");
wprintf("<br /><center>"
);
/** Pop open an address book -- end **/
- wprintf("<hr />");
- if (self_service(999) == 1) {
- wprintf(_("This room is configured to allow "
- "self-service subscribe/unsubscribe requests."));
- wprintf("<a href=\"toggle_self_service?newval=0&tab=listserv\">");
- wprintf(_("Click to disable."));
- wprintf("</A><br />\n");
- wprintf(_("The URL for subscribe/unsubscribe is: "));
- wprintf("<TT>%s://%s/listsub</TT><br />\n",
- (is_https ? "https" : "http"),
- WC->http_host);
- }
- else {
- wprintf(_("This room is <i>not</i> configured to allow "
- "self-service subscribe/unsubscribe requests."));
- wprintf(" <a href=\"toggle_self_service?newval=1&"
- "tab=listserv\">");
- wprintf(_("Click to enable."));
- wprintf("</A><br />\n");
- }
+ wprintf("<br />\n<form method=\"GET\" action=\"toggle_self_service\">\n");
+
+ get_roomflags (&RoomFlags);
+
+ /* Self Service subscription? */
+ wprintf("<table><tr><td>\n");
+ wprintf(_("Allow self-service subscribe/unsubscribe requests."));
+ wprintf("</td><td><input type=\"checkbox\" name=\"QR2_SelfList\" value=\"yes\" %s></td></tr>\n"
+ " <tr><td colspan=\"2\">\n",
+ (is_selflist(&RoomFlags))?"checked":"");
+ wprintf(_("The URL for subscribe/unsubscribe is: "));
+ wprintf("<TT>%s://%s/listsub</TT></td></tr>\n",
+ (is_https ? "https" : "http"),
+ WC->http_host);
+ /* Public posting? */
+ wprintf("<tr><td>");
+ wprintf(_("Allow non-subscribers to mail to this room."));
+ wprintf("</td><td><input type=\"checkbox\" name=\"QR2_SubsOnly\" value=\"yes\" %s></td></tr>\n",
+ (is_publiclist(&RoomFlags))?"checked":"");
+
+ /* Moderated List? */
+ wprintf("<tr><td>");
+ wprintf(_("Room post publication needs Aide permission."));
+ wprintf("</td><td><input type=\"checkbox\" name=\"QR2_Moderated\" value=\"yes\" %s></td></tr>\n",
+ (is_moderatedlist(&RoomFlags))?"checked":"");
+ wprintf("<tr><td colspan=\"2\" align=\"center\">"
+ "<input type=\"submit\" NAME=\"add_button\" VALUE=\"%s\"></td></tr>", _("Save changes"));
+ wprintf("</table></form>");
+
+
wprintf("</CENTER>\n");
wprintf("</div>");
}
wprintf("<i>");
wprintf(_("Retrieve messages from these remote POP3 accounts and store them in this room:"));
- wprintf("</i><br /><br />\n");
+ wprintf("</i><br />\n");
- wprintf("<table border=0 cellpadding=5><tr class=\"tab_cell\"><td>");
+ wprintf("<table class=\"altern\" border=0 cellpadding=5>"
+ "<tr class=\"even\"><th>");
wprintf(_("Remote host"));
- wprintf("</td><td>");
+ wprintf("</th><th>");
wprintf(_("User name"));
- wprintf("</td><td>");
+ wprintf("</th><th>");
wprintf(_("Password"));
- wprintf("</td></tr>");
+ wprintf("</th><th>");
+ wprintf(_("Keep messages on server?"));
+ wprintf("</th><th> </th></tr>");
serv_puts("GNET");
serv_getln(buf, sizeof buf);
+ bg = 1;
if (buf[0]=='1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
extract_token(cmd, buf, 0, '|', sizeof cmd);
if (!strcasecmp(cmd, "pop3client")) {
safestrncpy(recp, &buf[11], sizeof recp);
- wprintf("<tr>");
+
+ bg = 1 - bg;
+ wprintf("<tr class=\"%s\">",
+ (bg ? "even" : "odd")
+ );
wprintf("<td>");
extract_token(pop3_host, buf, 1, '|', sizeof pop3_host);
wprintf("<td>*****</td>"); /* Don't show the password */
- wprintf("<td>");
+ wprintf("<td>%s</td>", extract_int(buf, 4) ? _("Yes") : _("No"));
+
+ wprintf("<td class=\"button_link\">");
wprintf(" <a href=\"netedit&cmd=remove&tab=feeds&line=pop3client|");
urlescputs(recp);
wprintf("\">");
wprintf(_("(remove)"));
- wprintf("</A></td>");
+ wprintf("</a></td>");
wprintf("</tr>");
}
wprintf("<form method=\"POST\" action=\"netedit\">\n"
"<tr>"
- "<input type=\"hidden\" NAME=\"tab\" VALUE=\"feeds\">"
- "<input type=\"hidden\" NAME=\"prefix\" VALUE=\"pop3client|\">\n");
+ "<input type=\"hidden\" name=\"tab\" value=\"feeds\">"
+ "<input type=\"hidden\" name=\"prefix\" value=\"pop3client|\">\n");
wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%ld\">\n", WC->nonce);
wprintf("<td>");
wprintf("<input type=\"text\" id=\"add_as_pop3host\" NAME=\"line_pop3host\">\n");
wprintf("<input type=\"password\" id=\"add_as_pop3pass\" NAME=\"line_pop3pass\">\n");
wprintf("</td>");
wprintf("<td>");
+ wprintf("<input type=\"checkbox\" id=\"add_as_pop3keep\" NAME=\"line_pop3keep\" VALUE=\"1\">");
+ wprintf("</td>");
+ wprintf("<td>");
wprintf("<input type=\"submit\" NAME=\"add_button\" VALUE=\"%s\">", _("Add"));
wprintf("</td></tr>");
wprintf("</form></table>\n");
+ wprintf("<hr>\n");
+
+ wprintf("<i>");
+ wprintf(_("Fetch the following RSS feeds and store them in this room:"));
+ wprintf("</i><br />\n");
+
+ wprintf("<table class=\"altern\" border=0 cellpadding=5>"
+ "<tr class=\"even\"><th>");
+ wprintf("<img src=\"static/rss_16x.png\" width=\"16\" height=\"16\" alt=\" \"> ");
+ wprintf(_("Feed URL"));
+ wprintf("</th><th>");
+ wprintf("</th></tr>");
+
+ serv_puts("GNET");
+ serv_getln(buf, sizeof buf);
+ bg = 1;
+ if (buf[0]=='1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
+ extract_token(cmd, buf, 0, '|', sizeof cmd);
+ if (!strcasecmp(cmd, "rssclient")) {
+ safestrncpy(recp, &buf[10], sizeof recp);
+
+ bg = 1 - bg;
+ wprintf("<tr class=\"%s\">",
+ (bg ? "even" : "odd")
+ );
+
+ wprintf("<td>");
+ extract_token(pop3_host, buf, 1, '|', sizeof pop3_host);
+ escputs(pop3_host);
+ wprintf("</td>");
+
+ wprintf("<td class=\"button_link\">");
+ wprintf(" <a href=\"netedit&cmd=remove&tab=feeds&line=rssclient|");
+ urlescputs(recp);
+ wprintf("\">");
+ wprintf(_("(remove)"));
+ wprintf("</a></td>");
+
+ wprintf("</tr>");
+ }
+ }
+
+ wprintf("<form method=\"POST\" action=\"netedit\">\n"
+ "<tr>"
+ "<input type=\"hidden\" name=\"tab\" value=\"feeds\">"
+ "<input type=\"hidden\" name=\"prefix\" value=\"rssclient|\">\n");
+ wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%ld\">\n", WC->nonce);
+ wprintf("<td>");
+ wprintf("<input type=\"text\" id=\"add_as_pop3host\" size=\"72\" "
+ "maxlength=\"256\" name=\"line_pop3host\">\n");
+ wprintf("</td>");
+ wprintf("<td>");
+ wprintf("<input type=\"submit\" name=\"add_button\" value=\"%s\">", _("Add"));
+ wprintf("</td></tr>");
+ wprintf("</form></table>\n");
+
wprintf("</div>");
}
* \brief Toggle self-service list subscription
*/
void toggle_self_service(void) {
- int newval = 0;
+// int newval = 0;
+ room_states RoomFlags;
+
+ get_roomflags (&RoomFlags);
- newval = atoi(bstr("newval"));
- self_service(newval);
+ // Yank out the bits we want to change
+ RoomFlags.flags2 = RoomFlags.flags2 &
+ !(QR2_SELFLIST|QR2_SMTP_PUBLIC|QR2_MODERATED);
+
+ if (!strcasecmp(bstr("QR2_SelfList"), "yes"))
+ RoomFlags.flags2 = RoomFlags.flags2 | QR2_SELFLIST;
+ if (!strcasecmp(bstr("QR2_SMTP_PUBLIC"), "yes"))
+ RoomFlags.flags2 = RoomFlags.flags2 | QR2_SMTP_PUBLIC;
+ if (!strcasecmp(bstr("QR2_Moderated"), "yes"))
+ RoomFlags.flags2 = RoomFlags.flags2 | QR2_MODERATED;
+
+ set_roomflags (&RoomFlags);
+
display_editroom();
}
if (!strcmp(buf, "passworded")) {
er_flags |= (QR_PRIVATE | QR_PASSWORDED);
}
+ if (!strcmp(buf, "personal")) {
+ er_flags |= QR_MAILBOX;
+ } else {
+ er_flags &= ~QR_MAILBOX;
+ }
+
if (!strcmp(bstr("prefonly"), "yes")) {
er_flags |= QR_PREFONLY;
} else {
er_flags &= ~QR_READONLY;
}
+
if (!strcmp(bstr("collabdel"), "yes")) {
er_flags2 |= QR2_COLLABDEL;
} else {
wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%ld\">\n", WC->nonce);
wprintf(_("Invite:"));
wprintf(" ");
- wprintf("<input type=\"text\" name=\"username\" style=\"width:100%%\"><br />\n"
+ wprintf("<input type=\"text\" name=\"username\" id=\"username_id\" style=\"width:100%%\"><br />\n"
"<input type=\"hidden\" name=\"invite_button\" value=\"Invite\">"
"<input type=\"submit\" value=\"%s\">"
"</form></CENTER>\n", _("Invite"));
+ /** Pop open an address book -- begin **/
+ wprintf(
+ "<a href=\"javascript:PopOpenAddressBook('username_id|%s');\" "
+ "title=\"%s\">"
+ "<img align=middle border=0 width=24 height=24 src=\"static/viewcontacts_24x.gif\">"
+ " %s</a>",
+ _("User"),
+ _("Users"), _("Users")
+ );
+ /** Pop open an address book -- end **/
wprintf("</td></tr></table>\n");
+ address_book_popup();
wDumpContent(1);
}
strcat(line, bstr("line_pop3user"));
strcat(line, "|");
strcat(line, bstr("line_pop3pass"));
+ strcat(line, "|");
+ strcat(line, atoi(bstr("line_pop3keep")) ? "1" : "0" );
strcat(line, bstr("suffix"));
}
else if (!IsEmptyStr(bstr("line"))) {
&& (!IsEmptyStr(old_floor_name)) ) {
/* End inner box */
do_template("endbox");
+ wprintf("<br>");
++num_boxes;
if ((num_boxes % boxes_per_column) == 0) {
struct folder ftmp;
int max_folders = 0;
int alloc_folders = 0;
+ int *floor_mapping;
+ int IDMax;
int i, j;
int ra_flags = 0;
int flags = 0;
int num_floors = 1; /** add an extra one for private folders */
-
+ char buf2[SIZ];
+ char buf3[SIZ];
+
/** If our cached folder list is very old, burn it. */
if (WC->cache_fold != NULL) {
if ((time(NULL) - WC->cache_timestamp) > 300) {
}
memset(&fold[max_folders], 0, sizeof(struct folder));
extract_token(fold[max_folders].name, buf, 1, '|', sizeof fold[max_folders].name);
+ extract_token(buf3, buf, 0, '|', SIZ);
+ fold[max_folders].floor = atol (buf3);
++max_folders;
++num_floors;
}
-
+ IDMax = 0;
+ for (i=0; i<num_floors; i++)
+ if (IDMax < fold[i].floor)
+ IDMax = fold[i].floor;
+ floor_mapping = malloc (sizeof (int) * (IDMax + 1));
+ memset (floor_mapping, 0, sizeof (int) * (IDMax + 1));
+ for (i=0; i<num_floors; i++)
+ floor_mapping[fold[i].floor]=i;
+
/** refresh the messages index for this room */
// serv_puts("GOTO ");
// while (serv_getln(buf, sizeof buf), strcmp(buf, "000"));
fold[max_folders].floor,
fold[max_folders].is_mailbox);
fold[max_folders].selectable = 1;
+ /* Increase the room count for the associtaed floor */
+ if (fold[max_folders].is_mailbox) {
+ fold[0].num_rooms++;
+ }
+ else {
+ i = floor_mapping[fold[max_folders].floor];
+ fold[i].num_rooms++;
+ }
++max_folders;
}
-
+
+ /*
+ * Remove any floors that don't have rooms
+ */
+ get_preference("emptyfloors", buf2, sizeof buf2);
+ if (buf2[0]==0 || (strcasecmp(buf2, "no") == 0))
+ {
+ for (i=0; i<num_floors; i++)
+ {
+ if (fold[i].num_rooms == 0) {
+ for (j=i; j<max_folders; j++) {
+ memcpy(&fold[j], &fold[j+1], sizeof(struct folder));
+ }
+ max_folders--;
+ num_floors--;
+ i--;
+ }
+ }
+ }
+
/** Bubble-sort the folder list */
for (i=0; i<max_folders; ++i) {
for (j=0; j<(max_folders-1)-i; ++j) {
WC->cache_max_folders = max_folders;
WC->cache_num_floors = num_floors;
WC->cache_timestamp = time(NULL);
+ free(floor_mapping);
}