#--------------------------------------------------------------------
OBJS= \
modrec.o \
+ lvleml.o \
gestcp.o \
devsoc.o \
unieml.o \
gestcp.h \
modrec.h modrec.c
+lvleml.o: \
+ subrou.h \
+ unieml.h \
+ lvleml.h lvleml.c
+
gestcp.o: \
+ subrou.h \
unieml.h \
uniprc.h \
unisig.h \
devsoc.h devsoc.c
unieml.o: \
+ subrou.h \
unieml.h unieml.c
unipar.o: \
subrou.o: \
subrou.h subrou.c
+lvleml.h: \
+ gestcp.h
+
gestcp.h: \
subrou.h \
- devsoc.h \
+ devsoc.h
uniprc.h: \
- subrou.h \
+ subrou.h
#--------------------------------------------------------------------
*lineptr=calloc(soc->carin+1,sizeof(char));
*eol='\000';
(void) strcpy(*lineptr,soc->carpile);
- (void) strcat(*lineptr,soc->EOL);
got=strlen(*lineptr);
break;
case 4 : //managing carpile
- soc->carin-=strlen(*lineptr);
- if (soc->carin>0)
- (void) memmove(soc->carpile,soc->carpile+strlen(*lineptr),soc->carin);
+ soc->carin-=(got+strlen(soc->EOL));
+ if (soc->carin>0) {
+ int delta;
+
+ delta=got+strlen(soc->EOL);
+ (void) memmove(soc->carpile,soc->carpile+delta,soc->carin);
+ }
soc->carpile[soc->carin]='\000';
break;
default : //SAFE guard
--- /dev/null
+// vim: smarttab tabstop=8 shiftwidth=2 expandtab
+/********************************************************/
+/* */
+/* Implement all routine to manage SMTP low level */
+/* exchange. */
+/* */
+/********************************************************/
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "subrou.h"
+#include "unieml.h"
+#include "lvleml.h"
+
+
+
+static _Bool modopen; //module open/close status
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to proceed with peer exchange */
+/* 3 return values: */
+/* -1 exit with trouble. */
+/* 0 normal exit. */
+/* 1 continue to proceed. */
+/* */
+/********************************************************/
+PUBLIC int eml_docontact(CONTYP *contact)
+
+{
+#define OPEP "lvleml.c:eml_docontact"
+int status;
+
+status=1;
+while (status>0) {
+ char *line;
+ TIMESPEC attend;
+
+ attend.tv_sec=60;
+ attend.tv_nsec=0;
+ status=tcp_getline(contact,&attend,&line);
+ if (status<=0) //timeout or trouble?
+ break; //no need to go further
+ switch (eml_getcode(line)) {
+ case c_quit : //quit SMTP protocol
+ status=0;
+ break;
+ case c_unknown : //uknown keyword
+ if (line[0]!='\000') { //always
+ char info[300];
+
+ (void) snprintf(info,sizeof(info),"%d command <%s> is unknown",CMDBAD,line);
+ (void) tcp_write(contact,info,strlen(info));
+ (void) tcp_write(contact,CRLF,strlen(CRLF));
+ }
+ break;
+ default :
+ (void) rou_alert(0,"Unable to find keyword for <%s> (Bug?)",OPEP,line);
+ status=-1;
+ break;
+ }
+ }
+return status;
+#undef OPEP
+}
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to "open/close" module and do */
+/* homework purpose */
+/* return zero if everything right */
+/* */
+/********************************************************/
+int eml_modelvleml(_Bool mode)
+
+{
+#define OPEP "unidoc.c:soc_modeunisoc"
+
+int status;
+
+status=0;
+if (mode!=modopen) {
+ (void) rou_modesubrou(mode);
+ switch ((int)mode) {
+ case true :
+ break;
+ case false :
+ break;
+ default :
+ (void) fprintf(stderr,"Calling %s with wrong mode='%d' (Bug?!):",
+ OPEP,(int)mode);
+ status=-1;
+ break;
+ }
+ modopen=mode;
+ }
+return status;
+#undef OPEP
+}
--- /dev/null
+// vim: smarttab tabstop=8 shiftwidth=2 expandtab
+/********************************************************/
+/* */
+/* Define all routine to manage SMTP high level */
+/* exchange. */
+/* */
+/********************************************************/
+#ifndef LVLEML
+#define LVLEML
+
+#include "gestcp.h"
+
+//procedure to extract line and proceed with peer contact
+extern int eml_docontact(CONTYP *contact);
+
+//homework to be done before starting/stopping module.
+extern int eml_modelvleml(_Bool mode);
+
+#endif
#include "unisig.h"
#include "devsoc.h"
#include "gestcp.h"
+#include "lvleml.h"
#include "modrec.h"
static _Bool modopen; //boolean module open/close
printf("New client [%s] connected\n",contact->peerip);
break;
case 2 : //do contact
- for (int i=0;i<TESTL;i++) {
- TIMESPEC attend;
- char *line;
- int got;
- _Bool quit;
-
- attend.tv_sec=60;
- attend.tv_nsec=0;
- (void) printf("attend %d seconds\n",(int)attend.tv_sec);
- got=tcp_getline(contact,&attend,&line);
- if (got<=0) {
- (void) printf("remote timeout\n");
- break; //remote disconnect
- }
- (void) printf("Read '%d' char =<%s>\n",got,line);
- quit=(strcasecmp(line,"QUIT"CRLF)==0);
- (void) tcp_write(contact,line,strlen(line));
- (void) free(line);
- if (quit==true) {
- (void) printf("remote quit\n");
- break; //remote disconnect
- }
+ switch (eml_docontact(contact)) {
+ case -1 : //Signal received
+ break;
+ case 0 : //exit under timeout
+ (void) rou_alert(0,"Contact with peer <%s> closed by timeout",
+ contact->peerip);
+ break;
+ default : //exit under quit
+ break;
}
break;
case 3 : //connection terminated
(void) sig_modeunisig(mode);
(void) soc_modedevsoc(mode);
(void) tcp_modegestcp(mode);
+ (void) eml_modelvleml(mode);
break;
case false :
+ (void) eml_modelvleml(mode);
(void) tcp_modegestcp(mode);
(void) soc_modedevsoc(mode);
(void) sig_modeunisig(mode);
//version definition
#define VERSION "0.3"
-#define RELEASE "34"
+#define RELEASE "35"
//Public variables
PUBLIC int debug=0; //debug level
/********************************************************/
#include <stdbool.h>
#include <stdio.h>
+#include <string.h>
+#include "subrou.h"
#include "unieml.h"
-static _Bool modopen; //module open/close status
+static _Bool modopen; //module open/close status
+typedef struct {
+ CODTYP code; //keyword code
+ const char *key; //keyword itself
+ }VOCTYP;
+
+//this list order by key length
+static VOCTYP vocsmtp[]={
+ {c_quit,"QUIT"},
+ {c_unknown,(const char *)0}
+ };
+/*
+^L
+*/
+/********************************************************/
+/* */
+/* Procedure to return a protocol keywork code */
+/* */
+/********************************************************/
+PUBLIC CODTYP eml_getcode(char *keyword)
+
+{
+CODTYP code;
+VOCTYP *ptr;
+
+code=c_unknown;
+for (ptr=vocsmtp;ptr->code!=c_unknown;ptr++) {
+ if (strcasecmp(ptr->key,keyword)==0) {
+ code=ptr->code;
+ break;
+ }
+ }
+return code;
+}
/*
^L
*/
#define CRLF "\r\n" //EOL within SMTP protocol
#define SIGNON 220 //signon information
+#define CMDBAD 502 //command not implemented
+
+//list of keyword
+typedef enum { //list of SMTP protocol keyword
+ c_quit, //quit exchange
+ c_unknown //key word unknown
+ }CODTYP;
+
+//conver keyword to CODTYP
+extern CODTYP eml_getcode(char *keyword);
//homework to be done before starting/stopping module.
extern int eml_modeunieml(_Bool mode);
good=true;
va_start(args,msg);
(void) vsnprintf(info,sizeof(info),msg,args);
-(void) rou_alert(0,"JMPDBG showtlserror sslerror='%d' code='%d'",
+(void) rou_alert(0,"showtlserror sslerror='%d' code='%d'",
sslerror,SSL_get_error(tls->ssl,sslerror));
if (sslerror<=0) {
char *detail;
break;
case 1 : //set certificate
status=SSL_shutdown(tls->ssl);
- (void) printf("JMPDBG ssl_shutdown status='%d'\n",status);
+ if (status<0)
+ (void) rou_alert(0,"%s, Link with [%s], ssl_shutdown status='%d'",
+ OPEP,tls->peerip,status);
break;
default : //SAFE guard
tls=freetls(tls);
default :
(void) rou_alert(0,"%s Unexpected SSL_write error='%d'",
OPEP,SSL_get_error(tls->ssl,0));
- (void) showtlserror(tls,0,"%s JMPDBG Check what is SSL",OPEP);
+ (void) showtlserror(tls,0,"show SSL error",OPEP);
break;
}
(void) sleep(1);
break;
default : //some character sent
- (void) printf("JMPDBG sofar '%d' sent='%d'\n",sofar,sent);
sent+=sofar;
if (sent<tosend)
proceed=true;
phase=0;
proceed=true;
while (proceed==true) {
- (void) printf("JMPDBG phase='%d', check peer\n",phase);
switch (phase) {
case 0 : //check SSL
if ((tls==(TLSTYP *)0)||(tls->ssl=(SSL *)0)) {