c added code to support differing versions of the pop-3 implementation which seem to have different greeting formats with the message count in differing places
e
s 00004/00002/00449
d D 1.8 95/07/06 19:55:20 tim 8 7
c user the getpass command to get the users password as it is secure
e
s 00040/00011/00411
d D 1.7 95/07/06 14:53:45 tim 7 6
c modified talk to pop to operate on the config files
e
s 00001/00034/00421
d D 1.6 95/07/06 13:42:18 tim 6 5
c the #defines ar now in a seperate file
e
s 00001/00001/00454
d D 1.5 95/07/05 20:10:50 tim 5 4
c now deletes outgoing email files as well
e
s 00001/00001/00454
d D 1.4 95/07/05 11:43:15 tim 4 3
c added a newline print in one command
e
s 00235/00011/00220
d D 1.3 95/07/04 19:40:36 tim 3 2
c it seems to work now
e
s 00231/00000/00000
d D 1.2 95/07/03 13:04:08 tim 2 1
c the thing works in principle. it can connect, authenticate list and quit.
c it will need defaults handling installing
e
s 00000/00000/00000
d D 1.1 95/07/01 16:19:59 tim 1 0
c
e
u
U
f e 0
t
T
I 2
/* this program talks to pop3 servers */
/* (C) Tim Graves, Sun Microsystems 1995 */
I 6
#include "talktopop.h"
E 6
#include <netinet/in.h>
#include <sys/uio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
I 3
#include <stdlib.h>
E 3
D 6
#define POPNAME "pop-3"
#define PROTNAME "tcp"
#define POPSERVER "astir"
#define USERCMD "USER"
#define PASSCMD "PASS"
#define LISTCMD "LIST"
I 3
#define RETRCMD "RETR"
#define DELECMD "DELE"
E 3
#define QUITCMD "QUIT"
#define READY "."
#define BADCHAR '-'
#define OKCHAR '+'
/* standard defines */
#define TRUE 1
#define FALSE 0
/* error codes */
#define NETERR -1
#define NETOK -2
#define GOODCMD 1
#define BADCMD 0
I 3
#define BADFILE BADCMD
E 3
/* sizes and stuff */
#define MAXLINE 1024
I 3
#define MAXSIZE 2048 /* max size of an email to get */
#define MAXCOUNT 10 /* get 10 emails */
#define FIRST 1
#define LAST -1
E 3
I 3
/* skeleton for generating file names */
D 5
#define INSKELETON "in%d.msg"
E 5
I 5
#define INSKELETON "in%03d.msg"
E 6
E 5
E 3
/* info on the port we are dealing with etc */
struct sockaddr_in sin ;
int net ;
FILE *netinfd, *netoutfd ;
I 3
/* various strings etc that are set or reset from the command line */
char popserver[100] ;
char popname [100] ;
char protname [100] ;
char uname[100] ;
char passwd[100] ;
int filestartno = 0 ;
int dodel = FALSE ;
D 7
int direction = FIRST ;
E 7
I 7
int direction = TRUE ;
E 7
int verbose = FALSE ;
int maxsize = MAXSIZE ;
int maxemail = MAXCOUNT ;
I 7
int hnset, pwset, unset ;
E 7
E 3
/* message information */
int messcnt = 0 ;
/* debug information */
D 3
int debug = TRUE ;
E 3
I 3
int debug = FALSE ;
/* pointer to the message size array */
int * msglist ;
E 3
main(argc, argv, environ)
int argc ;
char * argv[] ;
char * environ[] ;
{
int ret ;
I 3
int startno ;
init() ;
/* handle the command line */
cmdline(argc, argv) ;
if (verbose == TRUE)
dogreet() ;
I 7
/* check that the arguments have worked out right and
get the password if required */
checkflags() ;
/* maxemail can viable be zero if there are more saved emails than
the default value of maxemail. in this case just crunch out */
/* calculate the number of emails to actually retrieve.
this is maxemail - the findnumber.
if the count has been specificaly set dont do this */
if (cset == FALSE)
E 7
{
D 7
fprintf(stderr, "Usage: talktopop -h <popserver name> -u <your username> -p <your password> [-c <max number of emails to retrieve>] [-s <max size of email to retrieve in bytes>] [-f] [-l] [-v] [-S <pop name in services file, defaults to pop-3>] [-n <start number>]") ;
exit(1) ;
E 7
I 7
maxemail = maxemail - filestartno ;
if (maxemail < 0)
maxemail = 0 ;
E 7
}
}
dogreet()
{
printf("Talktopop, Version %I%\n(C) Tim Graves, Sun Microsystems 1995\n") ;
}
E 3
doquit()
{
char tmp[MAXLINE] ;
sprintf(tmp, "%s", QUITCMD) ;
tonet(tmp) ;
fromnet(tmp) ;
I 3
free(msglist) ;
E 3
}
I 3
dodelete(i)
int i ;
{
char tmp[MAXLINE] ;
if (verbose == TRUE)
printf("Deleting mail no %i\n", i) ;
sprintf(tmp, "%s %d", DELECMD, i) ;
tonet(tmp) ;
fromnet(tmp) ;
if (tmp[0] == BADCHAR)
return(BADCMD) ;
else
return(GOODCMD) ;
}
doretrieve(i, fname)
int i ;
char * fname ;
{
FILE *fd ;
char tmp[MAXLINE] ;
if (verbose == TRUE)
D 4
printf("Retrieving mail no %d to file %s", i, fname) ;
E 4
I 4
printf("Retrieving mail no %d to file %s\n", i, fname) ;
E 4
if ((fd = fopen(fname, "w")) == NULL)
{
return(BADFILE) ;
}
sprintf(tmp, "%s %d", RETRCMD, i) ;
tonet(tmp) ;
/* do the first line, if there is a - there its an error */
fromnet(tmp) ;
if (tmp[0] == BADCHAR)
{
fclose(fd) ;
return(BADCMD) ;
}
/* the line is OK, do the message */
while(fromnet(tmp) == TRUE)
{
/* NOTE fromnet removes andy \r o \n stuff, we need to
reinsert this into the file */
fprintf(fd, "%s\n", tmp) ;
}
fclose(fd) ;
return(GOODCMD) ;
}
int findfromlast()
{
/* counting backwards from the last entry in msglist count
maxemails which are <= maxsize back and return the number of
the last one */
int i, count ;
count = 0 ;
for ( i = messcnt ; ((i >= 0 ) && ( count < maxemail)) ; i--)
if (msglist[i] <= maxsize)
count ++ ;
return(i) ;
}
/* get maxcount emails from the pop server and save then away */
doget(startno)
int startno ;
{
int i, count;
char tmp[100] ;
if (verbose == TRUE)
printf("Retrieving emails from %d\n", startno) ;
count = 0 ;
for (i = startno ; ((count < maxemail) && (i <= messcnt)) ; i ++)
{
/* is the email the right size ? */
if (msglist[i] > maxsize)
continue ;
/* OK we should be looking at this email */
/* create the filename */
sprintf(tmp, INSKELETON, count+filestartno) ;
/* get the file */
doretrieve(i, tmp) ;
/* are we deleting retrieved messages ? */
if (dodel == TRUE)
dodelete(i) ;
/* increment the count */
count ++ ;
}
}
E 3
dolist()
{
char tmp [MAXLINE] ;
D 3
int i ;
for (i = 1 ; i <= messcnt ; i ++)
E 3
I 3
int i, mailno, mailsize ;
if (verbose == TRUE)
printf("Listing email size\n") ;
for (i = 1 ; i <= messcnt; i ++)
E 3
{
sprintf(tmp, "%s %d", LISTCMD, i) ;
tonet(tmp) ;
fromnet(tmp) ;
D 3
if (tmp[0] == BADCMD)
E 3
I 3
if (tmp[0] == BADCHAR) /* this could get things out of sync but its usefull for debugging */
E 3
{
return(BADCMD) ;
}
I 3
/* skip over the "+OK " */
sscanf(&tmp[4],"%d %d", &mailno, &mailsize) ;
if (mailno > messcnt)
return(BADCMD) ;
if (mailno != i)
return(BADCMD) ;
msglist[i] = mailsize ;
E 3
}
return(GOODCMD) ;
}
doconnect()
{
char tmp[MAXLINE] ;
I 3
if (verbose == TRUE)
printf("Connecting to pop server\n") ;
E 3
fromnet(tmp) ;
if (tmp[0] == BADCHAR)
return(BADCMD) ;
else
return(GOODCMD) ;
}
int dologin()
{
char tmp[MAXLINE] ;
I 9
size_t i ;
E 9
I 3
if (verbose == TRUE)
printf("Logging in to pop server\n") ;
E 3
/* request the user name */
D 3
sprintf(tmp, "%s %s", USERCMD, UNAME) ;
E 3
I 3
sprintf(tmp, "%s %s", USERCMD, uname) ;
E 3
tonet(tmp) ;
fromnet(tmp) ;
if (tmp[0] == BADCHAR)
{
return(BADCMD) ;
}
D 3
sprintf(tmp, "%s %s", PASSCMD, PASSWORD) ;
E 3
I 3
sprintf(tmp, "%s %s", PASSCMD, passwd) ;
E 3
tonet(tmp) ;
fromnet(tmp) ;
if (tmp[0] == BADCHAR)
{
return(BADCMD) ;
}
/* the format is something like
+OK 360 messages ready for tim in /usr/spool/mail/tim
D 9
extract the number */
messcnt = atoi(&tmp[4]) ;
E 9
I 9
for a strict pop3 implementation but some are like
+OK tim has 77 message(s) (709547 octets).
find the first number and then extract it (assume the first