Пример #1
0
/*
 * This is the sending side of the chat window.  The form is designed to transmit asynchronously.
 */
void chat_send(void) {
	char send_this[SIZ];
	char buf[SIZ];

	begin_ajax_response();

	if (havebstr("send_this")) {
		strcpy(send_this, bstr("send_this"));
	}
	else {
		strcpy(send_this, "");
	}

	if (havebstr("exit_button")) {
		strcpy(send_this, "/quit");
	}

	if (!IsEmptyStr(send_this)) {
		serv_puts("RCHT send");
		serv_getln(buf, sizeof buf);
		if (buf[0] == '4') {
			text_to_server(send_this);
			serv_puts("000");
		}
	}
	end_ajax_response();
}
Пример #2
0
void save_net_conf(HashList *Nodelist)
{
	char buf[SIZ];
	StrBuf *Buf;
	HashPos *where;
	void *vNode;
	NodeConf *Node;
	const char *Key;
	long KeyLen;

	serv_puts("CONF putsys|application/x-citadel-ignet-config");
	serv_getln(buf, sizeof buf);
	if (buf[0] == '4') {
		if ((Nodelist != NULL) && (GetCount(Nodelist) > 0)) {
			where = GetNewHashPos(Nodelist, 0);
			Buf = NewStrBuf();
			while (GetNextHashPos(Nodelist, where, &KeyLen, &Key, &vNode)) {
				Node = (NodeConf*) vNode;
				if (Node->DeleteMe==0) { 
					SerializeNode(Node, Buf);
					serv_putbuf(Buf);
				}
			}
			FreeStrBuf(&Buf);
			DeleteHashPos(&where);
		}
		serv_puts("000");
	}
}
Пример #3
0
/*
 * This function is for uploading an ENTIRE calendar, not just one
 * component.  This would be for webcal:// 'publish' operations, not
 * for GroupDAV.
 */
void dav_put_bigics(void)
{
	wcsession *WCC = WC;
	char buf[1024];

	/*
	 * Tell the server that when we save a calendar event, we
	 * do *not* want the server to generate invitations. 
	 */
	serv_puts("ICAL sgi|0");
	serv_getln(buf, sizeof buf);

	serv_puts("ICAL putics");
	serv_getln(buf, sizeof buf);
	if (buf[0] != '4') {
		hprintf("HTTP/1.1 502 Bad Gateway\r\n");
		dav_common_headers();
		hprintf("Content-type: text/plain\r\n");
		begin_burst();
		wc_printf("%s\r\n", &buf[4]);
		end_burst();
		return;
	}

	serv_putbuf(WCC->upload);
	serv_printf("\n000");

	/* Report success and not much else. */
	hprintf("HTTP/1.1 204 No Content\r\n");
	syslog(LOG_DEBUG, "HTTP/1.1 204 No Content\r\n");
	dav_common_headers();
	begin_burst();
	end_burst();
}
Пример #4
0
void do_graphics_upload(char *filename)
{
	StrBuf *Line;
	const char *MimeType;
	wcsession *WCC = WC;
	int bytes_remaining;
	int pos = 0;
	int thisblock;
	bytes_remaining = WCC->upload_length;

	if (havebstr("cancel_button")) {
		AppendImportantMessage(_("Graphics upload has been cancelled."), -1);
		display_main_menu();
		return;
	}

	if (WCC->upload_length == 0) {
		AppendImportantMessage(_("You didn't upload a file."), -1);
		display_main_menu();
		return;
	}
	
	MimeType = GuessMimeType(ChrPtr(WCC->upload), bytes_remaining);
	serv_printf("UIMG 1|%s|%s", MimeType, filename);

	Line = NewStrBuf();
	StrBuf_ServGetln(Line);
	if (GetServerStatusMsg(Line, NULL, 1, 2) != 2) {
		display_main_menu();
		FreeStrBuf(&Line);
		return;
	}
	while (bytes_remaining) {
		thisblock = ((bytes_remaining > 4096) ? 4096 : bytes_remaining);
		serv_printf("WRIT %d", thisblock);
		StrBuf_ServGetln(Line);
		if (GetServerStatusMsg(Line, NULL, 1, 7) != 7) {
			serv_puts("UCLS 0");
			StrBuf_ServGetln(Line);
			display_main_menu();
			FreeStrBuf(&Line);
			return;
		}
		thisblock = extract_int(ChrPtr(Line) +4, 0);
		serv_write(&ChrPtr(WCC->upload)[pos], thisblock);
		pos += thisblock;
		bytes_remaining -= thisblock;
	}

	serv_puts("UCLS 1");
	StrBuf_ServGetln(Line);
	if (*ChrPtr(Line) != 'x') {
		display_success(ChrPtr(Line) + 4);
	
	}
	FreeStrBuf(&Line);

}
Пример #5
0
/*
 * Attempt to attach an OpenID to an existing, logged-in account
 */
