/* * Copyright (C) 2006 Tony Sin(x) '76 * All rights reserved. * */ /* * GNU GENERAL PUBLIC LICENSE * Version 2, June 1991 * * Copyright (C) 1989, 1991 Free Software Foundation, Inc. * 675 Mass Ave, Cambridge, MA 02139, USA * Everyone is permitted to copy and distribute verbatim copies * of this license document, but changing it is not allowed. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * 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. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifdef HAVE_CONFIG_H #ifndef __main_config_h__ #define __main_config_h__ #include "../config.h" #endif #include #include #include #include #include #include #include #ifndef __USE_MISC #define __USE_MISC #endif #include #ifndef SUN_LEN #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen ((ptr)->sun_path) + 1) #endif #include #include #include #endif #include "courier.h" #include "exception.h" #include "scan.h" cCourierTask::cCourierTask() { int err; try { no_exception = false; if ((err = pthread_create(&thid,NULL,cCourierTask::taskProc,(void *) this))) throw cException(COURIER_TASK_CLASS_NAME,COURIER_TASK_CLASS_NAME,"pthread_create",err); } catch (cException c_e) { syslog(LOG_ERR,"%s",c_e.str); /* signal TERM, do "filterctl" */ } } cCourierTask::~cCourierTask() { int err; no_exception = true; try { if (shutdown(mainSock,SHUT_RDWR) == -1) throw cException(COURIER_TASK_CLASS_NAME,COURIER_TASK_CLASS_NAME_D,"shutdown",errno); if (close(mainSock) == -1) throw cException(COURIER_TASK_CLASS_NAME,COURIER_TASK_CLASS_NAME_D,"close",errno); if ((err = pthread_join(thid,NULL))) throw cException(COURIER_TASK_CLASS_NAME,COURIER_TASK_CLASS_NAME_D,"pthread_join",err); } catch (cException c_e) { syslog(LOG_ERR,"%s",c_e.str); } } bool cCourierTask::initSocket() { struct sockaddr_un socket_addr; char old_sock_file[128], new_sock_file[128]; bool result = true; try { sprintf(old_sock_file,"%s/.%s",COURIER_FILTER_PATH,PACKAGE); sprintf(new_sock_file,"%s/%s",COURIER_FILTER_PATH,PACKAGE); if ((unlink(old_sock_file) == -1) && (errno != ENOENT)) throw cException(COURIER_TASK_CLASS_NAME,"initSocket","unlink(old_sock_file)",errno); if ((unlink(new_sock_file) == -1) && (errno != ENOENT)) throw cException(COURIER_TASK_CLASS_NAME,"initSocket","unlink(new_sock_file)",errno); memset((void *) &socket_addr,0,sizeof(struct sockaddr_un)); socket_addr.sun_family = AF_UNIX; strcpy(socket_addr.sun_path,old_sock_file); #ifdef HAVE_SOCKADDR_LEN socket_addr.sun_len = SUN_LEN(&socket_addr); #endif if ((mainSock = socket(PF_UNIX,SOCK_STREAM,0)) == -1) throw cException(COURIER_TASK_CLASS_NAME,"initSocket","socket",errno); if (bind(mainSock,(struct sockaddr *) &socket_addr,SUN_LEN(&socket_addr)) == -1) throw cException(COURIER_TASK_CLASS_NAME,"initSocket","bind",errno); if (chmod(old_sock_file,0666) == -1) throw cException(COURIER_TASK_CLASS_NAME,"initSocket","chmod",errno); if (rename(old_sock_file,new_sock_file) == -1) throw cException(COURIER_TASK_CLASS_NAME,"initSocket","rename",errno); if (listen(mainSock,MAX_QUEUE_SIZE) == -1) throw cException(COURIER_TASK_CLASS_NAME,"initSocket","listen",errno); } catch (cException c_e) { result = false; syslog(LOG_ERR,"%s",c_e.str); /* signal TERM, do "filterctl" */ } return result; } int cCourierTask::waitForMail() { int locsock_id = 0; struct sockaddr_un socket_addr; socklen_t socket_len; try { memset((void *) &socket_addr,0,sizeof(struct sockaddr_un)); #ifdef HAVE_SOCKADDR_LEN socket_addr.sun_len = sizeof(struct sockaddr_un); #endif socket_len = sizeof(struct sockaddr_un); if (((locsock_id = accept(mainSock,(struct sockaddr *) &socket_addr,&socket_len)) == -1) && (!no_exception)) throw cException(COURIER_TASK_CLASS_NAME,"waitForMail","accept",errno); } catch (cException c_e) { /* signal TERM, do "filterctl" */ syslog(LOG_ERR,"%s",c_e.str); } return locsock_id; } void *cCourierTask::taskProc(void *arg) { int msg_sock; cCourierTask *ptr = (cCourierTask *) arg; cScanTask *scan; try { syslog(LOG_INFO,"cCourierTask started"); if (!ptr->initSocket()) throw cException(); if (close(COURIER_FILE_DESC) == -1) throw cException(COURIER_TASK_CLASS_NAME,"taskProc","close",errno); syslog(LOG_INFO,"cCourierTask active"); while ((msg_sock = ptr->waitForMail()) > 0) scan = new cScanTask(msg_sock); syslog(LOG_INFO,"cCourierTask terminated"); } catch (cException c_e) { if (strlen(c_e.str) > 0) syslog(LOG_ERR,"%s",c_e.str); /* signal TERM, do "filterctl" */ } return NULL; }