/* ========================================================================== wsmail.c by Frank Wang, Copyright 1995 Functions: 1. Post reply packets created by wsOMR. 2. Retrieve mails from system mail box Usage: Compile this program in the internet side using ff. commands: cc wsmail.c mv a.out wsmail To send replies: wsmail r file_name To send replies and delete the reply file after sending wsmail r- file_name To retrieve mails from system mail box and move to a new file: wsmail m file_name To retrieve mails from system mail box and append to a new/existing file wsmail m+ file_name To retrieve mails from system mail box without deleting: wsmail M file_name wsmail M+ file_name Note: This program assumes max character per line is 512. ========================================================================== */ #include #include #include #include #include #include #define MAX_NUM 512 #define BUF_SIZE 512 /*#define MAIL_SPOOL "c:\\usenet\\"*/ #define MAIL_SPOOL "/usr/spool/mail/" char *send_cmd = "sendmail -t "; /* change this in case different */ char *temp_msg = "temp.msg"; /* Temporary file for mail processed */ char *wsomr_tag = "$WSOMR$"; /* Message seperating string */ char user_mail[128]; char home_dir[128]; /* -------------------------------- */ /* Read next line from the buffer */ /* -------------------------------- */ next_line( f, buf, buf_siz, cnt, offset, ret_buf ) FILE *f; char *buf; int buf_siz, *cnt, *offset; char *ret_buf; { int ret = 0; memset( ret_buf, 0, buf_siz ); if (*offset < 0) /* first pass */ { fseek( f, 0L, 0 ); *offset = *cnt = 0; } if (*offset == *cnt) /* at end of buffer ? */ { memset( buf, 0, buf_siz ); *cnt = fread( buf, 1, buf_siz, f ); /* read the next block into buffer */ *offset = 0; } while ( *cnt > 0 ) { int k, n; char *p = buf + *offset; for ( k = *offset, n = 0; *p && *p != '\n' && k < buf_siz; k ++, p++ ) n ++; /* If end of line or block */ if ( k < buf_siz && (*p == '\n' || *p == 0) ) { memcpy( ret_buf, buf + *offset, n ); ret_buf[n] = 0; *offset = ++k; ret = 1; break; } else /* The line is not ended in */ { /* block, read the next block if any */ int new_siz = buf_siz - n; memcpy( buf, buf + *offset, n ); memset( buf + n, 0, new_siz ); *cnt = fread( buf + n, 1, new_siz, f ); if ( *cnt == 0 ) /* no more left in the file */ { /* copy whatever left in the prv.blk*/ memcpy( ret_buf, buf + *offset, n ); ret_buf[n] = 0; } else { *cnt += n; *offset = 0; } } } return ret; } /* ------------------------------------------- */ /* Send mail using internet sendmail command */ /* ------------------------------------------- */ send_mail( msg_no, to ) int msg_no; char *to; { int status; char cmd[128]; sprintf( cmd, "%s <%s", send_cmd, temp_msg ); status = system( cmd ); printf("\nMail # %2d, Status: %d, To:%s", msg_no, status, to ); } /* ------------------------------------------------------------- */ /* Scan wsOMR created reply file and send one mail at one time */ /* ------------------------------------------------------------- */ post_all_mails( fname ) char *fname; { int ret = 0; FILE *rep = fopen (fname, "rt"); if (NULL == rep ) fprintf (stderr, "can't open %s\n", fname ); else { FILE *out; char buffer[MAX_NUM], ret_buf[MAX_NUM], name[128]; int cnt, offset = -1, done, msg_no, valid_msg, apnd, end_of_msg; cnt = done = apnd = msg_no = valid_msg = end_of_msg = 0; while (!done) { if (!apnd) { if (NULL == (out = fopen (temp_msg, "wt"))) { fprintf (stderr, "can't create %s\n", temp_msg ); exit (0); } apnd = 1; end_of_msg = valid_msg = 0; memset( name, 0, sizeof(name) ); } done = !next_line( rep, buffer, sizeof(buffer), &cnt, &offset, ret_buf ); if (!done) { if ( strncmp( ret_buf, wsomr_tag, strlen(wsomr_tag) ) ) { fwrite( ret_buf, 1, strlen(ret_buf), out ); fwrite( "\n", 1, 1, out ); if (!valid_msg) { valid_msg = strncmp( ret_buf, "To:", 3 ) == 0; if (valid_msg) strcpy( name, ret_buf + 3 ); } } else end_of_msg = 1; } if ( (apnd && valid_msg) && (done || end_of_msg) ) { fclose( out ); msg_no ++; send_mail( msg_no, name ); apnd = end_of_msg = valid_msg = 0; } } if ( apnd ) /* invalid message encountered */ fclose( out ); printf("\n"); fclose( rep ); } return ret; } /* --------------------------------------- Retrieve user info from UNIX system --------------------------------------- */ set_param() { struct passwd *pw; if (NULL == (pw = getpwuid(getuid()))) { fprintf ( stderr, "can't determin user info\n"); return 0; } else { strcpy ( user_mail, MAIL_SPOOL ); strcat ( user_mail, pw -> pw_name ); strcpy ( home_dir, pw -> pw_dir ); return 1; } } /* -------------------------------------------------------- Move personal mail from system mail box to file_name -------------------------------------------------------- */ get_mail( file_name, read_only, is_append ) char *file_name; int read_only, is_append; { int done = 0; long fsize = 0; FILE *mail, *folder; char *mode = is_append ? "ab" : "wb"; /* Open user's mail file */ if (NULL == (mail = fopen (user_mail, "rb"))) { fprintf ( stderr, "\ncan't open %s\n", user_mail ); return 0; } else { fseek( mail, 0L, 2 ); if ( !ftell(mail) ) { fprintf ( stderr, "\nmail box is empty\n" ); fclose(mail); return 0; } else rewind(mail); } if (NULL == (folder = fopen (file_name, mode ))) { fprintf ( stderr, "\ncan't create %s\n", file_name ); return 0; } /* Copy */ while (!done) { unsigned char buffer[BUF_SIZE]; int rcount, wcount; rcount = fread( buffer, 1, sizeof(buffer), mail ); done = rcount < sizeof(buffer); wcount = fwrite( buffer,1, rcount, folder ); if ( wcount != rcount ) { fprintf (stderr, "Error in writing file \n", file_name ); return 0; } fsize += wcount; } fclose (mail); fclose (folder); if (!read_only) { if (NULL == (mail = fopen (user_mail, "wb"))) fprintf (stderr, "can't write %s\n", user_mail ); else fclose (mail); } return (fsize); } void syntax() { printf( "Postman for wsOMR by Frank Wang\n" ); printf( "\nSyntax: wsmail [rm] file_name" ); printf( "\n r post reply(file_name)" ); printf( "\n r- post reply(file_name) and delete afterwards" ); printf( "\n m copy mails to file_name" ); printf( "\n m+ append mails to file_name" ); printf( "\n M copy mails(read only) to file_name" ); printf( "\n M+ append mails(read only) to file_name" ); printf( "\n" ); } main( argc, argv ) int argc; char *argv[]; { int ret = 1; char *param, *file_name; if ( argc > 2 ) { char optn, mode; param = argv[1]; file_name = argv[2]; optn = param[0]; mode = param[1]; /* optional switch */ if ( optn == 'r' ) { post_all_mails( file_name ); if ( mode == '-' ) unlink( file_name ); ret = 0; } else if ( optn == 'm' || optn == 'M' ) { if ( set_param() ) { long siz = get_mail(file_name, optn == 'M', mode == '+' ); if ( siz > 0 ) { printf( "\nmails packed into %s (%u characters)\n", file_name, siz ); ret = 0; } } } else syntax(); } else syntax(); exit(ret); }