void openid_attach(void) {
	char buf[4096];

	if (havebstr("attach_button")) {

		syslog(LOG_DEBUG, "Attempting to attach %s\n", bstr("openid_url"));

		snprintf(buf, sizeof buf,
			"OIDS %s|%s/finalize_openid_login?attach_existing=1|%s",
			bstr("openid_url"),
			ChrPtr(site_prefix),
			ChrPtr(site_prefix)
		);

		serv_puts(buf);
		serv_getln(buf, sizeof buf);
		if (buf[0] == '2') {
			syslog(LOG_DEBUG, "OpenID server contacted; redirecting to %s\n", &buf[4]);
			http_redirect(&buf[4]);
			return;
		}
		else {
			syslog(LOG_DEBUG, "OpenID attach failed: %s\n", &buf[4]);
		}
	}

	/* If we get to this point then something failed. */
	display_openids();
}
Пример #6
0
HashList *load_netconf(StrBuf *Target, WCTemplputParams *TP)
{
	StrBuf *Buf;
	HashList *Hash;
	char nnn[64];
	char buf[SIZ];
	int nUsed;
	NodeConf *Node;

	serv_puts("CONF getsys|application/x-citadel-ignet-config");
	serv_getln(buf, sizeof buf);
	if (buf[0] == '1') {
		Hash = NewHash(1, NULL);

		Buf = NewStrBuf();
		while (StrBuf_ServGetln(Buf), strcmp(ChrPtr(Buf), "000")) {
			Node = NewNode(Buf);
			if (Node != NULL) {
				nUsed = GetCount(Hash);
				nUsed = snprintf(nnn, sizeof(nnn), "%d", nUsed+1);
				Put(Hash, nnn, nUsed, Node, DeleteNodeConf); 
			}
		}
		FreeStrBuf(&Buf);
		return Hash;
	}
	return NULL;
}
Пример #7
0
void setconf_int(char *key, int val)
{
    char buf[SIZ];

    sprintf(buf, "CONF PUTVAL|%s|%d", key, val);
    serv_puts(buf);
    serv_gets(buf);
}
Пример #8
0
void setconf_str(char *key, char *val)
{
    char buf[SIZ];

    sprintf(buf, "CONF PUTVAL|%s|%s", key, val);
    serv_puts(buf);
    serv_gets(buf);
}
Пример #9
0
/*
 * Entry point for RSS feed generator
 */
void feed_rss(void) {
	char buf[1024];

	output_headers(0, 0, 0, 0, 1, 0);
	hprintf("Content-type: text/xml; charset=utf-8\r\n");
	hprintf(
		"Server: %s / %s\r\n"
		"Connection: close\r\n"
	,
		PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software)
	);
	begin_burst();

	wc_printf("<?xml version=\"1.0\"?>"
		"<rss version=\"2.0\">"
		"<channel>"
	);

	wc_printf("<title>");
	escputs(ChrPtr(WC->CurRoom.name));
	wc_printf("</title>");

	wc_printf("<link>");
	escputs(ChrPtr(site_prefix));
	wc_printf("/</link>");

	serv_puts("RINF");
	serv_getln(buf, sizeof buf);
	if (buf[0] == '1') {
		wc_printf("<description>\r\n");
		while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
			escputs(buf);
			wc_printf("\r\n");
		}
		wc_printf("</description>");
	}

	wc_printf("<image><title>");
	escputs(ChrPtr(WC->CurRoom.name));
	wc_printf("</title><url>");
	escputs(ChrPtr(site_prefix));
	wc_printf("/roompic?room=");
	urlescputs(ChrPtr(WC->CurRoom.name));
	wc_printf("</url><link>");
	escputs(ChrPtr(site_prefix));
	wc_printf("/</link></image>\r\n");

	feed_rss_do_room_info_as_description();
	feed_rss_do_messages();

	wc_printf("</channel>"
		"</rss>"
		"\r\n\r\n"
	);

	wDumpContent(0);
}
Пример #10
0
void cleanup(int exitcode) {
	char buf[1024];

	if (exitcode != 0) {
		fprintf(stderr, "citmail: error #%d occurred while sending mail.\n", exitcode);
		fprintf(stderr, "Please check your Citadel configuration.\n");
	}
	serv_puts("QUIT");
	serv_gets(buf);
	exit(exitcode);
}
Пример #11
0
/*
 * Display the OpenIDs associated with an account
 */
void display_openids(void)
{
	wcsession *WCC = WC;
	char buf[1024];
	int bg = 0;

	output_headers(1, 1, 1, 0, 0, 0);

	do_template("box_begin_1");
	StrBufAppendBufPlain(WCC->WBuf, _("Manage Account/OpenID Associations"), -1, 0);
	do_template("box_begin_2");

	if (WCC->serv_info->serv_supports_openid) {

		wc_printf("<table class=\"altern\">");
	
		serv_puts("OIDL");
		serv_getln(buf, sizeof buf);
		if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
			bg = 1 - bg;
			wc_printf("<tr class=\"%s\">", (bg ? "even" : "odd"));
			wc_printf("<td><img src=\"static/webcit_icons/openid-small.gif\"></td><td>");
			escputs(buf);
			wc_printf("</td><td>");
			wc_printf("<a href=\"openid_detach?id_to_detach=");
			urlescputs(buf);
			wc_printf("\" onClick=\"return confirm('%s');\">",
				_("Do you really want to delete this OpenID?"));
			wc_printf("%s</a>", _("(delete)"));
			wc_printf("</td></tr>\n");
		}
	
		wc_printf("</table><br>\n");
	
	        wc_printf("<form method=\"POST\" action=\"openid_attach\">\n");
		wc_printf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WCC->nonce);
		wc_printf(_("Add an OpenID: "));
	        wc_printf("<input type=\"text\" name=\"openid_url\" class=\"openid_urlarea\" size=\"40\">\n");
	        wc_printf("<input type=\"submit\" name=\"attach_button\" value=\"%s\">"
			"</form></center>\n", _("Attach"));
	}

	else {
		wc_printf(_("%s does not permit authentication via OpenID."), ChrPtr(WCC->serv_info->serv_humannode));
	}

	do_template("box_end");
	wDumpContent(2);
}
Пример #12
0
/*
 * Convenience functions to get/set system configuration entries
 */
