wbpop.c - siizuka/Web-Based-POP3-Service-C- GitHub Wiki
/---------------------------------------------------------------------- * * * COPYRIGHT©1997-2000 IIZUKA,Shinji. All Right reserved. * * * * wbpop - WEB based POP3 client * * * * author : IIZUKA,Shinji([email protected]) * * * ---------------------------------------------------------------------- * * * parmeters(all parameters are retrieved by POST method) * * * * s : pop3 server name * * u : user name * * p : password of user * * m : method * * c : command of method * * a : use apop when TRUE(1) * * t : port no(110 when blank) * * m = 0/none initial panel * * m = 1 console mode view * * m = 2 retrieve subject ( c = no of msg: all when zero ) * * m = 3 retrieve message ( c = no of msg: all when zero ) * * m = 4 delete subject ( c = no of msg: all when zero ) * * * ---------------------------------------------------------------------- * history: * * 1997.08.01 v1 created * * 1997.10.02 v2 add MIME decode process * * 1997.03.21 v3 Integrate wbmail.cgi * * 1998.03.23 v3.1 Change "new-line" to server * * 1998.03.25 v3.2 Decode user name and password * * 1998.04.20 v4 Update method to retrieve/delete mail * * Add dump mode(contents of mailbox only) * * 1998.05.27 v4.1 Add "-DLINUX" option for linux * * 1998.08.12 v4.2 Display size of mail in Header mode * * 1998.09.30 v4.3 enable to read the line starting "." * * 1998.10.02 v4.4 Buf fix for v4.3 * * 1998.10.02 v4.5 Enable user information definition * * 1999.01.26 v4.51 Bug fix for MIME-B Decode * * 2000.03.16 v4.6 APOP authorization * * Enable other than 110 socket no. * * 2002.04.07 v4.63 set alarm for troubled socket * ----------------------------------------------------------------------/ char *version = "Version 4.63(2002.04.07)"; char *copyright = "Copyright©1997-2002 IIZUKA,Shinji(<A HREF=\"mailto:[email protected]\">[email protected]</A>). All right reserved."; char *ident = "@(#)wbpop.c 2002.04.07 V4.63";
/* Include header files */ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> #include <sys/stat.h> #include <sys/signal.h> #include <stdarg.h> #include "md5.h"
#ifdef LINUX # include <sys/time.h> #else # include <time.h> #endif
#define WAITING 30
/---------------------------------------------------------------------- * * * Definition of macro constants / functions * * * ----------------------------------------------------------------------/
/* ------------------------------------ * * Logical type * * ------------------------------------ */ #define Boolean int #define FALSE 0 #define TRUE !(FALSE)
/* ------------------------------------ * * MIME header * * ------------------------------------ */ #define HEADER_CONTENT_TYPE "Content-Type: " #define HEADER_CONTENT_DISPOSITION "Content-Disposition: " #define HEADER_SUBJECT "Subject: " #define HEADER_FROM "From: " #define HEADER_DATE "Date: "
/* ------------------------------------ * * MIME encoding * * ------------------------------------ / #define BE_HEAD "=?ISO-2022-JP?B?" / Header of MIME B encode / #define QE_HEAD "=?ISO-2022-JP?Q?" / Header of MIME Q encode / #define L_E_HEAD 16 / Length of BE_HEAD,QE_HEAD */
#define is_B_header(a) !(strncmp(ucasea),L_E_HEAD),BE_HEAD,L_E_HEAD #define is_Q_header(a) !(strncmp(ucasea),L_E_HEAD),QE_HEAD,L_E_HEAD #define is_mime_header(a) is_B_header((a)||(is_Q_headera))
/* for decoding MIME encoded string */ #define decode_mime(a,b,c,d) (is_B_headera?decode_mime_Ba),(b),(c),(d:decode_mime_Qa),(b),(c),(d)
/* decide in/out of JIS escaped characters */ #define is_jis_in(a) (!(strncmpa),jis_in,3) #define is_jis_out(a) (!(strncmpa),jis_out1,3||!(strncmpa),jis_out2,3)
/* ------------------------------------ * * Method of CGI * * ------------------------------------ */ #define F_METHOD "m" #define F_HOST "s" #define F_USER "u" #define F_PASSWD "p" #define F_APOP "a" #define F_PORTNO "t"
#define FM_CONSOLE '1' #define FM_HEAD '2' #define FM_PROPER '3' #define FM_DUMP '5' #define FM_INIT (!(FM_CONSOLE)&&!(FM_HEAD)&&!(FM_PROPER)&&!(FM_DUMP))
/* ------------------------------------ * * other definition of constant * * ------------------------------------ / #define HUGE 4096 / bytes per line (long) / #define LINESIZ 256 / bytes per line (command) / #define PTR_FOR_NULL (void *)"\0" / pointer for Null / #define is_eom(str) (str[0]=='.'&&str[1]!='.') / end of mail */
/* ------------------------------------ * * other definition of constant * * ------------------------------------ / #define memalloc(x,c) (x *)mallocsizeof(x*c) / allocate (length of x)c bytes */ #define open_mon() stdout / open output area */
/---------------------------------------------------------------------- * * * Global variables * * * ----------------------------------------------------------------------/ FILE fp_mon; / output file [ = stdout ] / char *pgmname; / name of this program [cmdline level] / char *cginame; / name of this program [cgi level] / Boolean is_dump = FALSE; / Use dump mode if TRUE */
char s_line[LINESIZ]; /* command line to send to POP3 server / char r_line[HUGE]; / response line from POP3 server */
unsigned mail_size; / size[octet] of mail */ unsigned len_mail_size;
int fd; /* Socket */
/* socket interface (read UNIX manual if unable to understand) */ static struct sockaddr_in sin = { AF_INET };
/* MIME B encoding table. i.e: t64['A'] == 0 / char t64[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / 0 / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / 1 / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, / 2 / 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, / 3 / -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, / 4 / 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, / 5 / -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, / 6 / 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, / 7 / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / 8 / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / 9 / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / A / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / B / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / C / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / D / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, / E / -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; / F / / 0 1 2 3 4 5 6 7 8 9 A B C D E F */
char jis_in[3] = { 0x1b, 0x24, 0x42 }; /* shift-in to ISO-2022-JP / char jis_out1[3] = { 0x1b, 0x28, 0x42 }; / shift-out from ISO-2022-JP */ char jis_out2[3] = { 0x1b, 0x28, 0x4A };
char *getenv();
/ * base libraries * /
/---------------------------------------------------------------------- * * * on_alarm() - exit itself * * * ----------------------------------------------------------------------/ int on_alarm() { exit(0); }
/---------------------------------------------------------------------- * * * mon_print() - print into blowser * * * ----------------------------------------------------------------------/ int mon_print ( Boolean flag, char *format, …) { va_list arg; int nbyte;
if ( flag == TRUE ) { va_start(arg, format); nbyte = vfprintf(fp_mon, format, arg); va_end(arg); return (nbyte); } else { return ( 0 ); } } /*----------------------------------------------------------------------* * * * mon_flush() - flush buffer into blowser * * * *----------------------------------------------------------------------*/ void mon_flush ( Boolean flag ) { if ( flag == TRUE ) { fflush( fp_mon ); } }
/---------------------------------------------------------------------- * * * hex2int() - get number from hex-expressed charcter * * * ----------------------------------------------------------------------/ int hex2int( int c ) { switch ( c & 0xff ) { case '0' : return ( 0 ); case '1' : return ( 1 ); case '2' : return ( 2 ); case '3' : return ( 3 ); case '4' : return ( 4 ); case '5' : return ( 5 ); case '6' : return ( 6 ); case '7' : return ( 7 ); case '8' : return ( 8 ); case '9' : return ( 9 ); case 'a' : case 'A': return ( 10 ); case 'b' : case 'B': return ( 11 ); case 'c' : case 'C': return ( 12 ); case 'd' : case 'D': return ( 13 ); case 'e' : case 'E': return ( 14 ); case 'f' : case 'F': return ( 15 ); default : return( -1 ); } }
/---------------------------------------------------------------------- * * * str2int() - convert string to integer(zero if not number) * * * ----------------------------------------------------------------------/ int str2int( char *str ) { int ix;
for ( ix = 0; ix < strlen(str); ix++ ) { if ( !(isdigit(str[ix])) ) { return( 0 ); } } return( atoi( str ) ); }
/---------------------------------------------------------------------- * * * ucase() - get Upper case of string * * * ----------------------------------------------------------------------/ char *ucase( char *s, int l ) { int len, ix; static char buf[HUGE];
len = ( l <= 0 ? strlen(s) : l ); for ( ix = 0; ix < len; ix++) { buf[ix] = (('a' <= s[ix] && s[ix] <= 'z') ? s[ix] - 0x20 : s[ix]) & 0xff; } buf[ix] = '\0'; return ( buf ); }
/---------------------------------------------------------------------- * * * get_date_str() - get string format of date * * * ----------------------------------------------------------------------/
char get_date_str () { static char ymd_hms[18+1]; / return values / struct tm *ptr; / pointer for date */ struct tm *localtime(); time_t time(), nseconds;
nseconds = time (NULL); ptr = localtime (&nseconds);
sprintf(ymd_hms, "%d.%d.%d %d:%d:%d", ptr->tm_year + 1900, ptr->tm_mon + 1, ptr->tm_mday, ptr->tm_hour, ptr->tm_min, ptr->tm_sec); return (ymd_hms); }
/ * network libraries * /
/---------------------------------------------------------------------- * * * connect_to_remote_host ( ) - create connecton * * * ----------------------------------------------------------------------/ int connect_to_remote_host( char host, int portno ) { int rc; / int s; */
struct hostent *hp; struct servent *sp;
sin.sin_family = AF_INET;
mon_print (!(is_dump), "<FONT COLOR=green>resolving %s. ", host ); mon_print (!(is_dump), "please wait...<BR></FONT>\n" ); mon_flush(!(is_dump));
sp = malloc ( sizeof( struct servent ) ); sp->s_port = htons(portno);
if ( ( hp = gethostbyname( host ) ) == 0 ) { mon_print( !(is_dump), "<FONT COLOR=red>cannot resolve POP" ); mon_print( !(is_dump), " server %s</FONT><BR>\n", host ); mon_print( !(is_dump), "<FONT COLOR=red>It may be due to too " ); mon_print( !(is_dump), "many connections or server name " ); mon_print( !(is_dump), "mismatch.</FONT><BR>\n" ); mon_flush( !(is_dump) ); return ( -1 ); } sin.sin_port = sp->s_port; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { mon_print( !(is_dump), "<FONT COLOR=red>fatal: failed to call socket() (%s)</FONT><BR>\n", strerror( errno ) ); mon_flush( !(is_dump) ); return ( fd ); }
sin.sin_family = hp->h_addrtype; /* bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); */ memcpy(&sin.sin_addr, hp->h_addr, hp->h_length); sin.sin_port = sp->s_port;
mon_print( !(is_dump), "<FONT COLOR=green>connecting %s using port no. %d...<BR></FONT>\n", host,portno );
alarm( WAITING ); rc = connect(fd, (struct sockaddr *) & sin, sizeof(sin)); alarm( 0 );
if ( rc < 0) { mon_print( !(is_dump), "<FONT COLOR=red>failed to call connect() (%s)</FONT><BR>\n",strerror( errno ) ); mon_flush( !(is_dump) ); mon_flush( !(is_dump) ); mon_print( !(is_dump),"<FONT COLOR=red>It may be due to too many connections or server down.</FONT><BR>\n" ); mon_flush( !(is_dump) ); shutdown( fd, 2 ); close ( fd ); return ( rc ); } else { return ( fd ); } }
/---------------------------------------------------------------------- * * * poll_fd() - poll file * * * ----------------------------------------------------------------------/ int poll_fd ( int fd, char *mode, int poll_time ) { fd_set fds; int nfound; struct timeval timeout;
FD_ZERO ( &fds ); FD_SET (fd, &fds); timeout.tv_sec = poll_time; timeout.tv_usec = 0;
if ( *mode == 'r' ) { nfound = select(fd + 1, &fds, 0, 0, &timeout); } else if ( *mode == 'w' ) { nfound = select(fd + 1, 0, &fds, 0, &timeout); }
if ( nfound < 0 ) { return ( -1 ); } else if ( nfound == 0 ) { return ( 0 ); } else { if ( FD_ISSET ( fd, &fds ) ) { return ( 1 ); } else { return ( 0 ); } } }
/---------------------------------------------------------------------- * * * readline() - read one line from fd * * * ----------------------------------------------------------------------/ int readline ( int fd, char *buf ) { int ix; char c, nbyte;
ix = 0; while (1) { alarm( WAITING ); nbyte = read ( fd, &c, 1 ); alarm( 0 ); if ( nbyte <= 0 ) { buf[ix] = '\0'; return ( nbyte < 0 ? nbyte : ix ) ; } if ( c == '\n' ) { if ( ix > 0 && buf[ix - 1] == '\r' ) { buf[ix++] = c; buf[ix] = '\0'; return ( ix ); } else { /* No Statement */; } } else { buf[ix++] = c; } } }
/---------------------------------------------------------------------- * * * write_to_sock() - write to remote connection * * * ----------------------------------------------------------------------/ int write_to_sock ( int fd, char *line ) { int len, nbyte;
len = strlen ( line ); alarm( WAITING ); nbyte = write ( fd, line, len ); alarm( 0 ); if ( nbyte != len ) { mon_print( !(is_dump), "<FONT COLOR=red>fatal: system error occured to call write() (%s).</FONT>", strerror( errno ) ); mon_flush( !(is_dump) ); return ( -1 ); } else { return ( nbyte ); } }
/---------------------------------------------------------------------- * * * print_info() - Display Information area * * * ----------------------------------------------------------------------/ void print_info ( char *infofile ) { FILE * fp; char buf[HUGE];
if ( ( fp = fopen ( infofile, "r" ) ) != NULL ) { while ( ( fgets ( buf, HUGE, fp ) ) != NULL ) { fputs ( buf, fp_mon ); mon_flush(!(is_dump)); } fclose ( fp ); } }
/---------------------------------------------------------------------- * * * signal handler * * * ----------------------------------------------------------------------/ void on_end() { if ( !is_dump ) { #ifdef USER_INFO_2 print_info( USER_INFO_2 ); #endif mon_print( !(is_dump), "</BODY></HTML>" ); } }
void on_intr() { mon_print( !(is_dump),"<FONT COLOR=red>Interrupt caught.process terminated.<BR></FONT>\n" ); mon_flush( TRUE ); exit ( 0 ); }
/ * CGI libraries * /
/---------------------------------------------------------------------- * * * get_cginame() - just as name * * * ----------------------------------------------------------------------/
char *get_cginame ( char *dest ) { char *p; int ix, max_ix, ix_set;
for ( ix = strlen( dest ) - 1; ix >= 0 && dest[ix] != '/'; ix--) ;
p = memalloc( char, strlen( dest ) - ix );
ix_set = 0; for ( ix++; dest[ix] != '\0'; ix++) { p[ix_set++] = dest[ix]; }
p[ix_set] = '\0'; return ( p ); }
/---------------------------------------------------------------------- * * * url_decode() - decode URL-encoded Data * * * ----------------------------------------------------------------------/
char url_decode ( char *in ) { int ix, ix_set; / as you assume / static char out[LINESIZ]; / area for return value */
int len; len = strlen(in);
for ( ix = ix_set = 0; ix < len; ix++) { if ( in[ix] == '+' ) { out[ix_set++] = ' '; } else if ( in[ix] == '%' && ix < len - 2 ) { out[ix_set++] = 0xff & (hex2int(in[ix+1]) * 0x10 + hex2int(in[ix+2])); ix += 2; } else { out[ix_set++] = in[ix]; } } out[ix_set] = '\0'; return ( out ); }
/---------------------------------------------------------------------- * * * query_parm() - query cgi parameter * * * ----------------------------------------------------------------------/ char *query_parm( char *key ) { static char *query_key[256], *query_val[256]; int content_length; char *envp, *query_string; int ix;
if ( key == NULL ) { /* decide whether method to retrieve parameters */ envp = getenv ( "REQUEST_METHOD" ); if ( envp == NULL || *envp == '\0' ) { query_key[0] = NULL; return ( NULL ); } /* set parameters into query_key[] */ if ( !(strncmp ( envp, "GET", 3 ) ) ) { envp = getenv( "QUERY_STRING" ) ; if ( envp == NULL || *envp == '\0' ) { query_key[0] = ( char *) malloc( sizeof (char *) ); query_key[0] = NULL; return ( NULL ); } else { query_string = malloc( strlen(getenv("QUERY_STRING")) + 1 ); strcpy ( query_string, getenv("QUERY_STRING")); } } else { envp = getenv( "CONTENT_LENGTH" ); content_length = atoi( envp ); query_string = malloc( content_length + 1 ); read ( 0, query_string, content_length ); query_string[content_length] = '\0'; } /* pharse into array */ for ( ix = 0; 1 ; ix ++) { query_key[ix] = strtok(ix == 0 ? query_string : NULL, "=" ); if ( query_key[ix] == NULL ) { query_val[ix] = NULL; break; } query_val[ix] = strtok(NULL, "&" ); if ( query_val[ix] == NULL ) { break; } } return ( NULL ) ; } else { for ( ix = 0 ; query_key[ix] != NULL; ix++) { if ( strlen( query_key[ix] ) == strlen( key ) ) { if ( !strcmp ( query_key[ix], key ) ) { return ( query_val[ix] ); } } } return ( NULL ) ; } }
/---------------------------------------------------------------------- * * * real_parm() - query "real" parm for CGI * * (returns pointer for Null when parm == NULL) * * * ----------------------------------------------------------------------/ char *real_parm( char *key ) { char *p; p = query_parm( key ); return ( p == NULL ? PTR_FOR_NULL : p ); }
/ * functions * /
/---------------------------------------------------------------------- * * * input_cmd() - send cmd to POP server until max retry(2) * * reached or execution of command successed * * * ----------------------------------------------------------------------/ int input_cmd ( int fd, char cmd, char *res ) { int ix; / You already know what it is / char cmd_with_crnl[LINESIZ]; / cmd + \r + \n */
sprintf ( cmd_with_crnl, "%s\r\n", cmd );
for ( ix = 0; ix < 3; ix++) { mon_print( !(is_dump),"<FONT COLOR=blue>%s<BR></FONT>\n", cmd ); mon_flush(!(is_dump)); if ( write_to_sock ( fd, cmd_with_crnl ) < 0 ) { return ( 0 ); } readline ( fd, res ); mon_print( !(is_dump), "%s<BR>\n", res ); if ( res[0] != '-' ) { return ( 1 ); } } return ( 0 ); }
/---------------------------------------------------------------------- * * * input_cmd_crypt() - send cmd to POP server until max retry(2) * * reached or execution of command successed * * * ----------------------------------------------------------------------/ int input_cmd_crypt ( int fd, char cmd, char *res ) { int ix; static char c_buf[LINESIZ]; char cmd_with_crnl[LINESIZ]; / cmd + \r + \n */
strcpy ( c_buf, cmd ); sprintf ( cmd_with_crnl, "%s\r\n", cmd );
if ( !is_dump ) { for ( ix = 4; ix < strlen( c_buf ); ix++) { switch ( c_buf[ix] ) { case ' ': case '\r': case '\n' : break; default : c_buf[ix] = '*'; } } }
for ( ix = 0; ix < 3; ix++) { mon_print( !(is_dump), "<FONT COLOR=blue>%s<BR></FONT>\n", c_buf ); mon_flush(!(is_dump)); if ( write_to_sock ( fd, cmd_with_crnl ) < 0 ) { return ( 0 ); } readline ( fd, res );
mon_print( !(is_dump),"%s<BR>\n", res ); if ( res[0] != '-' ) { return ( 1 ); } } return ( 0 ); }
/---------------------------------------------------------------------- * * * retr_mail_list() - retrieve number of mail(s) * * * ----------------------------------------------------------------------/ int retr_mail_list(int fd) { int mail_cnt; int is_allocatable;
if ( !( input_cmd ( fd, "LIST", r_line ) ) ) { alarm( WAITING ); shutdown( fd, 2 ); close ( fd ); alarm( 0 ); exit ( 0 ); }
len_mail_size = 0; if ( ( mail_size = ( unsigned *) malloc( sizeof(unsigned) ) ) == NULL ) { is_allocatable = FALSE; } else { is_allocatable = TRUE; }
mail_cnt = 0; while ( readline ( fd, r_line ) > 0 ) { mon_print( !(is_dump),"%s<BR>\n", r_line ); mon_flush( !(is_dump) );
if ( r_line[0] == '.' ) { break; } else { mail_cnt++; mail_cnt = atoi ( strtok( r_line, " " )); if ( is_allocatable ) { if ( (mail_size = (unsigned *)realloc(mail_size, mail_cnt * sizeof(unsigned *)) ) != NULL ) { mail_size[mail_cnt - 1] = atoi( strtok( NULL, "\r\n " )); len_mail_size++; } else { is_allocatable = FALSE; } } } }
return ( mail_cnt ); }
/---------------------------------------------------------------------- * * * is_mail_to_process() - get whether this mail is to process * * * ----------------------------------------------------------------------/ Boolean is_mail_to_process(int no, char key) { char sk[256];
sprintf ( sk, "%c%d", key, no ); if ( (query_parm(sk) != NULL) && !(strcmp(ucase(query_parm(sk), 0), "ON")) ) { return ( TRUE ) ; } else { return ( FALSE ); } }
/---------------------------------------------------------------------- * * * display_input_area() - display input area of server,user,passwd * * * ----------------------------------------------------------------------/
void display_input_area ( /* No Argument */ ) { mon_print( TRUE, "<TABLE BORDER=1>\n" );
mon_print( TRUE, "<TR>\n" ); mon_print( TRUE, "<TD>DNS name of your POP3 server</TD>\n" ); mon_print( TRUE, "<TD><INPUT TYPE=text NAME=%s SIZE=60 value=%s></TD>\n", F_HOST, real_parm(F_HOST) ); mon_print( TRUE, "</TR>\n" );
mon_print( TRUE, "<TR>\n" ); mon_print( TRUE, "<TD>Port number of your POP3 server<BR>(110 when blank)</TD>\n" ); mon_print( TRUE, "<TD><INPUT TYPE=text NAME=%s SIZE=10 VALUE=%s></TD>\n", F_PORTNO, (*real_parm(F_PORTNO)) != '\0' ? real_parm(F_PORTNO) : "110" ); mon_print( TRUE, "</TR>\n" );
mon_print( TRUE, "<TR>\n" ); mon_print( TRUE, "<TD>Your account</TD>\n" ); mon_print( TRUE, "<TD><INPUT TYPE=text NAME=%s SIZE=60 value=%s></TD>\n", F_USER, real_parm(F_USER) ); mon_print( TRUE, "</TR>\n" );
mon_print( TRUE, "<TR>\n" ); mon_print( TRUE, "<TD>Password for your account</TD>\n" ); mon_print( TRUE, "<TD><INPUT TYPE=password NAME=%s SIZE=60></TD>\n", F_PASSWD ); mon_print( TRUE, "</TR>\n" );
mon_print( TRUE, "</TABLE>\n" );
mon_print( TRUE, "<P><INPUT TYPE=radio NAME=%s VALUE=%c>Console mode\n", F_METHOD, FM_CONSOLE );
mon_print( TRUE, "<INPUT TYPE=radio NAME=%s VALUE=%c %s>Header only\n", F_METHOD, FM_HEAD, (*real_parm(F_METHOD)) != FM_HEAD ? "CHECKED" : PTR_FOR_NULL );
mon_print( TRUE, "<INPUT TYPE=radio NAME=%s VALUE=%c %s>Retrieve/Delete Seleced Mail\n", F_METHOD, FM_PROPER, (*real_parm(F_METHOD)) == FM_HEAD ? "CHECKED" : PTR_FOR_NULL );
mon_print( TRUE, "<INPUT TYPE=radio NAME=%s VALUE=%c>Dump Mode\n", F_METHOD, FM_DUMP );
mon_print( TRUE, "<BR><INPUT TYPE=checkbox NAME=%s>Use APOP authorization<BR>\n", F_APOP );
mon_print( TRUE, "<SCRIPT LANGUAGE=\"JavaScript\">\n" ); mon_print( TRUE, "<!--//\n" ); mon_print( TRUE, "document.write ( \'<INPUT TYPE=button value=\"Execute\" onClick=\"execute_it();return(0);\">\' );\n" ); mon_print( TRUE, "//-->\n" ); mon_print( TRUE, "</SCRIPT>\n" ); mon_print( TRUE, "<NOSCRIPT>\n" ); mon_print( TRUE, "<INPUT TYPE=submit value=\"Execute\">\n" ); mon_print( TRUE, "</NOSCRIPT>\n" );
mon_print( TRUE, "<INPUT TYPE=reset value=\"Reset\">\n" );
mon_print( TRUE, "</P>\n" ); mon_flush(!(is_dump)); }
/---------------------------------------------------------------------- * * * print_js_head() - print header line of javascript * * * ----------------------------------------------------------------------/ void print_js_head() { mon_print( TRUE, "<SCRIPT LANGUAGE=\"JavaScript\">\n"); mon_print( TRUE, "<!--//\n"); mon_print( TRUE, "read_key = \"R\"; delete_key = \"D\";\n"); mon_print( TRUE, "function execute_it( ) {\n"); mon_print( TRUE, " for ( ix = 0; ix < document.f.m.length && document.f.m[ix].value != 3; ix ) ;\n"); mon_print( TRUE, " if ( document.f.m[ix].value == 3 ) {\n"); mon_print( TRUE, " if ( document.f.m[ix].checked ) {\n"); mon_print( TRUE, " check_cnt = 0\n"); mon_print( TRUE, " for ( ix = 0; ix < document.f.elements.length; ix ) {\n"); mon_print( TRUE, " if ( document.f.elements[ix].type == \"checkbox\" ) {\n"); mon_print( TRUE, " ident = document.f.elements[ix].name.substring(0,1);\n"); mon_print( TRUE, " if ( ident == read_key || ident == delete_key ) {\n"); mon_print( TRUE, " if ( document.f.elements[ix].checked == true ) {\n"); mon_print( TRUE, " check_cnt++;\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " if ( check_cnt < 1 ) {\n"); mon_print( TRUE, " alert( \"Check \\\"Read\\\" checkbox or \\\"Delete\\\" checkbox.\" );\n"); mon_print( TRUE, " return(0);\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " }\n");
mon_print( TRUE, " if ( document.f.s.value == \"\" ) {\n"); mon_print( TRUE, " alert( \"Input the name of your POP3 Server.\" );\n"); mon_print( TRUE, " document.f.s.focus();\n"); mon_print( TRUE, " return(0);\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " if ( document.f.u.value == \"\" ) {\n"); mon_print( TRUE, " alert( \"Input your account.\" );\n"); mon_print( TRUE, " document.f.u.focus();\n"); mon_print( TRUE, " return(0);\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " if ( document.f.p.value == \"\" ) {\n"); mon_print( TRUE, " alert( \"Input the password of your account.\" );\n"); mon_print( TRUE, " document.f.p.focus();\n"); mon_print( TRUE, " return(0);\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " document.f.submit();\n"); mon_print( TRUE, "}\n");
mon_print( TRUE, "//-->\n"); mon_print( TRUE, "</SCRIPT>\n"); mon_print( TRUE, "<BR>\n" ); }
/---------------------------------------------------------------------- * * * print_js_select_all_mail() - as the name of function * * * ----------------------------------------------------------------------/ void print_js_select_all_mail() { mon_print( TRUE, "<SCRIPT LANGUAGE=\"JavaScript\">\n"); mon_print( TRUE, "<!--//\n"); mon_print( TRUE, "function check_all( k,b ) {\n"); mon_print( TRUE, " for ( ix = 0; ix < document.f.elements.length; ix++ ) {\n"); mon_print( TRUE, " if ( document.f.elements[ix].type == \"checkbox\" ) {\n"); mon_print( TRUE, " if ( document.f.elements[ix].name.substring(0,1) == k ) { \n"); mon_print( TRUE, " if ( document.f.elements[ix].checked != b ) { \n"); mon_print( TRUE, " document.f.elements[ix].click();\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, " }\n"); mon_print( TRUE, "}\n");
mon_print( TRUE, "//-->\n"); mon_print( TRUE, "</SCRIPT>\n"); }
/---------------------------------------------------------------------- * * * print_javascript_indicate() - as the name of function * * * ----------------------------------------------------------------------/ void print_javascript_indicate() { mon_print( TRUE, "<SCRIPT LANGUAGE=\"JavaScript\">\n"); mon_print( TRUE, "<!--//\n");
mon_print( TRUE, "document.write ( '<INPUT TYPE=BUTTON VALUE=\"ON all(read)\" onClick=\"check_all(read_key,true);return(0)\">');\n"); mon_print( TRUE, "document.write ( '<INPUT TYPE=BUTTON VALUE=\"OFF all(read)\" onClick=\"check_all(read_key,false);return(0)\"> ');\n"); mon_print( TRUE, "document.write ( '<INPUT TYPE=BUTTON VALUE=\"ON all(del)\" onClick=\"check_all(delete_key,true);return(0)\">');\n"); mon_print( TRUE, "document.write ( '<INPUT TYPE=BUTTON VALUE=\"OFF all(del)\" onClick=\"check_all(delete_key,false);return(0)\">');\n"); mon_print( TRUE, "//-->\n"); mon_print( TRUE, "</SCRIPT><BR>\n"); }
/---------------------------------------------------------------------- * * * display_initial_panel() - just as name of function * * * ----------------------------------------------------------------------/ int display_initial_panel() { #ifdef USR_NPH_MODE mon_print( TRUE, "HTTP/1.0 200 OK\n" ); #endif mon_print( TRUE, "Content-type: text/html\n\n" ); mon_print( TRUE, "<HTML><HEAD><TITLE>Web Based POP3 Service" ); mon_print( TRUE, "</TITLE></HEAD><BODY BGCOLOR=white><CENTER>" ); mon_print( TRUE, "<FONT SIZE=+2>Web Based POP3 Service</FONT>" ); mon_print( TRUE, "</CENTER><P>" ); display_copyright( "RIGHT" ); mon_print( TRUE, " <FORM NAME=f METHOD=POST ACTION=\"%s\"></P>\n", cginame ); display_input_area ( ) ; mon_print( TRUE, "</FORM>\n" ); }
/---------------------------------------------------------------------- * * * display_copyright() - just as name of function * * * ----------------------------------------------------------------------/ int display_copyright(char *align) { mon_print( TRUE, "<P ALIGIN=%s>", align ); mon_print( TRUE, "%s.<BR>\n", version ); mon_print( TRUE, "%s<BR>\n", copyright ); mon_print( TRUE, " This page is served "AS IS"." ); mon_print( TRUE, "Use this service at your own risk</P>\n" ); mon_print( TRUE, "</FONT>\n" ); print_js_head();
#ifdef USER_INFO_1 print_info( USER_INFO_1 ); #endif }
/---------------------------------------------------------------------- * * * is_url_char() - decide whether this charcter is a part of URL * * * ----------------------------------------------------------------------/
Boolean is_url_char ( unsigned int c ) { if ( 0x21 ⇐ (c & 0xff) && (c & 0xff) ⇐ 0x7e ) { switch ( c & 0xff ) { case '<' : case '>' : case '(' : case ')' : case '[' : case ']' : case '{' : case '}' : case ',' : case '*' : case '$' : case '’ : case ';' : case '^' : case '\\': case '\"': case '\'': return ( FALSE ); default: return ( TRUE ); } } else { return ( FALSE ); } }
/---------------------------------------------------------------------- * * * decode_mime_Q ( ) - convert MIME Q encodeed data * * * ----------------------------------------------------------------------/
int decode_mime_Q ( unsigned char *in, unsigned char *out, int *in_len, int *out_len ) { unsigned char *p;
int ix, ix_out;
/* determin start pointer of data area */ p = in + strlen ( QE_HEAD );
ix = 0; ix_out = 0; while ( ix < strlen ( p ) && strncmp( p + ix, "?=", 2 ) != 0 ) { switch ( p[ix] ) { case '=': out[ix_out++] = 0xff & (hex2int(p[ix+1]) * 16 + hex2int(p[ix+2])); ix += 3; break; case '_': out[ix_out++] = ' '; ix++; break; default: out[ix_out++] = p[ix++]; break; } } out[ix_out] = '\0';
*in_len = ix + strlen( QE_HEAD ) + 2; *out_len = ix_out; return ( ix_out ); }
/---------------------------------------------------------------------- * * * decode_mime_B ( ) - convert MIME B encodeed data * * * ----------------------------------------------------------------------/
int decode_mime_B ( unsigned char *in, unsigned char *out, int *in_len, int *out_len ) { unsigned char *p; char cv[3];
int ix, ix_out, ix_cv;
/* determin start pointer of data area */ p = in + strlen ( BE_HEAD );
ix = 0; ix_out = 0; while ( ix < strlen ( p ) && strncmp( p + ix, "?=", 2 ) != 0 ) { /* decode first character */ cv[0] = (( t64[p[ix]] << 2 ) & 0xfc ) + ((t64[p[ix+1]] >> 4 ) & 0x03); if ( p[ix+2] == '=' ) { ix_cv = 1; } else { cv[1] = (( t64[p[ix+1]] << 4 ) & 0xf0 ) + ((t64[p[ix+2]] >> 2 ) & 0x0f); if ( p[ix+3] == '=' ) { ix_cv = 2; } else { ix_cv = 3; cv[2] = (( t64[p[ix+2]] << 6 ) & 0xC0 ) + ( t64[p[ix+3]] & 0x3f); } } memcpy ( out + ix_out, cv, ix_cv ); ix += 4; ix_out += ix_cv; }
out[ix_out] = '\0';
*in_len = ix + strlen ( BE_HEAD ) + 2; *out_len = ix_out;
return ( ix_out ); }
/---------------------------------------------------------------------- * * * decode_str_of_mime () - convert mail into adequate format * * * ----------------------------------------------------------------------/
int decode_str_of_mime( char *in, long len, char *out ) { int ix, ix_out, cv_in_len, decoded_char; unsigned char *u_in, *u_out;
u_in = ( unsigned char *) in; u_out = ( unsigned char *) out;
/* decode all MIME character */ ix = 0, ix_out = 0; while ( ix < len - L_E_HEAD ) { if ( is_mime_header ( u_in + ix ) ) { decode_mime ( u_in + ix, u_out + ix_out, &cv_in_len, &decoded_char ); ix += cv_in_len; ix_out += decoded_char; } else { u_out[ix_out] = u_in[ix]; ix++; ix_out++; } }
memcpy ( (char *)u_out + ix_out, in + ix, len - ix + 1 ); out[ix_out + len - ix + 1 ] = '\0'; }
/---------------------------------------------------------------------- * * * strip_dummy_period () - strip dummy period * * * ----------------------------------------------------------------------/
int strip_dummy_period ( char *in ) { int ix, len;
len = strlen ( in );
if ( in[0] == '.' && len > 3 ) { for ( ix = 0; ix < len - 1; ix++) { in[ix] = in[ix + 1]; } ix--; } else { ix = len; } return ( ix ); }
/---------------------------------------------------------------------- * * * get_apop_hex_didgest() - get hex expression of MD5 digest * * for APOP authorization * * * ----------------------------------------------------------------------/ void get_apop_hex_didgest( char *line, char *password, char *apop_str ) { int ix,ix_set; char apop_salt[LINESIZ]; unsigned char digest[LINESIZ]; MD5_CTX context;
/* Find the start of timestamp */ for (ix = 0 ; line[ix] != '\0' && line[ix] != '<'; ix++ ); for (ix_set = 0; line[ix] != '\0' && line[ix] != '>'; ix++ ) { apop_salt[ix_set++] = line[ix]; } if( ix_set <= 1 ) { /* error if Null or '<' only */ *apop_str = '\0'; return; }
apop_salt[ix_set++] = '>'; apop_salt[ix_set] = '\0'; strcat(apop_salt, password );
MD5Init(&context); MD5Update(&context, (unsigned char *)apop_salt, strlen(apop_salt)); MD5Final(digest, &context);
for (ix = 0; ix < 16; ix++) { /* this ix is differnt from previous ix */ sprintf( apop_str + (ix * 2), "%02x", digest[ix]); } apop_str[ix * 2] = 0; return; }
/---------------------------------------------------------------------- * * * login_to_mail_server () - login * * * ----------------------------------------------------------------------/ int login_to_mail_server( int fd ) { int nbyte; static char apop_str[LINESIZ];
while ( 1 ) { if ( poll_fd ( fd, "r", 3 ) <= 0 ) { break; } nbyte = readline ( fd, r_line ); if ( nbyte <= 0 ) { break; } } mon_print( !(is_dump), "%s<BR>\n", r_line ); mon_flush( !(is_dump) );
*apop_str = '\0'; if ( strcmp( ucase(real_parm(F_APOP),0), "ON" ) == 0 ) { /* APOP authorization */ get_apop_hex_didgest( r_line, url_decode(real_parm(F_PASSWD)), apop_str ); if ( *apop_str != '\0' ) { sprintf ( s_line, "APOP %s %s\r\n",url_decode(real_parm(F_USER)), apop_str ); if ( !( input_cmd ( fd, s_line, r_line ) ) ) { alarm( WAITING ); shutdown( fd, 2 ); close ( fd ); alarm( 0 ); return ( -1 ); } return ( 0 ); } } if ( *apop_str == '\0' ) { /* when no APOP timestamp or old POP3 indicated */ /* old POP3 authorization */ /* Connect by user */ sprintf ( s_line, "USER %s", url_decode(real_parm(F_USER)) ); if ( !( input_cmd ( fd, s_line, r_line ) ) ) { alarm( WAITING ); shutdown( fd, 2 ); close ( fd ); alarm( 0 ); return ( -1 ); }
/* Ask password */ sprintf ( s_line, "PASS %s", url_decode(real_parm(F_PASSWD)) ); if ( !( input_cmd_crypt ( fd, s_line, r_line ) ) ) { alarm( WAITING ); shutdown( fd, 2 ); close ( fd ); alarm( 0 ); return ( -1 ); } return ( 0 ); } }
/---------------------------------------------------------------------- * * * set_anchor() - set <A> tag to line * * * ----------------------------------------------------------------------/ int set_anchor ( char *in, char *out, int *in_clen, int *out_clen ) { int ixi, set_len, ixo, max_ixi;
/* URL must be start with "http://" */ if ( strlen( in ) < 8 || strncmp(in, "http://", 7) != 0 || !(is_url_char(in[7])) ) { *in_clen = *out_clen = 0; return ( 0 ); }
/* set <A> tag */ memcpy ( out, "<A HREF=\"", 9 ); for ( ixi = 0, ixo = 9; is_url_char(in[ixi]); ixi++, ixo++) { out[ixo] = in[ixi]; } set_len = ixi; memcpy ( out + ixo, "\">", 2 ); ixo += 2;
memcpy ( out + ixo, in, set_len ); /* set content */ ixo += set_len;
memcpy ( out + ixo, "</A>", 4 ); /* set </A> tag */ ixo += 4;
/* set length */ *in_clen = ixi; *out_clen = ixo; }
/---------------------------------------------------------------------- * * * fmt_into_txt() - format input line into text * * * ----------------------------------------------------------------------/ int fmt_into_txt( unsigned char *r_line, int nbyte, unsigned char *buf ) { static Boolean is_shift_in = FALSE; int ix, ix_buf, len_from, len_to;
for ( ix = ix_buf = 0; ix < nbyte; ix++) { /* check shift mode */ if ( ix <= nbyte - 3 ) { if ( is_jis_in ( r_line + ix ) ) { is_shift_in = TRUE; } else if ( is_jis_out ( r_line + ix ) ) { is_shift_in = FALSE; } } /* when this char is non-sjis code */ if ( is_shift_in == FALSE ) { switch ( r_line[ix] ) { case '<': memcpy ( &(buf[ix_buf]), "<", 4 ); ix_buf += 4; break; case '>': memcpy ( &(buf[ix_buf]), ">", 4 ); ix_buf += 4; break; case '\"': memcpy ( &(buf[ix_buf]), """, 6 ); ix_buf += 6; break; case 'h': set_anchor( r_line + ix, buf + ix_buf, &len_from, &len_to ); if ( len_from <= 0 ) { buf[ix_buf] = r_line[ix]; ix_buf ++; } else { ix_buf += len_to; ix += len_from - 1; } break; default: buf[ix_buf] = r_line[ix]; ix_buf ++; break; } } else { buf[ix_buf] = r_line[ix]; ix_buf++; } } buf[ix_buf] = '\0'; return ( 1 ); }
/---------------------------------------------------------------------- * * * get_mail_date() - get date of mail * * * ----------------------------------------------------------------------/ char *get_mail_date ( char *line, char *date ) { int len; len = strlen( line );
switch ( line[6] ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': len = ( len > 26 ? 20: len - 6 ); if ( len > 0 ) { memcpy ( date, &(line[6]), len ) ; date[len] = '\0'; } else { date[0] = '\0'; } return( date ); default: len = ( len > 31 ? 20: len - 11 ); if ( len > 0 ) { memcpy ( date, &(line[11]), len ); date[len] = '\0'; } else { date[0] = '\0'; } return( date ); } }
/---------------------------------------------------------------------- * * * retrieve_header_line() - retrieve a line of header * * * ----------------------------------------------------------------------/ int retrieve_header_line( int fd, char *buf, Boolean is_first_indicate ) { static char prev_rec[HUGE]; static Boolean is_first = TRUE; static Boolean is_last = FALSE;
int len_buf, nbyte, len_line; int ofset;
is_first = is_first_indicate;
/* set from previous buffer */ if ( is_first ) { /* when no buffer */ is_first = FALSE; nbyte = readline ( fd, buf ); len_line = (nbyte <= 2 ? 0 : nbyte - 2); buf[len_line] = '\0'; len_buf = len_line; } else { len_buf = ( strlen(prev_rec) ); memcpy( buf, prev_rec, len_buf ); buf[len_buf] = '\0'; if ( is_last ) { *prev_rec = '\0'; /* set length of prev_rec to zero */ is_last = FALSE, is_first = TRUE; return( 0 ); } }
/* read current record */ for(;;) { nbyte = readline ( fd, r_line ); len_line = (nbyte <= 2 ? 0 : nbyte - 2); if ( ( len_line == 0 ) || /* EOF */ ( r_line[0] == '.' && r_line[1] != '.') || /* EOT */ ( r_line[0] != ' ' ) ) { /* EOL */ /* set previous buffer */ memcpy( prev_rec,r_line, len_line ); prev_rec[len_line] = '\0'; buf[len_buf] = '\0'; if ( ( r_line[0] == '.' && r_line[1] != '.') || ( strlen( r_line ) <= 2 ) ) { is_last = TRUE; len_buf = 0; } return( /* len_buf */ strlen( buf ) ); }
memcpy( buf + len_buf, r_line + 1, len_line - 1 ); len_buf += (len_line - 1); } }
/---------------------------------------------------------------------- * * * get_boundary() - same as the name of function * * * ----------------------------------------------------------------------/ int get_boundary( char buf, char *boundary ) { / Content-Type: multipart/mixed; boundary="=============================102331843129542" */ int pos; char *pos_boundary; int ix;
pos_boundary = strstr( buf, "boundary=" ); if ( pos_boundary == NULL ) { *boundary = '\0'; return(0); }
pos_boundary += 9; if ( *pos_boundary == '\"' ) { pos_boundary++; }
ix = 0; while( pos_boundary[ix] != '\0' && pos_boundary[ix] != '\"' ) { boundary[ix] = pos_boundary[ix]; ix++; } boundary[ix] = '\0'; return( 0 ); } /*----------------------------------------------------------------------* * * * get_mime_type() - same as the name of function * * * *----------------------------------------------------------------------*/ int get_mime_type( char *buf, char *mime_type ) { /* Content-Type: multipart/mixed; boundary="=============================102331843129542" */ int pos; char *pos_mime_type; int ix;
pos_mime_type = buf + 14; if ( pos_mime_type == NULL ) { *mime_type = '\0'; return(0); } ix = 0; while( pos_mime_type[ix] != '\0' && pos_mime_type[ix] != ';' ) { mime_type[ix] = pos_mime_type[ix]; ix++; } mime_type[ix] = '\0'; return( 0 ); }
/---------------------------------------------------------------------- * * * is_boundary() - same as the name of function * * * ----------------------------------------------------------------------/ Boolean is_boundary( char *str, char *boundary ) { int len_boundary;
len_boundary = strlen( boundary );
if ( ( strncmp( str, "--", 2 ) == 0 ) && ( strncmp( str + 2, boundary, len_boundary ) == 0 ) ) { if ( str[2 + len_boundary] == '\r' || str[2 + len_boundary] == '\n' || str[2 + len_boundary] == '\0' || str[2 + len_boundary] == ' ' ) { return( TRUE ); } else { return( FALSE ); } } else { return( FALSE ); } }
/---------------------------------------------------------------------- * * * is_last_boundary() - same as the name of function * * * ----------------------------------------------------------------------/ Boolean is_last_boundary( char *str, char *boundary ) { int len_boundary;
len_boundary = strlen( boundary );
if ( ( strncmp( str, "--", 2 ) == 0 ) && ( strncmp( str + 2, boundary, len_boundary ) == 0 ) && ( strncmp( str + 2 + len_boundary, "--", 2 ) == 0 ) ) { if ( str[4 + len_boundary] == '\r' || str[4 + len_boundary] == '\n' || str[4 + len_boundary] == '\0' || str[4 + len_boundary] == ' ' ) { return( TRUE ); } else { return( FALSE ); } } else { return( FALSE ); } }
/---------------------------------------------------------------------- * * * get_atatch_filename() - same as the name of function * * * ----------------------------------------------------------------------/ int get_attach_filename( char buf, char *filename ) { / Content-Type: application/octet-stream; name="profile.html"; */ int pos; char *pos_filename; int ix;
pos_filename = strstr( buf, "name=" ); if ( pos_filename == NULL ) { *filename = '\0'; return(0); }
pos_filename += 5; if ( *pos_filename == '\"' ) { pos_filename++; }
ix = 0; while( pos_filename[ix] != '\0' && pos_filename[ix] != '\"' ) { filename[ix] = pos_filename[ix]; ix++; } filename[ix] = '\0'; return( 0 ); }
/---------------------------------------------------------------------- * * * retrieve_each_head() - retrieve header * * * ----------------------------------------------------------------------/ int retrieve_each_head( Boolean is_display, int fd, char *subject,char *from,char *date,char *mime_type,char *boundary, char *filename ) { unsigned char buf[HUGE]; char buf1[HUGE]; unsigned char buf2[HUGE]; char encoded_filename[BUFSIZ]; int nbyte, len_buf1;
if ( subject != NULL ) { *subject = '\0'; }; if ( from != NULL ) { *from = '\0'; }; if ( date != NULL ) { *date = '\0'; }; if ( mime_type != NULL ) { *mime_type = '\0'; }; if ( boundary != NULL ) { *boundary = '\0'; }; if ( filename != NULL ) { *filename = '\0'; };
/* Process reply */ nbyte = retrieve_header_line( fd, buf, TRUE ); while( nbyte > 0 ) { /* process buffer */ if ( boundary != NULL && *boundary == '\0' && strncmp( buf, HEADER_CONTENT_TYPE, strlen(HEADER_CONTENT_TYPE) ) == 0 ) { get_boundary( buf, boundary ); } if ( mime_type != NULL && *mime_type == '\0' && strncmp( buf, HEADER_CONTENT_TYPE, strlen(HEADER_CONTENT_TYPE) ) == 0 ) { get_mime_type( buf, mime_type ); } if ( filename != NULL && *filename == '\0' && strncmp( buf, HEADER_CONTENT_DISPOSITION, strlen(HEADER_CONTENT_DISPOSITION) ) == 0 ) { get_attach_filename( buf, encoded_filename ); decode_str_of_mime ( encoded_filename, nbyte, buf1 ); fmt_into_txt ( buf1, strlen(buf1), filename ); }
decode_str_of_mime ( buf, nbyte, buf1 ); fmt_into_txt ( buf1, strlen(buf1), buf2 ); if ( is_display ) { mon_print( TRUE, "%s\n", buf2 ); }
if ( subject != NULL && *subject == '\0' && strncmp ( buf2, HEADER_SUBJECT, strlen(HEADER_SUBJECT) ) == 0 ) { memcpy ( subject, &(buf2[9]), strlen(buf2) - 9 ); subject[strlen(buf2) - 9] = '\0'; } else if ( from != NULL && *from == '\0' && strncmp ( buf2, HEADER_FROM, strlen(HEADER_FROM) ) == 0 ) { memcpy ( from, &(buf2[6]), strlen(buf2) - 6 ); from[strlen(buf2) - 6] = '\0'; } else if ( date != NULL && *date == '\0' && strncmp ( buf2, HEADER_DATE, strlen(HEADER_DATE) ) == 0 ) { get_mail_date( buf2, date ); } nbyte = retrieve_header_line( fd, buf, FALSE ); } }
/------------------------------------------------------------------------------ * * * retrieve_related_message() - retrieve contents of alternative message * * * ------------------------------------------------------------------------------/ int retrieve_related_message ( int fd, char* boundary ) { int nbyte; unsigned char buf[HUGE]; unsigned char buf1[HUGE]; unsigned char buf2[HUGE];
char mime_type[BUFSIZ],filename[BUFSIZ];
/* Main Header */ for(;;) { if ( *boundary != '\0' && is_boundary( r_line,boundary ) ) { retrieve_each_head( FALSE, fd, NULL, NULL,NULL, mime_type, NULL, filename );
/* if ( strncmp( mime_type, "text/html", 9 ) == 0 ) { } else { } / } else if ( is_last_boundary( r_line,boundary ) ) { return( 0 ); } if ( is_eom(r_line) ) { / EOT */ return( 0 ); } if ( ( nbyte = readline ( fd, r_line ) ) ⇐ 0 ) { return( 0 ); } } }
/---------------------------------------------------------------------- * * * retrieve_proper_mail() - retrieve mail * * * ----------------------------------------------------------------------/ int retrieve_proper_mail ( int fd ) { int nbyte; unsigned char buf[HUGE]; unsigned char buf1[HUGE]; unsigned char buf2[HUGE]; int in_attach;
char mime_type[BUFSIZ],boundary[BUFSIZ],filename[BUFSIZ]; char boundary2[BUFSIZ]; /* For alternative message */
/* Main Header */ *boundary = '\0'; retrieve_each_head( TRUE, fd, NULL, NULL, NULL, mime_type, boundary, NULL );
if ( is_eom(r_line) ) { /* EOT */ return( 0 ); }
in_attach = FALSE; for(;;) { if ( *boundary != '\0' && is_boundary( r_line,boundary ) ) { retrieve_each_head( FALSE, fd, NULL, NULL,NULL, mime_type, boundary2, filename ); if ( strncmp( mime_type, "text/plain", 10 ) == 0 ) { in_attach = FALSE; } else if ( strncmp( mime_type, "multipart/related", 17 ) == 0 ) { mon_print( !(is_dump), "<B>This mail contains alternative(s)(perhaps HTML)</B>\n" ); (void) retrieve_related_message( fd, boundary2 ); if ( ( nbyte = readline ( fd, r_line ) ) <= 0 ) { return( 0 ); } in_attach = FALSE; } else { in_attach = TRUE; mon_print( !(is_dump), "<B>Attached File: %s</B>\n", filename ); } } if ( is_last_boundary( r_line,boundary ) ) { /* ignore this line */ } else { if ( !( in_attach ) ) { strip_dummy_period( r_line ); nbyte = nbyte - 1; fmt_into_txt ( r_line, nbyte, buf2 ); mon_print( !(is_dump), "%s", buf2 ); } }
if ( is_eom(r_line) ) { /* EOT */ return( 0 ); } if ( ( nbyte = readline ( fd, r_line ) ) <= 0 ) { return( 0 ); } } }
/---------------------------------------------------------------------- * * * dump_proper_mail() - retrieve mail by dump mode * * * ----------------------------------------------------------------------/ int dump_proper_mail ( int fd ) { int nbyte;
nbyte = readline ( fd, r_line ); while( ( nbyte = readline ( fd, r_line ) ) > 0 ) { mon_print( TRUE, "%s", r_line ); if ( is_eom(r_line) ) { /* EOT */ return( 0 ); } } }
/---------------------------------------------------------------------- * * * retrieve_mail() - retrieve prefer mail ( all when no. = 0 ) * * * ----------------------------------------------------------------------/ int retrieve_mail ( int fd, int no, int mail_cnt ) { int ix, max_ix, min_ix; char boundary[HUGE]; int nbyte;
Boolean is_ok = FALSE;
max_ix = (no != 0 ? no : mail_cnt); min_ix = (no != 0 ? no : 1 );
for ( ix = min_ix; ix <= max_ix; ix++) { mon_print( !(is_dump), "<HR>\n" ); sprintf ( s_line, "RETR %d\r\n", ix ); fflush ( fp_mon ); mon_print( !(is_dump), "<FONT COLOR=blue>%s</FONT><BR>\n", s_line ); is_ok = FALSE; nbyte = write_to_sock ( fd, s_line );
if ( is_dump ) { dump_proper_mail( fd ); } else { mon_print( !(is_dump), "<P><PRE>" );mon_flush( !(is_dump) ); retrieve_proper_mail( fd ); mon_print( TRUE, "</PRE>" ); mon_print( TRUE, "<INPUT TYPE=checkbox NAME=R%d>Re-retrieve this mail ", ix ); mon_print( TRUE, "<INPUT TYPE=checkbox NAME=D%d>Delete this mail</P>\n", ix ); }
mon_flush( !(is_dump) ); } }
/---------------------------------------------------------------------- * * * retrieve_head() - retrieve prefer header ( all when no. = 0 ) * * * ----------------------------------------------------------------------/ int retrieve_head ( int fd, int no, int mail_cnt ) { int ix, max_ix, min_ix; char from[BUFSIZ], subject[BUFSIZ],date[BUFSIZ],mime_type[BUFSIZ],boundary[BUFSIZ]; int nbyte;
mon_print( TRUE, " <FORM NAME=f METHOD=POST ACTION=\"%s\">", cginame ); mon_print( TRUE, "<TABLE BORDER=1 WIDTH=\"100%%\"><TR>\n" ); mon_print( TRUE, "<TD><FONT COLOR=GREEN><B><CENTER>Read</FONT></B></CENTER></TD>\n" ); mon_print( TRUE, "<TD><FONT COLOR=GREEN><B><CENTER>Delete</FONT></B></CENTER></TD>\n" ); mon_print( TRUE, "<TD><FONT COLOR=GREEN><B><CENTER>Date</FONT></B></CENTER></TD>\n" ); mon_print( TRUE, "<TD><FONT COLOR=GREEN><B><CENTER>Subject</FONT></B></CENTER></TD>\n" ); mon_print( TRUE, "<TD><FONT COLOR=GREEN><B><CENTER>From</FONT></B></CENTER></TD>\n" ); mon_print( TRUE, "<TD><FONT COLOR=GREEN><B><CENTER>Size</FONT></B></CENTER></TD></TR>\n" );
max_ix = (no != 0 ? no : mail_cnt); min_ix = (no != 0 ? no : 1 );
for ( ix = min_ix; ix <= max_ix; ix++) { /* Send command */ sprintf ( s_line, "TOP %d 1\r\n", ix ); nbyte = write_to_sock ( fd, s_line ); fflush ( fp_mon );
/* get replay */ retrieve_each_head( FALSE, fd, subject, from, date, mime_type, NULL, NULL ); while( !( r_line[0] == '.' && r_line[1] != '.' ) ) { /* discard rest of message */ (void) readline( fd, r_line ); }
mon_print( TRUE, "<TR><TD><INPUT TYPE=checkbox NAME=R%d></TD>\n", ix ); mon_print( TRUE, "<TD><INPUT TYPE=checkbox NAME=D%d></TD>\n", ix ); mon_print( TRUE, "<TD>%s</TD><TD>%s</TD><TD>%s</TD>", date, subject, from ); if ( ix <= len_mail_size ) { mon_print( TRUE, "<TD>%d</TD></TR>\n", mail_size[ix - 1] ); } else { mon_print( TRUE, "<TD></TD></TR>\n" ); } mon_print( TRUE, "</TR>\n" );
}
mon_print( TRUE, "</TABLE><BR>\n" ); print_javascript_indicate(); display_input_area( ); mon_print( TRUE, "</FORM>\n" ); fflush ( fp_mon ); }
/---------------------------------------------------------------------- * * * delete_mail() - delete prefer header * * * ----------------------------------------------------------------------/ int delete_mail ( int fd, int no, int mail_cnt ) { /* Connect by user */ sprintf ( s_line, "DELE %d\r\n", no ); if ( !( input_cmd ( fd, s_line, r_line ) ) ) { return ( -1 ); } }
/---------------------------------------------------------------------- * * * main() - main control * * * ----------------------------------------------------------------------/
main(int argc, char *argv[]) { int len; int mail_cnt; char *method; int ix; char *str_portno; int portno;
/* trap */ atexit( on_end );
/* Initial Process */ fd = -1; pgmname = argv[0]; cginame = get_cginame( pgmname ); fp_mon = open_mon(); signal( SIGINT, on_intr ); signal( SIGHUP, on_intr ); query_parm( NULL /* = set parameter from CGI environment */ );
/* select method */ if ( *(real_parm(F_METHOD)) == FM_INIT ) { display_initial_panel(); exit ( 0 ); } is_dump = ( *(real_parm(F_METHOD)) == FM_DUMP ); /* Set mode(Dump/other) */
/* print out header information */ #ifdef USR_NPH_MODE mon_print ( "HTTP/1.0 200 OK\n" ); #endif mon_print( TRUE, "Content-type: text/%s\n\n", (is_dump ? "plain" : "html" ) ); mon_print( !(is_dump), "<HTML><HEAD><TITLE>Web Based POP3 Service - Execution view\n" ); mon_print( !(is_dump), "</TITLE></HEAD><BODY BGCOLOR=WHITE><CENTER><FONT SIZE=+2>\n" ) ; mon_print( !(is_dump), "Web Based POP3 Service - result</FONT></CENTER>\n" ); if ( !(is_dump ) ) { display_copyright( "RIGHT" ); } mon_print( !(is_dump), "<p><FONT COLOR=green>------ execution log -------</FONT></p>\n" ); mon_print( !(is_dump), "<p><FONT COLOR=green>execution date : %s</FONT></p>\n", get_date_str() ); mon_flush( !(is_dump) );
/* Decide a port number for POP3 */ str_portno = real_parm( F_PORTNO ); portno = str2int( str_portno ); if ( portno <= 0 ) { portno = 110; }
/* Connet to remote host */ if ( ( connect_to_remote_host ( real_parm(F_HOST), portno ) ) < 0 ) { mon_print( !(is_dump), "<FONT COLOR=RED>Process terminated.</FONT><BR>\n"); fflush ( fp_mon ); exit ( 0 ); }
/* login to mail server */ if ( ( login_to_mail_server ( fd ) ) != 0 ) { exit ( 0 ); }
/* Retrieve number of mail */ mail_cnt = retr_mail_list( fd ) ;
/* Get mails */ switch ( *(real_parm(F_METHOD)) ) { case FM_CONSOLE: case FM_DUMP: mon_print( !(is_dump), " <FORM NAME=f METHOD=POST ACTION=\"%s\">\n", cginame ); retrieve_mail( fd, 0, mail_cnt ); if ( !(is_dump) ) { display_input_area( ) ; } mon_print( !(is_dump), "</FORM>\n" ); break; case FM_HEAD: /* retrieve head */ print_js_select_all_mail(); retrieve_head( fd, 0, mail_cnt ); break; case FM_PROPER: mon_print( !(is_dump), " <FORM NAME=f METHOD=POST ACTION=\"%s\">\n", cginame ); for ( ix = 1; ix <= mail_cnt; ix++) { if ( is_mail_to_process( ix, 'R' ) ) { retrieve_mail( fd, ix, mail_cnt ); } } for ( ix = 1; ix <= mail_cnt; ix++) { if ( is_mail_to_process( ix, 'D' ) ) { delete_mail( fd, ix, mail_cnt ); } } if ( !is_dump ) { display_input_area( ) ; } mon_print( !(is_dump), "</FORM>\n" ); fflush ( fp_mon ); break; default: break; }
/* QUIT */ input_cmd ( fd, "QUIT", r_line ); alarm( WAITING ); shutdown( fd, 2 ); close ( fd ); alarm( 0 );
mon_print( !(is_dump), "<FONT COLOR=green>Connection closed. Goodbye.<BR></FONT>\n" ); mon_print( !(is_dump), "<p><FONT COLOR=green>------ end of execution log -----</FONT></p>\n" );
exit ( 0 ); }