mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-12-25 07:20:11 +01:00
really removed pilergetd
This commit is contained in:
parent
a83bdc43a7
commit
02e5ddcad8
399
src/pilergetd.c
399
src/pilergetd.c
@ -1,399 +0,0 @@
|
||||
/*
|
||||
* pilergetd.c, SJ
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
#include <errno.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
int sd;
|
||||
int quit = 0;
|
||||
int received_sighup = 0;
|
||||
char *configfile = CONFIG_FILE;
|
||||
struct __config cfg;
|
||||
struct __data data;
|
||||
struct passwd *pwd;
|
||||
|
||||
struct child children[MAXCHILDREN];
|
||||
|
||||
|
||||
static void takesig(int sig);
|
||||
static void child_sighup_handler(int sig);
|
||||
static void child_main(struct child *ptr);
|
||||
static pid_t child_make(struct child *ptr);
|
||||
int search_slot_by_pid(pid_t pid);
|
||||
void kill_children(int sig);
|
||||
void p_clean_exit();
|
||||
void fatal(char *s);
|
||||
void initialise_configuration();
|
||||
|
||||
|
||||
|
||||
|
||||
static void takesig(int sig){
|
||||
int i, status;
|
||||
pid_t pid;
|
||||
|
||||
switch(sig){
|
||||
case SIGHUP:
|
||||
initialise_configuration();
|
||||
if(read_key(&cfg)) fatal(ERR_READING_KEY);
|
||||
kill_children(SIGHUP);
|
||||
break;
|
||||
|
||||
case SIGTERM:
|
||||
case SIGKILL:
|
||||
quit = 1;
|
||||
p_clean_exit();
|
||||
break;
|
||||
|
||||
case SIGCHLD:
|
||||
while((pid = waitpid (-1, &status, WNOHANG)) > 0){
|
||||
|
||||
if(quit == 0){
|
||||
i = search_slot_by_pid(pid);
|
||||
if(i >= 0){
|
||||
children[i].status = READY;
|
||||
children[i].pid = child_make(&children[i]);
|
||||
}
|
||||
else syslog(LOG_PRIORITY, "error: couldn't find slot for pid %d", pid);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void child_sighup_handler(int sig){
|
||||
if(sig == SIGHUP){
|
||||
received_sighup = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void child_main(struct child *ptr){
|
||||
int new_sd;
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
struct sockaddr_storage client_addr;
|
||||
socklen_t addr_size;
|
||||
|
||||
ptr->messages = 0;
|
||||
|
||||
if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child (pid: %d) started main()", getpid());
|
||||
|
||||
while(1){
|
||||
if(received_sighup == 1){
|
||||
if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child (pid: %d) caught HUP signal", getpid());
|
||||
break;
|
||||
}
|
||||
|
||||
ptr->status = READY;
|
||||
|
||||
addr_size = sizeof(client_addr);
|
||||
new_sd = accept(sd, (struct sockaddr *)&client_addr, &addr_size);
|
||||
|
||||
if(new_sd == -1) continue;
|
||||
|
||||
ptr->status = BUSY;
|
||||
|
||||
inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), s, sizeof(s));
|
||||
|
||||
syslog(LOG_PRIORITY, "connection from %s", s);
|
||||
|
||||
|
||||
sig_block(SIGHUP);
|
||||
ptr->messages += handle_pilerget_request(new_sd, &data, &cfg);
|
||||
sig_unblock(SIGHUP);
|
||||
|
||||
close(new_sd);
|
||||
|
||||
if(cfg.max_requests_per_child > 0 && ptr->messages >= cfg.max_requests_per_child){
|
||||
if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child (pid: %d) served enough: %d", getpid(), ptr->messages);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ptr->status = UNDEF;
|
||||
|
||||
#ifdef HAVE_MEMCACHED
|
||||
memcached_shutdown(&(data.memc));
|
||||
#endif
|
||||
|
||||
if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "child decides to exit (pid: %d)", getpid());
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static pid_t child_make(struct child *ptr){
|
||||
pid_t pid;
|
||||
|
||||
if((pid = fork()) > 0) return pid;
|
||||
|
||||
if(pid == -1) return -1;
|
||||
|
||||
if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "forked a child (pid: %d)", getpid());
|
||||
|
||||
/* reset signals */
|
||||
|
||||
set_signal_handler(SIGCHLD, SIG_DFL);
|
||||
set_signal_handler(SIGTERM, SIG_DFL);
|
||||
set_signal_handler(SIGHUP, child_sighup_handler);
|
||||
|
||||
child_main(ptr);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int child_pool_create(){
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAXCHILDREN; i++){
|
||||
children[i].pid = 0;
|
||||
children[i].messages = 0;
|
||||
children[i].status = UNDEF;
|
||||
}
|
||||
|
||||
for(i=0; i<cfg.number_of_worker_processes; i++){
|
||||
children[i].status = READY;
|
||||
children[i].pid = child_make(&children[i]);
|
||||
|
||||
if(children[i].pid == -1){
|
||||
syslog(LOG_PRIORITY, "error: failed to fork a child");
|
||||
p_clean_exit();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int search_slot_by_pid(pid_t pid){
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAXCHILDREN; i++){
|
||||
if(children[i].pid == pid) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void kill_children(int sig){
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAXCHILDREN; i++){
|
||||
if(children[i].status != UNDEF && children[i].pid > 1){
|
||||
if(cfg.verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "sending signal to child (pid: %d)", children[i].pid);
|
||||
kill(children[i].pid, sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void p_clean_exit(){
|
||||
if(sd != -1) close(sd);
|
||||
|
||||
kill_children(SIGTERM);
|
||||
|
||||
syslog(LOG_PRIORITY, "%s has been terminated", PILERGETD_PROGNAME);
|
||||
|
||||
unlink(cfg.pilergetd_pidfile);
|
||||
|
||||
if(data.ctx){
|
||||
SSL_CTX_free(data.ctx);
|
||||
ERR_free_strings();
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void fatal(char *s){
|
||||
syslog(LOG_PRIORITY, "%s\n", s);
|
||||
p_clean_exit();
|
||||
}
|
||||
|
||||
|
||||
int init_ssl(){
|
||||
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
|
||||
data.ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
|
||||
if(data.ctx == NULL){ syslog(LOG_PRIORITY, "SSL_CTX_new() failed"); return ERR; }
|
||||
|
||||
if(SSL_CTX_set_cipher_list(data.ctx, cfg.cipher_list) == 0){ syslog(LOG_PRIORITY, "failed to set cipher list: '%s'", cfg.cipher_list); return ERR; }
|
||||
|
||||
if(SSL_CTX_use_PrivateKey_file(data.ctx, cfg.pemfile, SSL_FILETYPE_PEM) != 1){ syslog(LOG_PRIORITY, "cannot load private key from %s", cfg.pemfile); return ERR; }
|
||||
|
||||
if(SSL_CTX_use_certificate_file(data.ctx, cfg.pemfile, SSL_FILETYPE_PEM) != 1){ syslog(LOG_PRIORITY, "cannot load certificate from %s", cfg.pemfile); return ERR; }
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
void initialise_configuration(){
|
||||
|
||||
cfg = read_config(configfile);
|
||||
|
||||
if(cfg.number_of_worker_processes < 5) cfg.number_of_worker_processes = 5;
|
||||
if(cfg.number_of_worker_processes > MAXCHILDREN) cfg.number_of_worker_processes = MAXCHILDREN;
|
||||
|
||||
if(strlen(cfg.username) > 1){
|
||||
pwd = getpwnam(cfg.username);
|
||||
if(!pwd) fatal(ERR_NON_EXISTENT_USER);
|
||||
}
|
||||
|
||||
|
||||
if(getuid() == 0 && pwd){
|
||||
check_and_create_directories(&cfg, pwd->pw_uid, pwd->pw_gid);
|
||||
}
|
||||
|
||||
|
||||
if(chdir(cfg.workdir)){
|
||||
syslog(LOG_PRIORITY, "workdir: *%s*", cfg.workdir);
|
||||
fatal(ERR_CHDIR);
|
||||
}
|
||||
|
||||
setlocale(LC_MESSAGES, cfg.locale);
|
||||
setlocale(LC_CTYPE, cfg.locale);
|
||||
|
||||
syslog(LOG_PRIORITY, "reloaded config: %s", configfile);
|
||||
|
||||
#ifdef HAVE_MEMCACHED
|
||||
memcached_init(&(data.memc), cfg.memcached_servers, 11211);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int i, rc, yes=1, daemonise=0;
|
||||
char port_string[8];
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
|
||||
while((i = getopt(argc, argv, "c:dvVh")) > 0){
|
||||
switch(i){
|
||||
|
||||
case 'c' :
|
||||
configfile = optarg;
|
||||
break;
|
||||
|
||||
case 'd' :
|
||||
daemonise = 1;
|
||||
break;
|
||||
|
||||
case 'v' :
|
||||
case 'V' :
|
||||
printf("%s %s, build %d, Janos SUTO <sj@acts.hu>\n\n%s\n\n", PILERGETD_PROGNAME, VERSION, get_build(), CONFIGURE_PARAMS);
|
||||
return 0;
|
||||
|
||||
case 'h' :
|
||||
default :
|
||||
__fatal("usage: ...");
|
||||
}
|
||||
}
|
||||
|
||||
(void) openlog(PILERGETD_PROGNAME, LOG_PID, LOG_MAIL);
|
||||
|
||||
data.ctx = NULL;
|
||||
data.ssl = NULL;
|
||||
|
||||
initialise_configuration();
|
||||
|
||||
if(cfg.tls_enable > 0 && init_ssl() == ERR) fatal("cannot init ssl");
|
||||
|
||||
set_signal_handler (SIGPIPE, SIG_IGN);
|
||||
|
||||
|
||||
if(read_key(&cfg)) fatal(ERR_READING_KEY);
|
||||
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
snprintf(port_string, sizeof(port_string)-1, "%d", cfg.pilergetd_listen_port);
|
||||
|
||||
if((rc = getaddrinfo(cfg.pilergetd_listen_addr, port_string, &hints, &res)) != 0){
|
||||
fprintf(stderr, "getaddrinfo for '%s': %s\n", cfg.pilergetd_listen_addr, gai_strerror(rc));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if((sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1)
|
||||
fatal(ERR_OPEN_SOCKET);
|
||||
|
||||
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
|
||||
fatal(ERR_SET_SOCK_OPT);
|
||||
|
||||
if(bind(sd, res->ai_addr, res->ai_addrlen) == -1)
|
||||
fatal(ERR_BIND_TO_PORT);
|
||||
|
||||
if(listen(sd, cfg.backlog) == -1)
|
||||
fatal(ERR_LISTEN);
|
||||
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
|
||||
if(drop_privileges(pwd)) fatal(ERR_SETUID);
|
||||
|
||||
|
||||
syslog(LOG_PRIORITY, "%s %s, build %d starting", PILERGETD_PROGNAME, VERSION, get_build());
|
||||
|
||||
|
||||
#if HAVE_DAEMON == 1
|
||||
if(daemonise == 1) i = daemon(1, 0);
|
||||
#endif
|
||||
|
||||
write_pid_file(cfg.pilergetd_pidfile);
|
||||
|
||||
|
||||
child_pool_create();
|
||||
|
||||
set_signal_handler(SIGCHLD, takesig);
|
||||
set_signal_handler(SIGTERM, takesig);
|
||||
set_signal_handler(SIGKILL, takesig);
|
||||
set_signal_handler(SIGHUP, takesig);
|
||||
|
||||
|
||||
for(;;){ sleep(1); }
|
||||
|
||||
p_clean_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
273
src/retr.c
273
src/retr.c
@ -1,273 +0,0 @@
|
||||
/*
|
||||
* retr.c, SJ
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <time.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <piler.h>
|
||||
|
||||
|
||||
int stat_file(struct session_data *sdata, char *f, char **buf, int buflen, struct __config *cfg){
|
||||
struct stat st;
|
||||
|
||||
snprintf(*buf, buflen, "%s/%02x/%c%c%c/%c%c/%c%c/%s", cfg->queuedir, cfg->server_id, f[8], f[9], f[10], f[RND_STR_LEN-4], f[RND_STR_LEN-3], f[RND_STR_LEN-2], f[RND_STR_LEN-1], f);
|
||||
if(!stat(*buf, &st)) return st.st_size;
|
||||
|
||||
#ifdef HAVE_SUPPORT_FOR_COMPAT_STORAGE_LAYOUT
|
||||
snprintf(*buf, TINYBUFSIZE-1, "%s/%02x/%c%c/%c%c/%c%c/%s", cfg->queuedir, cfg->server_id, f[RND_STR_LEN-6], f[RND_STR_LEN-5], f[RND_STR_LEN-4], f[RND_STR_LEN-3], f[RND_STR_LEN-2], f[RND_STR_LEN-1], f);
|
||||
if(!stat(*buf, &st)) return st.st_size;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int stat_message(struct session_data *sdata, struct __data *data, char **buf, int buflen, struct __config *cfg){
|
||||
int i, attachments, len=0;
|
||||
struct ptr_array ptr_arr[MAX_ATTACHMENTS];
|
||||
char puf[TINYBUFSIZE];
|
||||
|
||||
if(strlen(sdata->ttmpfile) != RND_STR_LEN){
|
||||
return ERR;
|
||||
}
|
||||
|
||||
snprintf(*buf, buflen-2, "%s.m", sdata->ttmpfile);
|
||||
len = strlen(*buf);
|
||||
|
||||
attachments = query_attachments(sdata, data, &ptr_arr[0], cfg);
|
||||
|
||||
if(attachments == -1){
|
||||
return ERR;
|
||||
}
|
||||
|
||||
for(i=1; i<=attachments; i++){
|
||||
if(len < buflen){
|
||||
snprintf(puf, sizeof(puf)-1, " %s.a%d", ptr_arr[i].piler_id, ptr_arr[i].attachment_id);
|
||||
strncat(*buf, puf, buflen);
|
||||
len += strlen(puf);
|
||||
}
|
||||
}
|
||||
|
||||
strncat(*buf, "\r\n", buflen-2);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int do_ssl_handshake(struct session_data *sdata, struct __data *data, int new_sd, struct __config *cfg){
|
||||
int ssl_ok=0, rc;
|
||||
char ssl_error[SMALLBUFSIZE];
|
||||
|
||||
if(data->ctx){
|
||||
data->ssl = SSL_new(data->ctx);
|
||||
|
||||
if(data->ssl){
|
||||
if(SSL_set_fd(data->ssl, new_sd) == 1){
|
||||
ssl_ok = 1;
|
||||
}
|
||||
else syslog(LOG_PRIORITY, "SSL_set_fd() failed");
|
||||
}
|
||||
else syslog(LOG_PRIORITY, "SSL_new() failed");
|
||||
}
|
||||
else syslog(LOG_PRIORITY, "SSL ctx is null!");
|
||||
|
||||
|
||||
if(ssl_ok == 0){
|
||||
send(new_sd, SMTP_RESP_421_ERR_TMP, strlen(SMTP_RESP_421_ERR_TMP), 0);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
|
||||
rc = SSL_accept(data->ssl);
|
||||
|
||||
if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "SSL_accept() finished");
|
||||
|
||||
if(rc == 1){
|
||||
sdata->tls = 1;
|
||||
return OK;
|
||||
}
|
||||
else {
|
||||
ERR_error_string_n(ERR_get_error(), ssl_error, SMALLBUFSIZE);
|
||||
syslog(LOG_PRIORITY, "SSL_accept() failed, rc=%d, errorcode: %d, error text: %s\n", rc, SSL_get_error(data->ssl, rc), ssl_error);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int handle_pilerget_request(int new_sd, struct __data *data, struct __config *cfg){
|
||||
int len, n, auth_ok=0, n_files=0;
|
||||
char *q, buf[MAXBUFSIZE], puf[MAXBUFSIZE], muf[TINYBUFSIZE], resp[MAXBUFSIZE];
|
||||
struct session_data sdata;
|
||||
int db_conn=0;
|
||||
struct __counters counters;
|
||||
|
||||
struct timezone tz;
|
||||
struct timeval tv1, tv2;
|
||||
|
||||
#ifdef HAVE_LIBWRAP
|
||||
struct request_info req;
|
||||
|
||||
request_init(&req, RQ_DAEMON, PILERGETD_PROGNAME, RQ_FILE, new_sd, 0);
|
||||
fromhost(&req);
|
||||
if(!hosts_access(&req)){
|
||||
send(new_sd, SMTP_RESP_550_ERR_YOU_ARE_BANNED_BY_LOCAL_POLICY, strlen(SMTP_RESP_550_ERR_YOU_ARE_BANNED_BY_LOCAL_POLICY), 0);
|
||||
syslog(LOG_PRIORITY, "denied connection from %s by tcp_wrappers", eval_client(&req));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
init_session_data(&sdata, cfg);
|
||||
sdata.tls = 0;
|
||||
|
||||
bzero(&counters, sizeof(counters));
|
||||
|
||||
|
||||
/* open database connection */
|
||||
|
||||
db_conn = 0;
|
||||
|
||||
#ifdef NEED_MYSQL
|
||||
if(open_database(&sdata, cfg) == OK){
|
||||
db_conn = 1;
|
||||
}
|
||||
else
|
||||
syslog(LOG_PRIORITY, "%s", ERR_MYSQL_CONNECT);
|
||||
#endif
|
||||
|
||||
if(db_conn == 0){
|
||||
send(new_sd, SMTP_RESP_421_ERR_TMP, strlen(SMTP_RESP_421_ERR_TMP), 0);
|
||||
syslog(LOG_PRIORITY, "cannot make prepared statement");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gettimeofday(&tv1, &tz);
|
||||
|
||||
|
||||
if(cfg->tls_enable > 0){
|
||||
if(do_ssl_handshake(&sdata, data, new_sd, cfg) == ERR) goto QUITTING;
|
||||
}
|
||||
else {
|
||||
auth_ok = 1;
|
||||
}
|
||||
|
||||
|
||||
snprintf(buf, MAXBUFSIZE-1, SMTP_RESP_220_BANNER, cfg->hostid);
|
||||
|
||||
write1(new_sd, buf, strlen(buf), sdata.tls, data->ssl);
|
||||
|
||||
if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "sent: %s", buf);
|
||||
|
||||
while((n = recvtimeoutssl(new_sd, puf, MAXBUFSIZE, TIMEOUT, sdata.tls, data->ssl)) > 0){
|
||||
|
||||
if(strncasecmp(puf, "MESSAGE ", strlen("MESSAGE ")) == 0 && auth_ok == 1){
|
||||
trimBuffer(puf);
|
||||
q = &resp[0];
|
||||
|
||||
memset(resp, 0, sizeof(resp));
|
||||
|
||||
snprintf(sdata.ttmpfile, sizeof(sdata.ttmpfile)-1, "%s", &puf[8]);
|
||||
stat_message(&sdata, data, &q, sizeof(resp)-2, cfg);
|
||||
|
||||
write1(new_sd, resp, strlen(resp), sdata.tls, data->ssl);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(strncasecmp(puf, "AUTH ", strlen("AUTH ")) == 0){
|
||||
trimBuffer(puf);
|
||||
q = &muf[0];
|
||||
|
||||
if(strcmp(&puf[5], cfg->pilergetd_password)){
|
||||
snprintf(resp, sizeof(resp)-1, "550 AUTH FAILED\r\n");
|
||||
}
|
||||
else {
|
||||
snprintf(resp, sizeof(resp)-1, "250 AUTH\r\n");
|
||||
auth_ok = 1;
|
||||
}
|
||||
|
||||
write1(new_sd, resp, strlen(resp), sdata.tls, data->ssl);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(strncasecmp(puf, "STAT ", strlen("STAT ")) == 0 && auth_ok == 1){
|
||||
trimBuffer(puf);
|
||||
q = &muf[0];
|
||||
|
||||
len = stat_file(&sdata, &puf[5], &q, sizeof(muf)-2, cfg);
|
||||
|
||||
snprintf(resp, sizeof(resp)-1, "SIZE %s %d\r\n", &puf[5], len);
|
||||
|
||||
write1(new_sd, resp, strlen(resp), sdata.tls, data->ssl);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(strncasecmp(puf, "RETR ", strlen("RETR ")) == 0 && auth_ok == 1){
|
||||
|
||||
trimBuffer(puf);
|
||||
q = &muf[0];
|
||||
|
||||
if(strlen(&puf[5]) >= RND_STR_LEN){
|
||||
len = stat_file(&sdata, &puf[5], &q, sizeof(muf)-2, cfg);
|
||||
file_from_archive_to_network(muf, new_sd, sdata.tls, data, cfg);
|
||||
n_files++;
|
||||
}
|
||||
else {
|
||||
snprintf(resp, sizeof(resp)-1, "ERR\r\n");
|
||||
write1(new_sd, resp, strlen(resp), sdata.tls, data->ssl);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(strncasecmp(puf, SMTP_CMD_QUIT, strlen(SMTP_CMD_QUIT)) == 0){
|
||||
snprintf(resp, sizeof(resp)-1, SMTP_RESP_221_GOODBYE, cfg->hostid);
|
||||
write1(new_sd, resp, strlen(resp), sdata.tls, data->ssl);
|
||||
|
||||
gettimeofday(&tv2, &tz);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(resp, sizeof(resp)-1, "550 ERR INVALID COMMAND\r\n");
|
||||
write1(new_sd, resp, strlen(resp), sdata.tls, data->ssl);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
QUITTING:
|
||||
|
||||
#ifdef NEED_MYSQL
|
||||
close_database(&sdata);
|
||||
#endif
|
||||
|
||||
SSL_shutdown(data->ssl);
|
||||
SSL_free(data->ssl);
|
||||
|
||||
if(cfg->verbosity >= _LOG_DEBUG) syslog(LOG_PRIORITY, "served %d files", n_files);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user