void getconf_str(char *buf, char *key)
{
    char cmd[SIZ];
    char ret[SIZ];

    sprintf(cmd, "CONF GETVAL|%s", key);
    serv_puts(cmd);
    serv_gets(ret);
    if (ret[0] == '2') {
        extract_token(buf, &ret[4], 0, '|', SIZ);
    }
    else {
        strcpy(buf, "");
    }
}
Пример #13
0
/*
 * Display the screen containing multiuser chat for a room.
 */
void do_chat(void)
{
	char buf[256];

	WC->last_chat_seq = 0;
	WC->last_chat_user[0] = 0;

	output_headers(1, 1, 1, 0, 0, 0);
	do_template("roomchat");

	serv_puts("RCHT enter");
	serv_getln(buf, sizeof buf);

	wDumpContent(1);
}
Пример #14
0
/*
 * Helper function for the asynchronous check to see if we need
 * to open the instant messenger window.
 */
void seconds_since_last_gexp(void)
{
	char buf[256];

	if ( (time(NULL) - WC->last_pager_check) < 30) {
		wc_printf("NO\n");
	}
	else {
		memset(buf, 0, 5);
		serv_puts("NOOP");
		serv_getln(buf, sizeof buf);
		if (buf[3] == '*') {
			wc_printf("YES");
		}
		else {
			wc_printf("NO");
		}
	}
}
Пример #15
0
/*
 * wholist for chat
 */
void chat_rwho(void) {
	char buf[1024];

	serv_puts("RCHT rwho");
	serv_getln(buf, sizeof buf);
	if (buf[0] == '1') {
		while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
			if (!strcasecmp(buf, ChrPtr(WC->wc_fullname))) {
				wc_printf("<span class=\"chat_myname_class\">");
			}
			else {
				wc_printf("<span class=\"chat_notmyname_class\">");
			}
			wc_printf("<img src=\"static/webcit_icons/essen/16x16/chat.png\">");
			escputs(buf);
			wc_printf("</span><br>\n");
		}
	}
}
Пример #16
0
/*
 * advise the Citadel server that the user is navigating away from the chat window
 */
void chat_exit(void) {
	char buf[1024];

	serv_puts("RCHT exit");
	serv_getln(buf, sizeof buf);		/* Throw away the server reply */
}
Пример #17
0
/*
 * Wraps a Citadel server command in an AJAX transaction.
 */
void ajax_servcmd(void)
{
	wcsession *WCC = WC;
	int Done = 0;
	StrBuf *Buf;
	char *junk;
	size_t len;

	if (verbose)
		syslog(LOG_DEBUG, "ajax_servcmd() g_cmd=\"%s\"", bstr("g_cmd") );
	begin_ajax_response();
	Buf = NewStrBuf();
	serv_puts(bstr("g_cmd"));
	StrBuf_ServGetln(Buf);
	StrBufAppendBuf(WCC->WBuf, Buf, 0);
	StrBufAppendBufPlain(WCC->WBuf, HKEY("\n"), 0);
	
	switch (GetServerStatus(Buf, NULL)) {
	case 8:
		serv_puts("\n\n000");
		if ( (StrLength(Buf)==3) && 
		     !strcmp(ChrPtr(Buf), "000")) {
			StrBufAppendBufPlain(WCC->WBuf, HKEY("\000"), 0);
			break;
		}
	case 1:
		while (!Done) {
			if (StrBuf_ServGetln(Buf) < 0)
				break;
			if ( (StrLength(Buf)==3) && 
			     !strcmp(ChrPtr(Buf), "000")) {
				Done = 1;
			}
			StrBufAppendBuf(WCC->WBuf, Buf, 0);
			StrBufAppendBufPlain(WCC->WBuf, HKEY("\n"), 0);
		}
		break;
	case 4:
		text_to_server(bstr("g_input"));
		serv_puts("000");
		break;
	case 6:
		len = atol(&ChrPtr(Buf)[4]);
		StrBuf_ServGetBLOBBuffered(Buf, len);
		break;
	case 7:
		len = atol(&ChrPtr(Buf)[4]);
		junk = malloc(len);
		memset(junk, 0, len);
		serv_write(junk, len);
		free(junk);
	}
	
	end_ajax_response();
	
	/*
	 * This is kind of an ugly hack, but this is the only place it can go.
	 * If the command was GEXP, then the instant messenger window must be
	 * running, so reset the "last_pager_check" watchdog timer so
	 * that page_popup() doesn't try to open it a second time. TODO: page_popup isn't with us anymore.
	 */
	if (!strncasecmp(bstr("g_cmd"), "GEXP", 4)) {
		WCC->last_pager_check = time(NULL);
	}
	FreeStrBuf(&Buf);
}
Пример #18
0
/*
 * Serialize a vnote and write it to the server
 */
