/****************************************************************************** popdump.c - dump mail from popmail3 into spool subdirectory Copyright (C) 1991, University of Waterloo This program is free software; you can redistribute it and/or modify it, but you may not sell it. This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. Erick Engelke or via E-Mail Faculty of Engineering University of Waterloo Erick@development.watstar.uwaterloo.ca 200 University Ave., Waterloo, Ont., Canada N2L 3G1 ******************************************************************************/ #include #include #include #include #define POP3_PORT 110 long localdiskspace() { struct dfree d; getdfree( 0, &d ); return( (longword) d.df_avail * (longword)d.df_bsec * (longword)d.df_sclus ); } tcp_Socket popsock; char buffer[ 513 ]; /* getnumbers - returns the count of numbers received */ int getnumbers( char *ascii, long *d1, long *d2 ) { char *p; /* it must return a number after the white space */ if (( p = strchr( ascii, ' ')) == NULL ) return( 0 ); /* skip space */ while ( *p == ' ') p++; *d1 = atol( p ); if (( p = strchr( p, ' ')) == NULL ) return( 1 ); /* skip space */ while ( *p == ' ') p++; *d2 = atol( p ); return( 2 ); } popdump(userid, password, host, hoststring, dumpfile) char *userid, *password, *hoststring, *dumpfile; longword host; { tcp_Socket *s; int status; int len; char *p; long process = 0, count, totallength, locallength, dummy; FILE *f; s = &popsock; if (!tcp_open( s, 0, host, POP3_PORT, NULL )) { puts("Sorry, unable to connect to that machine right now!"); return; } printf("waiting...\r"); sock_mode( s, TCP_MODE_ASCII ); sock_wait_established(s, sock_delay, NULL, &status); sock_wait_input( s, sock_delay, NULL, &status ); sock_gets( s, buffer, sizeof( buffer )); puts(buffer); if ( *buffer != '+' ) goto quit; sock_printf( s, "USER %s", userid); sock_wait_input( s, sock_delay, NULL, &status ); sock_gets( s, buffer, sizeof( buffer )); puts(buffer); if ( *buffer != '+' ) goto quit; sock_printf( s, "PASS %s", password ); sock_wait_input( s, sock_delay, NULL, &status ); sock_gets( s, buffer, sizeof( buffer )); puts(buffer); if ( *buffer != '+' ) goto quit; sock_printf(s, "STAT"); printf("STAT\n"); sock_wait_input( s, sock_delay, NULL, &status ); sock_gets( s, buffer, sizeof( buffer )); puts(buffer); if ( *buffer != '+' ) goto quit; /* it must return two valid numbers */ if ( getnumbers( buffer, &count, &totallength ) < 2 ) { printf("protocol error on STAT\n"); goto quit; } printf("Attempting to download %lu messages (%lu bytes)\n", count, totallength ); while ( process++ < count ) { printf("Getting file # %lu\n", process ); sock_printf( s, "LIST %lu", process ); sock_wait_input( s, sock_delay, NULL, &status ); sock_gets( s, buffer, sizeof( buffer )); if ( getnumbers( buffer, &dummy, &locallength ) < 2 ) { printf("protocol error on LIST %lu\n", process ); goto quit; } if ( localdiskspace() < locallength * 2 ) { printf("Skipping file # %lu, too big for disk space available\n", process ); continue; } sock_printf( s, "RETR %lu", process ); sock_wait_input( s, sock_delay, NULL, &status ); sock_gets( s, buffer, sizeof( buffer )); if (*buffer != '+' ) goto quit; /* sprintf( buffer, "%s%s%lu.mai", dumpfile, dumpfile ? "\\":".\\", index if (( f = fopen( dumpfile , "wt" )) == NULL ) { printf("Unable to open %s\n", dumpfile ); return; } */ do { sock_wait_input( s, sock_delay, NULL, &status ); sock_gets( s, buffer, sizeof( buffer )); puts( buffer ); } while ( buffer[0] != '.' || buffer[1] != 0 ); sock_printf(s,"DELE %lu", process ); sock_wait_input( s, sock_delay, NULL, &status ); sock_gets( s, buffer, sizeof( buffer )); puts(buffer); if ( *buffer != '+' ) goto quit; } quit: sock_puts(s,"QUIT"); sock_close( s ); sock_wait_closed( s, sock_delay, NULL, &status ); sock_err: switch (status) { case 1 : /* foreign host closed */ break; case -1: /* timeout */ printf("ERROR: %s\n", sockerr(s)); break; } printf("\n"); } main(int argc, char **argv ) { char user[128], password[64], *server; longword host; int status; if ( argc < 2 ) { puts("popdump userid@server password"); exit(3 ); } sock_init(); strncpy( user, argv[1], sizeof(user)-1 ); user[ sizeof(user) -1 ] = 0; strncpy( password, argv[2], sizeof(password)-1 ); password[ sizeof(password) -1 ] = 0; if ( (server = strchr( user, '@' ))== NULL) { printf("missing @server part of userid: %s\n", user ); exit( 3 ); } *server++ = 0; if (host = resolve( server )) { status = popdump( user, password, host, server); } else { printf("Could not resolve host '%s'\n", server ); exit( 3 ); } exit( status ); }