I try do same in all protocols. Perhaps, in a object-oriented-language
as JAVA or C++, this program will become more redable, less code line
(saving near 50%), and more natural. But at beginning, we choose C and
start with a prototype, learning what is the best way... when we go
back from others options.
For example, we start coding pop3 protocol; What we do ?
$ cd lib/weblib
$ cp -R l_ftp l_pop3
$ cd l_pop3
In all files in 'l_pop3', will need change FTP word to POP3,
and all file need to be renamed :
$ mv l_ftp_response.c l_pop3_response.c
$ mv l_ftp_response.h l_pop3_response.h
$ mv ...
$ vi l_pop3_response.h
next, we change 't_pop3_response'. All protocols can be sumarize
with to fields : a boolean 'ok', if command execution go well and
a string 'msg' with response from server. In FTP and HTTP protocols,
inside 'msg' are a special code; In HTTP, response is like a list
of string' pairs : mime-header-field and value. In POP3, response
in only a line. ("+OK more_details" or "-ERR more_info") and we only
need 'ok' and 'msg' fields.
In L_POP3_RESPONSE_Skip function, we need add a param : a boolean
'isMultiLine'. In FTP, multiline response are signed inside mensage,
but in POP3 multiline response ocurrs only in a few special command.
$ vi l_pop3_response.c
If command success, response begin with "+OK", we change code that
in FTP scan to "200" :
pop3r.ok = TRUE ;
if (lineBuff[0] == '-')
pop3r.ok = FALSE ;
if (lineBuff[0] == '+')
pop3r.ok = TRUE ;
and we update code that use t_pop3_response type, now has only
two fields.
In L_POP3_RESPONSE_Skip, multiline response are diferent :
if (isMultiLine == TRUE)
{
while ( L_LINE_dot_enter(lineBuff) == FALSE )
{
eof = X_SOCKET_ReadLine( sd,
lineBuff,
sizeof(lineBuff) ) ;
if (eof == TRUE)
return (pop3r.ok) ;
}
}
$ vi l_pop3_log.c
now L_POP3_LOG_PrintResponse will use only 'pop3r->msg'
$ vi l_pop3_command.[ch]
we need remove some functions like L_POP3_COMMAND_nlst,
L_POP3_COMMAND_port, etc. This functions are not valid in POP3.
And we can add some new functions, like L_POP3_COMMAND_list,
L_POP3_COMMAND_noop...
$ vi l_pop3_download.[ch]
now, we has two entities : mailbox and mail (like a directory
and a file from it). We need change L_POP3_DOWNLOAD_DownLoadUrl
in order to call L_POP3_BOX_DownLoadBox if url is like a mailbox
or L_POP3_MAIL_DownLoadMail if url is like a mail from a mailbox.
$ cd l_pop3_download
$ mv l_pop3_download_file.c l_pop3_download_mail.c
$ mv l_pop3_download_file.h l_pop3_download_mail.h
$ mv l_pop3_download_dir.c l_pop3_download_box.c
$ mv l_pop3_download_dir.h l_pop3_download_box.h
$ vi l_pop3_download_box.c
we remove some code, because POP3 is very similar to FTP
but easier.
$ cd ../..
$ vi Makefile.linux Makefile.sunos
Add a new entry in 'OBJETOS' variable. Copy and paste from
other protocol, and change object names :
$(SRCDIR)/l_pop3/l_pop3_log.o \
$(SRCDIR)/l_pop3/l_pop3_download.o \
$(SRCDIR)/l_pop3/l_pop3_response.o \
$(SRCDIR)/l_pop3/l_pop3_server.o \
$(SRCDIR)/l_pop3/l_pop3_command.o \
$(SRCDIR)/l_pop3/l_pop3_download/l_pop3_box.o \
$(SRCDIR)/l_pop3/l_pop3_download/l_pop3_mail.o \
and ...
$ make -f Makefile.linux fast
When you can compile new code, edit this files :
l_vp/l_vp_download.c
l_vp/l_vp_server.c
You will see that here is where is call specific code. Here
we try show a 'virtual protocol'. We need add code and when
a url has a url->protocol like 'pop3', is when we call pop3
code.