void write_vnote_to_server(struct vnote *v) 
{
	char buf[1024];
	char *pch;
	char boundary[256];
	static int seq = 0;

	snprintf(boundary, sizeof boundary, "Citadel--Multipart--%s--%04x--%04x",
		ChrPtr(WC->serv_info->serv_fqdn),
		getpid(),
		++seq
	);

	serv_puts("ENT0 1|||4");
	serv_getln(buf, sizeof buf);
	if (buf[0] == '4') {
		/* Remember, serv_printf() appends an extra newline */
		serv_printf("Content-type: multipart/alternative; "
			"boundary=\"%s\"\n", boundary);
		serv_printf("This is a multipart message in MIME format.\n");
		serv_printf("--%s", boundary);
	
		serv_puts("Content-type: text/plain; charset=utf-8");
		serv_puts("Content-Transfer-Encoding: 7bit");
		serv_puts("");
		serv_puts(v->body);
		serv_puts("");
	
		serv_printf("--%s", boundary);
		serv_puts("Content-type: text/vnote");
		serv_puts("Content-Transfer-Encoding: 7bit");
		serv_puts("");
		pch = vnote_serialize(v);
		serv_puts(pch);
		free(pch);
		serv_printf("--%s--", boundary);
		serv_puts("000");
	}
}
Пример #19
0
                  int main(int argc, char *argv[])
{
    int a, i;
    int curr;
    char buf[1024];
    char aaa[128];
    int relh = 0;
    int home = 0;
    int nRetries = 0;
    char relhome[PATH_MAX]="";
    char ctdldir[PATH_MAX]=CTDLDIR;
    struct passwd *pw;
    gid_t gid;
    char *activity = NULL;

    /* Keep a mild groove on */
    program_title = _("Citadel setup program");

    /* set an invalid setup type */
    setup_type = (-1);

    /* parse command line args */
    for (a = 0; a < argc; ++a) {
        if (!strncmp(argv[a], "-u", 2)) {
            strcpy(aaa, argv[a]);
            strcpy(aaa, &aaa[2]);
            setup_type = atoi(aaa);
        }
        else if (!strcmp(argv[a], "-q")) {
            setup_type = UI_SILENT;
        }
        else if (!strncmp(argv[a], "-h", 2)) {
            relh=argv[a][2]!='/';
            if (!relh) {
                safestrncpy(ctdl_home_directory, &argv[a][2], sizeof ctdl_home_directory);
            } else {
                safestrncpy(relhome, &argv[a][2], sizeof relhome);
            }
            home = 1;
        }

    }

    calc_dirs_n_files(relh, home, relhome, ctdldir, 0);
    SetTitles();

    /* If a setup type was not specified, try to determine automatically
     * the best one to use out of all available types.
     */
    if (setup_type < 0) {
        setup_type = discover_ui();
    }

    enable_home = ( relh | home );

    if (chdir(ctdl_run_dir) != 0) {
        display_error("%s: [%s]\n", _("The directory you specified does not exist"), ctdl_run_dir);
        exit(errno);
    }


    /*
     * Connect to the running Citadel server.
     */
    while ((serv_sock < 0) && (nRetries < 10)) {
        serv_sock = uds_connectsock(file_citadel_admin_socket);
        nRetries ++;
        if (serv_sock < 0)
            sleep(1);
    }
    if (serv_sock < 0) {
        display_error(
            "%s: %s %s\n",
            _("Setup could not connect to a running Citadel server."),
            strerror(errno), file_citadel_admin_socket
        );
        exit(1);
    }

    /*
     * read the server greeting
     */
    serv_gets(buf);
    if (buf[0] != '2') {
        display_error("%s\n", buf);
        exit(2);
    }

    /*
     * Are we connected to the correct Citadel server?
     */
    serv_puts("INFO");
    serv_gets(buf);
    if (buf[0] != '1') {
        display_error("%s\n", buf);
        exit(3);
    }
    a = 0;
    while (serv_gets(buf), strcmp(buf, "000")) {
        if (a == 5) {
            if (atoi(buf) != REV_LEVEL) {
                display_error("%s\n",
                              _("Your setup program and Citadel server are from different versions.")
                             );
                exit(4);
            }
        }
        ++a;
    }

    /*
     * Now begin.
     */


    if (setup_type == UI_TEXT) {
        printf("\n\n\n	       *** %s ***\n\n", program_title);
    }

    if (setup_type == UI_DIALOG) {
        system("clear 2>/dev/null");
    }

    /* Go through a series of dialogs prompting for config info */
    for (curr = 1; curr < eMaxQuestions; ++curr) {
        edit_value(curr);

        if (	(curr == eAuthType)
                && (getconf_int("c_auth_mode") != AUTHMODE_LDAP)
                && (getconf_int("c_auth_mode") != AUTHMODE_LDAP_AD)
           ) {
            curr += 5;	/* skip LDAP questions if we're not authenticating against LDAP */
        }

        if (curr == eSysAdminName) {
            if (getconf_int("c_auth_mode") == AUTHMODE_NATIVE) {
                /* for native auth mode, fetch the admin's existing pw */
                snprintf(buf, sizeof buf, "AGUP %s", admin_name);
                serv_puts(buf);
                serv_gets(buf);
                if (buf[0] == '2') {
                    extract_token(admin_pass, &buf[4], 1, '|', sizeof admin_pass);
                }
            }
            else {
                ++curr;		/* skip the password question for non-native auth modes */
            }
        }
    }

    if ((pw = getpwuid( getconf_int("c_ctdluid") )) == NULL) {
        gid = getgid();
    } else {
        gid = pw->pw_gid;
    }

    if (create_run_directories(getconf_int("c_ctdluid"), gid) != 0) {
        display_error("%s\n", _("failed to create directories"));
    }

    activity = _("Reconfiguring Citadel server");
    progress(activity, 0, 5);
    sleep(1);					/* Let the message appear briefly */

    /*
     * Create the administrator account.  It's ok if the command fails if this user already exists.
     */
    progress(activity, 1, 5);
    snprintf(buf, sizeof buf, "CREU %s|%s", admin_name, admin_pass);
    serv_puts(buf);
    progress(activity, 2, 5);
    serv_gets(buf);
    progress(activity, 3, 5);

    /*
     * Assign the desired password and access level to the administrator account.
     */
    snprintf(buf, sizeof buf, "AGUP %s", admin_name);
    serv_puts(buf);
    progress(activity, 4, 5);
    serv_gets(buf);
    if (buf[0] == '2') {
        int admin_flags = extract_int(&buf[4], 2);
        int admin_times_called = extract_int(&buf[4], 3);
        int admin_msgs_posted = extract_int(&buf[4], 4);
        snprintf(buf, sizeof buf, "ASUP %s|%s|%d|%d|%d|6",
                 admin_name, admin_pass, admin_flags, admin_times_called, admin_msgs_posted
                );
        serv_puts(buf);
        serv_gets(buf);
    }
    progress(activity, 5, 5);

#ifndef __CYGWIN__
    check_xinetd_entry();	/* Check /etc/xinetd.d/telnet */
    disable_other_mtas();   /* Offer to disable other MTAs */
    fixnss();		/* Check for the 'db' nss and offer to disable it */
#endif

    /*
     * Restart citserver
     */
    activity = _("Restarting Citadel server to apply changes");
    progress(activity, 0, 41);

    serv_puts("TIME");
    serv_gets(buf);
    long original_start_time = extract_long(&buf[4], 3);

    progress(activity, 1, 41);
    serv_puts("DOWN 1");
    progress(activity, 2, 41);
    serv_gets(buf);
    if (buf[0] != '2') {
        display_error("%s\n", buf);
        exit(6);
    }

    close(serv_sock);
    serv_sock = (-1);

    for (i=3; i<=6; ++i) {					/* wait for server to shut down */
        progress(activity, i, 41);
        sleep(1);
    }

    for (i=7; ((i<=38) && (serv_sock < 0)) ; ++i) {		/* wait for server to start up */
        progress(activity, i, 41);
        serv_sock = uds_connectsock(file_citadel_admin_socket);
        sleep(1);
    }

    progress(activity, 39, 41);
    serv_gets(buf);

    progress(activity, 40, 41);
    serv_puts("TIME");
    serv_gets(buf);
    long new_start_time = extract_long(&buf[4], 3);

    close(serv_sock);
    progress(activity, 41, 41);

    if (	(original_start_time == new_start_time)
            || (new_start_time <= 0)
       ) {
        display_error("%s\n", _("Setup failed to restart Citadel server.  Please restart it manually."));
        exit(7);
    }

    exit(0);
    return 0;
}
Пример #20
0
/*
 * The pathname is always going to take one of two formats:
 * [/groupdav/]room_name/euid	(GroupDAV)
 * [/groupdav/]room_name		(webcal)
 */
