* Added qpdecode.c to the distribution (decodes quoted-printable)
* Finished the MIME parser
* Gave MSG0 a reasonable behaviour for MIME messages
+ * Added the OPNA command for downloading attachments
Sat Jan 30 18:39:53 EST 1999 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
* Look for citadel.rc in current directory if not found elsewhere
cmd_msg4(&cmdbuf[5]);
}
+ else if (!strncasecmp(cmdbuf,"OPNA",4)) {
+ cmd_opna(&cmdbuf[5]);
+ }
+
else if (!strncasecmp(cmdbuf,"INFO",4)) {
cmd_info();
}
* It examines the file and displays the OK result code and some information
* about the file. NOTE: this stuff is Unix dependent.
*/
-void OpenCmdResult(void) {
+void OpenCmdResult(char *filename, char *mime_type) {
struct stat statbuf;
fstat(fileno(CC->download_fp), &statbuf);
- cprintf("%d %ld|%ld\n", OK, statbuf.st_size, statbuf.st_mtime);
+ cprintf("%d %ld|%ld|%s|%s\n", OK, statbuf.st_size, statbuf.st_mtime,
+ filename, mime_type);
}
return;
}
- OpenCmdResult();
+ OpenCmdResult(filename, "application/octet-stream");
}
/*
return;
}
- OpenCmdResult();
+ OpenCmdResult(pathname, "image/gif");
}
/*
void cmd_delf (char *filename);
void cmd_movf (char *cmdbuf);
void cmd_netf (char *cmdbuf);
-void OpenCmdResult (void);
+void OpenCmdResult (char *, char *);
void cmd_open (char *cmdbuf);
void cmd_oimg (char *cmdbuf);
void cmd_uopn (char *cmdbuf);
#include "sysdep_decls.h"
#include "room_ops.h"
#include "user_ops.h"
+#include "file_ops.h"
#include "control.h"
#include "dynloader.h"
#include "tools.h"
}
+/*
+ * Callback function for mime parser that opens a section for downloading
+ */
+void mime_download(char *name, char *filename, char *partnum, char *disp,
+ void *content, char *cbtype, size_t length) {
+
+ char tmpname[PATH_MAX];
+ static int seq = 0;
+
+ /* Silently go away if there's already a download open... */
+ if (CC->download_fp != NULL) return;
+
+ /* ...or if this is not the desired section */
+ if (strcasecmp(CC->desired_section, partnum)) return;
+
+ snprintf(tmpname, sizeof tmpname,
+ "/tmp/CitServer.download.%4x.%4x", getpid(), ++seq);
+
+ CC->download_fp = fopen(tmpname, "wb+");
+ if (CC->download_fp == NULL) return;
+
+ /* Unlink the file while it's open, to guarantee that the
+ * temp file will always be deleted.
+ */
+ unlink(tmpname);
+
+ fwrite(content, length, 1, CC->download_fp);
+ fflush(CC->download_fp);
+ rewind(CC->download_fp);
+
+ OpenCmdResult(filename, cbtype);
+ }
+
+
+
/*
* Get a message off disk. (return value is the message's timestamp)
*
anon_flag = *mptr++;
format_type = *mptr++;
+ /* Are we downloading a MIME component? */
+ if (mode == MT_DOWNLOAD) {
+ if (format_type != 4) {
+ cprintf("%d This is not a MIME message.\n",
+ ERROR);
+ }
+ else if (CC->download_fp != NULL) {
+ cprintf("%d You already have a download open.\n",
+ ERROR);
+ }
+ else {
+ /* Skip to the message body */
+ while(ch = *mptr++, (ch!='M' && ch!=0)) {
+ buf[0] = 0;
+ do {
+ buf[strlen(buf)+1] = 0;
+ rch = *mptr++;
+ buf[strlen(buf)] = rch;
+ } while (rch > 0);
+ }
+ /* Now parse it */
+ mime_parser(mptr, NULL, *mime_download);
+ /* If there's no file open by this time, the requested
+ * section wasn't found, so print an error
+ */
+ if (CC->download_fp == NULL) {
+ cprintf("%d Section %s not found.\n",
+ ERROR+FILE_NOT_FOUND,
+ CC->desired_section);
+ }
+ }
+ cdb_free(dmsgtext);
+ return(xtime);
+ }
+
/* Are we just looking for the message date? */
if (mode == MT_DATE) while(ch = *mptr++, (ch!='M' && ch!=0)) {
buf[0] = 0;
+/*
+ * Open a component of a MIME message as a download file
+ */
+void cmd_opna(char *cmdbuf)
+{
+ char msgid[256];
+
+ extract(msgid, cmdbuf, 0);
+ extract(CC->desired_section, cmdbuf, 1);
+
+ output_message(msgid, MT_DOWNLOAD, 0);
+ }
+
+
+
/*
* Message base operation to send a message to the master file
* (returns new message number)
void do_help_subst (char *buffer);
void memfmout (int width, char *mptr, char subst);
void output_mime_parts(char *);
-time_t output_message (char *msgid, int mode, int headers_only);
+time_t output_message (char *, int, int);
void cmd_msg0 (char *cmdbuf);
void cmd_msg2 (char *cmdbuf);
void cmd_msg3 (char *cmdbuf);
void cmd_msg4 (char *cmdbuf);
+void cmd_opna (char *cmdbuf);
long int send_message (char *message_in_memory, size_t message_length,
int generate_id);
void loadtroom (void);
int client_socket;
char *ExpressMessages;
int cs_pid; /* session ID */
- char cs_room[20]; /* current room */
+ char cs_room[ROOMNAMELEN]; /* current room */
time_t cs_lastupdt; /* time of last update */
time_t lastcmd; /* time of last command executed */
time_t lastidle; /* For computing idle time */
char last_pager[32]; /* The username of the last pager */
int FloorBeingSearched; /* This is used by cmd_lrms() etc. */
+ char desired_section[64]; /* This is used for MIME downloads */
};
typedef struct CitContext t_context;
#define MT_RFC822 2 /* RFC822 */
#define MT_RAW 3 /* IGnet raw format */
#define MT_MIME 4 /* MIME-formatted message */
+#define MT_DOWNLOAD 5 /* Download a component */
/*
OK (file is open)
If the file is successfully opened, OK will be returned, along with the
-size (in bytes) of the file, and (in version 5.00 and above) the time of last
-modification.
+size (in bytes) of the file, the time of last modification (if applicable),
+the filename (if known), and the MIME type of the file (if known).
CLOS (CLOSe the download file)
This command is probably temporary, until we can work some sort of scheduler
into the system. It is implemented in the serv_expire module.
+
+
+
+ MSG4 (read MeSsaGe, mode 4 -- enumerate MIME parts)
+
+ FIX ... do the writeup for this once it's done.
+
+
+
+ OPNA (OPeN Attachment)
+
+ Opens, as a download file, a component of a MIME-encoded message. The two
+parameters which must be passed to this command are the message number and the
+name of the desired section. If the message or section does not exist, an
+appropriate ERROR code will be returned; otherwise, if the open is successful,
+this command will succeed returning the same information as an OPEN command.