/* -------------------------------------------------------------------- */ /* SMS Client, send messages to mobile phones and pagers */ /* */ /* snppd.c */ /* */ /* Copyright (C) 1997,1998,1999 Angelo Masci */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU Library General Public */ /* License as published by the Free Software Foundation; either */ /* version 2 of the License, or (at your option) any later version. */ /* */ /* This library 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 */ /* Library General Public License for more details. */ /* */ /* You should have received a copy of the GNU Library General Public */ /* License along with this library; if not, write to the Free */ /* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* */ /* You can contact the author at this e-mail address: */ /* */ /* angelo@styx.demon.co.uk */ /* */ /* -------------------------------------------------------------------- $Id$ -------------------------------------------------------------------- */ #include #include #include #include #include #if defined(LINUX) #include #endif #include "lock/lock.h" #include "server.h" #include "logfile/logfile.h" #include "common/common.h" #include "version.h" /* -------------------------------------------------------------------- */ #if !defined(MSNPPDLOGFILE) #error "MSNPPDLOGFILE undefined" #else #define LOGFILE MSNPPDLOGFILE #endif #if !defined(MSNPPDLOGLEVEL) #error "MSNPPDLOGLEVEL undefined" #else #define LOGLEVEL MSNPPDLOGLEVEL #endif #if !defined(MVERSION) #error "MVERSION undefined" #else #define VERSION MVERSION #endif /* -------------------------------------------------------------------- */ #define SNPP_PORT 444 /* Standard port number */ /* assigned for snpp traffic */ #define SNPPD_SPOOLDIR "/var/spool/sms" #define SNPPD_LOCKDIR "locks" #define SNPPD_LOCKFILE SNPPD_SPOOLDIR SNPPD_LOCKDIR "/snppd.pid" /* -------------------------------------------------------------------- */ #define ERROR_STATE -2 #define EXIT_STATE -1 #define LOGIN_STATE 0 #define PAGE_STATE 1 #define MESSAGE_STATE 2 #define SEND_STATE 3 #define HELP_STATE 4 /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ void gateway(int new_fd) { char buf[MAX_STRING_LEN], host_name[512], ip_address[512]; int state; if (get_client_information(new_fd, host_name, ip_address) == 0) { lprintf(LOG_STANDARD, "Connection from %s [%s]\n", host_name, ip_address); } hprintf(new_fd, "220 SNPP Gateway Ready\n"); state = LOGIN_STATE; while ((state != EXIT_STATE) && (state != ERROR_STATE) && (hgets(buf, MAX_STRING_LEN, new_fd) != NULL)) { if (strncasecmp(buf, "PAGE", 4) == 0) { if (state == LOGIN_STATE) { hprintf(new_fd, "250 Pager ID Accepted\n"); state = PAGE_STATE; } else { state = ERROR_STATE; } } else if (strncasecmp(buf, "MESS", 4) == 0) { if (state == PAGE_STATE) { hprintf(new_fd, "250 Message OK\n"); state = MESSAGE_STATE; } else { state = ERROR_STATE; } } else if (strncasecmp(buf, "SEND", 4) == 0) { if (state == MESSAGE_STATE) { hprintf(new_fd, "250 Message Sent Successfully\n"); state = SEND_STATE; } else { state = ERROR_STATE; } } else if (strncasecmp(buf, "QUIT", 4) == 0) { hprintf(new_fd, "221 OK, Goodbye\n"); state = EXIT_STATE; } else if (strncasecmp(buf, "RESE", 4) == 0) { hprintf(new_fd, "250 RESET OK\n"); state = LOGIN_STATE; } else if (strncasecmp(buf, "HELP", 4) == 0) { hprintf(new_fd, "214 PAGE \n"); hprintf(new_fd, "214 MESS \n"); hprintf(new_fd, "214 SEND\n"); hprintf(new_fd, "214 QUIT\n"); hprintf(new_fd, "250 End of Help Information\n"); state = LOGIN_STATE; } else { state = ERROR_STATE; } if (state == ERROR_STATE) { hprintf(new_fd, "421 Error Connection Terminated\n"); } } } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ void usage(char *file) { lprintf(LOG_STANDARD, "Usage: %s [-l loglevel] [-p port]\n", file); lprintf(LOG_STANDARD, " %s -v\n", file); } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ void release_lock(void) { resource_unlock(SNPPD_LOCKFILE); } /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int c, port; char *ptr; struct sockaddr sa_client; /* ---------------------------- */ set_logfile(LOGFILE); set_loglevel(LOGLEVEL); set_consolelog(TRUE); /* ---------------------------- */ port = SNPP_PORT; while ((c = getopt (argc, argv, "p:l:v")) != -1) { switch (c) { case 'p': port = (int)strtol(optarg, &ptr, 10); break; case 'l': set_loglevel((int)strtol(optarg, &ptr, 10)); if (ptr == optarg) { lprintf(LOG_ERROR, "Option l requires an argument\n"); usage(argv[0]); exit(-1); } break; case 'v': lprintf(LOG_STANDARD, "%s %s\n", argv[0], VERSION); exit(0); case '?': lprintf(LOG_ERROR, "Unknown option `-%c'\n", optopt); usage(argv[0]); exit(-1); default: abort (); } } if ((argc - optind) != 0) { usage(argv[0]); exit(-1); } /* ---------------------------- */ c = sizeof(sa_client); if (getpeername(fileno(stdin), &sa_client, &c) < 0) { /* getpeername() fails if fd isn't a */ /* socket. If this is the case we can */ /* assume that we aren't running */ /* from inetd and should startup and */ /* as and run as a daemon ourselves. */ lprintf(LOG_STANDARD, "Starting SNPPD Standalone Server deamon...\n"); if (server_main(port, gateway, SNPPD_LOCKFILE) == -1) { lprintf(LOG_STANDARD, "Failed to start SNPPD Standalone Server deamon\n"); exit(-1); } } else { set_consolelog(FALSE); lprintf(LOG_STANDARD, "Starting SNPPD Server as an INETD service\n"); gateway(fileno(stdin)); } return 0; }