void dav_put(void) 
{
	wcsession *WCC = WC;
	StrBuf *dav_roomname;
	StrBuf *dav_uid;
	long new_msgnum = (-2L);
	long old_msgnum = (-1L);
	char buf[SIZ];
	int n = 0;

	if (StrBufNum_tokens(WCC->Hdr->HR.ReqLine, '/') < 2) {
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Content-Type: text/plain\r\n");
		begin_burst();
		wc_printf("The object you requested was not found.\r\n");
		end_burst();
		return;
	}

	dav_roomname = NewStrBuf();;
	dav_uid = NewStrBuf();;
	StrBufExtract_token(dav_roomname, WCC->Hdr->HR.ReqLine, 0, '/');
	StrBufExtract_token(dav_uid, WCC->Hdr->HR.ReqLine, 1, '/');
	if ((!strcasecmp(ChrPtr(dav_uid), "ics")) || 
	    (!strcasecmp(ChrPtr(dav_uid), "calendar.ics"))) {
		FlushStrBuf(dav_uid);
	}

	/* Go to the correct room. */
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		gotoroom(dav_roomname);
	}
	if (strcasecmp(ChrPtr(WC->CurRoom.name), ChrPtr(dav_roomname))) {
		hprintf("HTTP/1.1 404 not found\r\n");
		dav_common_headers();
		hprintf("Content-Type: text/plain\r\n");
		begin_burst();
		wc_printf("There is no folder called \"%s\" on this server.\r\n",
			ChrPtr(dav_roomname));
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);		
		return;
	}

	/*
	 * If an HTTP If-Match: header is present, the client is attempting
	 * to replace an existing item.  We have to check to see if the
	 * message number associated with the supplied uid matches what the
	 * client is expecting.  If not, the server probably contains a newer
	 * version, so we fail...
	 */
	if (StrLength(WCC->Hdr->HR.dav_ifmatch) > 0) {
		syslog(LOG_DEBUG, "dav_ifmatch: %s\n", ChrPtr(WCC->Hdr->HR.dav_ifmatch));
		old_msgnum = locate_message_by_uid(ChrPtr(dav_uid));
		syslog(LOG_DEBUG, "old_msgnum:  %ld\n", old_msgnum);
		if (StrTol(WCC->Hdr->HR.dav_ifmatch) != old_msgnum) {
			hprintf("HTTP/1.1 412 Precondition Failed\r\n");
			syslog(LOG_INFO, "HTTP/1.1 412 Precondition Failed (ifmatch=%ld, old_msgnum=%ld)\r\n",
				StrTol(WCC->Hdr->HR.dav_ifmatch), old_msgnum);
			dav_common_headers();
			
			end_burst();
			FreeStrBuf(&dav_roomname);
			FreeStrBuf(&dav_uid);
			return;
		}
	}

	/** PUT on the collection itself uploads an ICS of the entire collection.
	 */
	if (StrLength(dav_uid) == 0) {
		dav_put_bigics();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/*
	 * We are cleared for upload!  We use the new calling syntax for ENT0
	 * which allows a confirmation to be sent back to us.  That's how we
	 * extract the message ID.
	 */
	serv_puts("ENT0 1|||4|||1|");
	serv_getln(buf, sizeof buf);
	if (buf[0] != '8') {
		hprintf("HTTP/1.1 502 Bad Gateway\r\n");
		dav_common_headers();
		hprintf("Content-type: text/plain\r\n");
		begin_burst();
		wc_printf("%s\r\n", &buf[4]);
		end_burst();
		return;
	}

	/* Send the content to the Citadel server */
	//serv_printf("Content-type: %s\n\n", WCC->upload_content_type);
	serv_putbuf(WCC->upload);
	serv_puts("\n000");

	/* Fetch the reply from the Citadel server */
	n = 0;
	FlushStrBuf(dav_uid);
	while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
		switch(n++) {
		case 0: 
			new_msgnum = atol(buf);
			break;
		case 1:	
			syslog(LOG_DEBUG, "new_msgnum=%ld (%s)\n", new_msgnum, buf);
			break;
		case 2: 
			StrBufAppendBufPlain(dav_uid, buf, -1, 0);
			break;
		default:
			break;
		}
	}

	/* Tell the client what happened. */

	/* Citadel failed in some way? */
	if (new_msgnum < 0L) {
		hprintf("HTTP/1.1 502 Bad Gateway\r\n");
		dav_common_headers();
		hprintf("Content-type: text/plain\r\n");
		begin_burst();
		wc_printf("new_msgnum is %ld\r\n"
			"\r\n", new_msgnum);
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/* We created this item for the first time. */
	if (old_msgnum < 0L) {
	        char escaped_uid[1024];
		hprintf("HTTP/1.1 201 Created\r\n");
		syslog(LOG_DEBUG, "HTTP/1.1 201 Created\r\n");
		dav_common_headers();
		hprintf("etag: \"%ld\"\r\n", new_msgnum);
		hprintf("Location: ");
		dav_identify_hosthdr();
		hprintf("/groupdav/");/* TODO */
		hurlescputs(ChrPtr(dav_roomname));
	        euid_escapize(escaped_uid, ChrPtr(dav_uid));
	        hprintf("/%s\r\n", escaped_uid);
		end_burst();
		FreeStrBuf(&dav_roomname);
		FreeStrBuf(&dav_uid);
		return;
	}

	/* We modified an existing item. */
	hprintf("HTTP/1.1 204 No Content\r\n");
	syslog(LOG_DEBUG, "HTTP/1.1 204 No Content\r\n");
	dav_common_headers();
	hprintf("Etag: \"%ld\"\r\n", new_msgnum);
	/* The item we replaced has probably already been deleted by
	 * the Citadel server, but we'll do this anyway, just in case.
	 */
	serv_printf("DELE %ld", old_msgnum);
	serv_getln(buf, sizeof buf);
	begin_burst();
	end_burst();
	FreeStrBuf(&dav_roomname);
	FreeStrBuf(&dav_uid);
	return;
}
Пример #21
0
void display_pushemail(void) 
{
	folder Room;
	int Done = 0;
	StrBuf *Buf;
	long vector[8] = {8, 0, 0, 1, 2, 3, 4, 5};
	WCTemplputParams SubTP;
	char mobnum[20];

	StackContext(NULL, &SubTP, &vector, CTX_LONGVECTOR, 0, NULL);
	vector[0] = 16;

	/* Find any existing settings*/
	Buf = NewStrBuf();
	memset(&Room, 0, sizeof(folder));
	if (goto_config_room(Buf, &Room) == 0) {
		int msgnum = 0;
		serv_puts("MSGS ALL|0|1");
		StrBuf_ServGetln(Buf);
		if (GetServerStatus(Buf, NULL) == 8) {
			serv_puts("subj|__ Push email settings __");
			serv_puts("000");
			while (!Done &&
			       StrBuf_ServGetln(Buf) >= 0) {
				if ( (StrLength(Buf)==3) && 
				     !strcmp(ChrPtr(Buf), "000")) {
					Done = 1;
					break;
				}
				msgnum = StrTol(Buf);
			}
		}
		if (msgnum > 0L) {
		serv_printf("MSG0 %d", msgnum);
		StrBuf_ServGetln(Buf);
		if (GetServerStatus(Buf, NULL) == 1) {
			int i =0;
			Done = 0;
			while (!Done &&
			       StrBuf_ServGetln(Buf) >= 0) {
				if (( (StrLength(Buf)==3) && 
				      !strcmp(ChrPtr(Buf), "000"))||
				    ((StrLength(Buf)==4) && 
				     !strcmp(ChrPtr(Buf), "text")))
				{
					Done = 1;
					break;
				}
			}
			if (!strcmp(ChrPtr(Buf), "text")) {
				Done = 0;
				while (!Done &&
				       StrBuf_ServGetln(Buf) >= 0) {
					if ( (StrLength(Buf)==3) && 
					     !strcmp(ChrPtr(Buf), "000")) {
						Done = 1;
						break;
					}
					if (strncasecmp(ChrPtr(Buf), "none", 4) == 0) {
						vector[1] = 0;
					} else if (strncasecmp(ChrPtr(Buf), "textmessage", 11) == 0) {
						vector[1] = 1;
						i++;
					} else if (strncasecmp(ChrPtr(Buf), "funambol", 8) == 0) {
						vector[1] = 2;
					} else if (strncasecmp(ChrPtr(Buf), "httpmessage", 12) == 0) {
						vector[1] = 3;
					} else if (i == 1) {
						strncpy(mobnum, ChrPtr(Buf), 20);
						i++;
					}
				}	
			}
		}
		}
		serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name));
		StrBuf_ServGetln(Buf);
		GetServerStatus(Buf, NULL);
	}
	FlushFolder(&Room);
	output_headers(1, 1, 1, 0, 0, 0);
	DoTemplate(HKEY("prefs_pushemail"), NULL, &SubTP);
	wDumpContent(1);
	UnStackContext(&SubTP);
	FreeStrBuf(&Buf);
}
Пример #22
0
void save_pushemail(void) 
{
	folder Room;
	int Done = 0;
	StrBuf *Buf;
	char buf[SIZ];
	int msgnum = 0;
	char *pushsetting = bstr("pushsetting");
	char *sms = NULL;

	if (strncasecmp(pushsetting, "textmessage", 11) == 0) {
		sms = bstr("user_sms_number");
	}
	Buf = NewStrBuf();
	memset(&Room, 0, sizeof(folder));
	if (goto_config_room(Buf, &Room) != 0) {
		FreeStrBuf(&Buf);
		FlushFolder(&Room);
		return;	/* oh well. */
	}
	FlushFolder(&Room);

	serv_puts("MSGS ALL|0|1");
	StrBuf_ServGetln(Buf);
	if (GetServerStatus(Buf, NULL) == 8) {
		serv_puts("subj|__ Push email settings __");
		serv_puts("000");
	} else {
		printf("Junk in save_pushemail buffer!: %s\n", buf);
		FreeStrBuf(&Buf);
		return;
	}

	while (!Done &&
	       StrBuf_ServGetln(Buf) >= 0) {
		if ( (StrLength(Buf)==3) && 
		     !strcmp(ChrPtr(Buf), "000")) {
			Done = 1;
			break;
		}
		msgnum = StrTol(Buf);
	}

	if (msgnum > 0L) {
		serv_printf("DELE %d", msgnum);
		StrBuf_ServGetln(Buf);
		GetServerStatus(Buf, NULL);
	}

	serv_printf("ENT0 1||0|1|__ Push email settings __|");
	StrBuf_ServGetln(Buf);
	if (GetServerStatus(Buf, NULL) == 4) {
		serv_puts(pushsetting);
		if (sms != NULL) {
		serv_puts(sms);
		} 
		serv_puts("");
		serv_puts("000");
	}

	/** Go back to the room we're supposed to be in */
	serv_printf("GOTO %s", ChrPtr(WC->CurRoom.name));
	StrBuf_ServGetln(Buf);
	GetServerStatus(Buf, NULL);
	http_redirect("display_pushemail");
	FreeStrBuf(&Buf);
}
Пример #23
0
int main(int argc, char **argv) {
	char buf[1024];
	char fromline[1024];
	FILE *fp;
	int i;
	struct passwd *pw;
	int from_header = 0;
	int in_body = 0;
	int relh=0;
	int home=0;
	char relhome[PATH_MAX]="";
	char ctdldir[PATH_MAX]=CTDLDIR;
	char *sp, *ep;
	char hostname[256];
	char **recipients = NULL;
	int num_recipients = 0;
	int to_or_cc = 0;
	int read_recipients_from_headers = 0;
	char *add_these_recipients = NULL;

	for (i=1; i<argc; ++i) {
		if (!strcmp(argv[i], "-d")) {
			debug = 1;
		}
		else if (!strcmp(argv[i], "-t")) {
			read_recipients_from_headers = 1;
		}
		else if (argv[i][0] != '-') {
			++num_recipients;
			recipients = realloc(recipients, (num_recipients * sizeof (char *)));
			recipients[num_recipients - 1] = strdup(argv[i]);
		}
	}
	       
	/* TODO: should we be able to calculate relative dirs? */
	calc_dirs_n_files(relh, home, relhome, ctdldir, 0);

	pw = getpwuid(getuid());

	fp = tmpfile();
	if (fp == NULL) return(errno);
	serv_sock = uds_connectsock(file_lmtp_socket);	/* FIXME: if called as 'sendmail' connect to file_lmtp_unfiltered_socket */
	serv_gets(buf);
	if (buf[0] != '2') {
		fprintf(stderr, "%s\n", &buf[4]);
		if (debug) fprintf(stderr, "citmail: could not connect to LMTP socket.\n");
		cleanup(1);
	}

	sp = strchr (buf, ' ');
	if (sp == NULL) {
		if (debug) fprintf(stderr, "citmail: could not calculate hostname.\n");
		cleanup(2);
	}
	sp ++;
	ep = strchr (sp, ' ');
	if (ep == NULL) {
		if (debug) fprintf(stderr, "citmail: error parsing hostname\n");
		cleanup(3);
	}
	else
		*ep = '\0';

	strncpy(hostname, sp, sizeof hostname);

	snprintf(fromline, sizeof fromline, "From: %s@%s", pw->pw_name, hostname);
	while (fgets(buf, 1024, stdin) != NULL) {
		if ( ( (buf[0] == 13) || (buf[0] == 10)) && (in_body == 0) ) {
			in_body = 1;
			if (from_header == 0) {
				fprintf(fp, "%s%s", fromline, buf);
			}
		}
		if (in_body == 0 && !strncasecmp(buf, "From:", 5)) {
			strcpy(fromline, buf);
			from_header = 1;
		}

		if (read_recipients_from_headers) {
			add_these_recipients = NULL;
			if ((isspace(buf[0])) && (to_or_cc)) {
				add_these_recipients = buf;
			}
			else {
				if ((!strncasecmp(buf, "To:", 3)) || (!strncasecmp(buf, "Cc:", 3))) {
					to_or_cc = 1;
				}
				else {
					to_or_cc = 0;
				}
				if (to_or_cc) {
					add_these_recipients = &buf[3];
				}
			}

			if (add_these_recipients) {
				int num_recp_on_this_line;
				char this_recp[256];

				num_recp_on_this_line = num_tokens(add_these_recipients, ',');
				for (i=0; i<num_recp_on_this_line; ++i) {
					extract_token(this_recp, add_these_recipients,
						i, ',', sizeof this_recp);
					striplt(this_recp);
					if (!IsEmptyStr(this_recp)) {
						++num_recipients;
						recipients = realloc(recipients,
							(num_recipients * sizeof (char *)));
						recipients[num_recipients - 1] = strdup(this_recp);
					}
				}
			}
		}

		fprintf(fp, "%s", buf);
	}
	strip_trailing_nonprint(fromline);

	sprintf(buf, "LHLO %s", hostname);
	serv_puts(buf);
	do {
		serv_gets(buf);
		strcat(buf, "    ");
	} while (buf[3] == '-');
	if (buf[0] != '2') {
		if (debug) fprintf(stderr, "citmail: LHLO command failed\n");
		cleanup(4);
	}

	snprintf(buf, sizeof buf, "MAIL %s", fromline);
	serv_puts(buf);
	serv_gets(buf);
	if (buf[0] != '2') {
		if (debug) fprintf(stderr, "citmail: MAIL command failed\n");
		cleanup(5);
	}

	for (i=0; i<num_recipients; ++i) {
		snprintf(buf, sizeof buf, "RCPT To: %s", recipients[i]);
		serv_puts(buf);
		serv_gets(buf);
		free(recipients[i]);
	}
	free(recipients);

	serv_puts("DATA");
	serv_gets(buf);
	if (buf[0]!='3') {
		if (debug) fprintf(stderr, "citmail: DATA command failed\n");
		cleanup(6);
	}

	rewind(fp);
	while (fgets(buf, sizeof buf, fp) != NULL) {
		strip_trailing_nonprint(buf);
		serv_puts(buf);
	}
	serv_puts(".");
	serv_gets(buf);
	if (buf[0] != '2') {
		fprintf(stderr, "%s\n", &buf[4]);
		cleanup(7);
	}
	else {
		cleanup(0);
	}

	/* We won't actually reach this statement but the compiler will
	 * display a spurious warning about an invalid return type if
	 * we don't return an int.
	 */
	return(0);
}