/* * ---------------------------------------------------------------- * Night Light System Functions * ---------------------------------------------------------------- * Copyright (C) 1997-2003 Jonas Kvinge * All rights reserved. * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Last modified by: * Jonas Kvinge (15.11.2006) * */ #define SYSCALLS_C #define NEED_SYS_TYPES_H 1 /* Extra types */ #define NEED_SYS_PARAM_H 1 /* Some systems need this */ #define NEED_LIMITS_H 1 /* Kernel limits */ #define NEED_STDARG_H 1 /* va_list, etc */ #define NEED_ERRNO_H 1 /* errno */ #define NEED_CTYPE_H 1 /* isdigit(), etc */ #define NEED_NETINET_IN_H 1 /* in_addr, sockaddr_in, etc */ #define NEED_ARPA_INET_H 1 /* inet_ntoa(), inet_aton(), etc */ #define NEED_STDIO_H 1 /* Standard C UNIX functions */ #define NEED_STDLIB_H 1 /* malloc(), exit(), atoi(), etc */ #define NEED_TIME_H 1 /* time(), etc */ #define NEED_SYSCTL_H 0 /* sysctl(), etc */ #define NEED_SYS_STAT_H 1 /* chmod(), mkdir(), etc */ #define NEED_SYS_UIO_H 0 /* iovec, etc */ #define NEED_FCNTL_H 1 /* open(), creat(), fcntl(), etc */ #define NEED_SYS_IOCTL_H 1 /* ioctl(), etc */ #define NEED_SYS_FILIO_H 1 /* Solaris need this for ioctl(), etc */ #define NEED_UNISTD_H 1 /* Unix standard functions */ #define NEED_STRING_H 1 /* C string functions */ #define NEED_SIGNAL_H 1 /* Signal functions */ #define NEED_SYS_SOCKET_H 1 /* Socket functions */ #define NEED_NETDB_H 0 /* Network database functions */ #define NEED_ARPA_NAMESER_H 0 /* Nameserver definitions */ #define NEED_GETUSERPW_HEADERS 1 /* Functions to retrive system passwords */ #include "includes.h" #include "nlstrsignal.h" #include "main.h" #include "conf.h" #if DCC #include "dcc_conn.h" #endif /* VARIABLES - JONAS (23.08.2001) */ const char SYSCALLS_VERSION[] = "1.3.5d"; unsigned short int ScreenMode = TRUE; unsigned short int ScreenPrint = TRUE; unsigned short int ScreenDTS = TRUE; unsigned short int Run = TRUE; unsigned short int Exit = FALSE; unsigned short int Root = FALSE; static pid_t PID = 0; time_t StartTime = 0; time_t FlushTime = 0; time_t ExitTime = 0; #if !WIN32 uid_t UID_Current = 0; uid_t EUID_Current = 0; uid_t UID_Normal = 0; uid_t EUID_Normal = 0; gid_t GID_Current = 0; gid_t EGID_Current = 0; gid_t GID_Normal = 0; gid_t EGID_Normal = 0; #endif unsigned short int ExitSignals = 0; char *TMPSTRPT = NULL; extern unsigned long int ScreenBitmask; extern struct PrintFile_Struct PrintFileS[]; extern unsigned short int PrintFileS_Len; extern struct Conf_Struct ConfS; /* SYSINIT FUNCTION - JONAS (27.02.2002) */ void sysinit(void) { signed long int Flags = 0; signed long int Result = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "System initialization."); PID = getpid(); NOW = time(NULL); srand(NOW); StartTime = NOW; #if defined(NBLOCK_SYSV) Flags = 1; Result = ioctl(STDIN_FILENO, FIONBIO, &Flags); #else Flags = fcntl(STDIN_FILENO, F_GETFL); if (Flags <= ERROR) { Flags = 0; } #if defined(NBLOCK_BSD) Flags |= O_NDELAY; #elif defined(NBLOCK_POSIX) Flags |= O_NONBLOCK; #else #warning "This system does not support non-blocking sockets?" Flags |= O_NONBLOCK; #endif Result = fcntl(STDIN_FILENO, F_SETFL, Flags); #endif strgetunameinfo(); strgetplatform(); strgetosname(); strgetosrelease(); strgethostname(); } #if !WIN32 /* SYSINITID FUNCTION - JONAS (18.07.2001) */ void sysinitid(void) { signed long int Result = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Initializing ID."); UID_Current = getuid(); EUID_Current = geteuid(); GID_Current = getgid(); EGID_Current = getegid(); UID_Normal = UID_Current; GID_Normal = GID_Current; if (UID_Current == 0) { Root = TRUE; assert(ConfS.EUser != NULL); EUID_Normal = sysgetuidfromuser(ConfS.EUser); if (aerrno != AESUCCESS) { printf("%s: No such user.\n", ConfS.EUser); printf("Cannot start %s from root without a vaild EUSER.\n", PACKAGE); exit(ERROR); } if (EUID_Normal == 0) { printf("You must set EUSER to something else than root!\n"); exit(ERROR); } EGID_Normal = sysgetgidfromgroup(ConfS.EGroup); if (aerrno != AESUCCESS) { printf("%s: No such group.\n", ConfS.EGroup); printf("Cannot start %s from root without a vaild EGROUP.\n", PACKAGE); exit(ERROR); } if (EGID_Normal == 0) { printf("You must set EGROUP to something else than (root/system/wheel)!\n"); exit(ERROR); } } else { Root = FALSE; EUID_Normal = EUID_Current; EGID_Normal = EGID_Current; } if (ConfS.ChDir == TRUE) { Result = chdir(ConfS.ChDirPath); if (Result == ERROR) { printf("Unable to change working directory to %s (CHDIRPATH): [%d] %s\n", ConfS.ChDirPath, errno, strerror(errno)); exit(ERROR); } } if (GID_Current == 0) { Result = setegid(EGID_Normal); if (Result <= ERROR) { printf("Unable to change effective group ID to %ld: [%d] %s\n", (PRINT_GID_T) EGID_Normal, errno, strerror(errno)); exit(1); } EGID_Current = EGID_Normal; } if (UID_Current == 0) { Result = seteuid(EUID_Normal); if (Result <= ERROR) { printf("Unable to change effective user ID to %ld: [%d] %s\n", (PRINT_UID_T) EUID_Normal, errno, strerror(errno)); exit(1); } EUID_Current = EUID_Normal; } assert(EUID_Current == EUID_Normal); assert(EGID_Current == EGID_Normal); assert(EUID_Current == geteuid()); assert(EGID_Current == getegid()); assert(EUID_Current != 0); assert(EGID_Current != 0); } #endif #if !WIN32 /* SYSSETEUIDNORMAL FUNCTION - JONAS (01.07.2000) */ signed long int sysseteuidnormal(void) { signed long int Result = 0; if (EUID_Current == EUID_Normal) { return(SUCCESS); } if (EUID_Current != 0) { Result = seteuid(0); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to root (0): [%d] %s", errno, strerror(errno)); exit(1); } EUID_Current = 0; } Result = seteuid(EUID_Normal); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to normal (%ld): [%d] %s", (PRINT_UID_T) EUID_Normal, errno, strerror(errno)); exit(1); } EUID_Current = EUID_Normal; return(SUCCESS); } #endif #if !WIN32 /* SYSSETUID FUNCTION - JONAS (01.07.2000) */ signed long int sysseteuid(const uid_t UID) { signed long int Result = 0; if (UID_Current != 0) { return(ERROR); } if (EUID_Current == UID) { return(SUCCESS); } Result = seteuid(0); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to root (0): [%d] %s", errno, strerror(errno)); return(ERROR); } EUID_Current = 0; if (UID == 0) { return(SUCCESS); } Result = seteuid(UID); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to %ld: [%d] %s", (PRINT_UID_T) UID, errno, strerror(errno)); Result = seteuid(EUID_Normal); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to normal (%ld): [%d] %s", (PRINT_UID_T) EUID_Normal, errno, strerror(errno)); exit(1); } return(ERROR); } EUID_Current = UID; return(SUCCESS); } #endif #if !WIN32 /* SYSSETUIDBYUSER FUNCTION - JONAS (01.07.2000) */ signed long int sysseteuidbyuser(const char *const UserPT) { signed long int Result = 0; uid_t UID = 0; assert(UserPT != NULL); if (UID_Current != 0) { return(ERROR); } UID = sysgetuidfromuser(UserPT); if (aerrno != AESUCCESS) { return(ERROR); } if (EUID_Current == UID) { return(SUCCESS); } Result = sysseteuid(UID); return(Result); } #endif /* SYSINITFILES FUNCTION - JONAS (27.02.2002) */ void sysinitfiles(void) { unsigned short int Index = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Initializing all files."); for (Index = 0 ; Index < PrintFileS_Len ; Index++) { char File[FILELEN+1] = ""; assert(PrintFileS[Index].Name != NULL); if ((strncmp(PrintFileS[Index].Name, ConfS.LogPath, strlen(ConfS.LogPath)) != FALSE) && (PrintFileS[Index].Name[0] != '/')) { memset(File, 0, FILELEN+1); strncat(File, ConfS.LogPath, (FILELEN - strlen(File))); if (File[strlen(File)] != '/') { strncat(File, "/", (FILELEN - strlen(File))); } strncat(File, PrintFileS[Index].Name, (FILELEN - strlen(File))); PrintFileS[Index].Name = strrealloc(PrintFileS[Index].Name, File); } assert(PrintFileS[Index].Name != NULL); if (Index == 2) { PrintFileS[Index].FilePT = stderr; } else { PrintFileS[Index].FilePT = stdout; } } } /* SYSCLOSEFILES FUNCTION - JONAS (25.06.2000) */ void sysclosefiles(void) { unsigned long int FD = 0; unsigned long int FDL = sysconf(_SC_OPEN_MAX); DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Closing all files."); for (FD = 0 ; FD <= FDL ; FD++) { close(FD); } } /* SYSOPENFILES_FG FUNCTION - JONAS (18.07.2001) */ void sysopenfiles_fg(void) { unsigned short int Index = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Opening files (foreground)."); for (Index = 1 ; Index < PrintFileS_Len ; ++Index) { assert(PrintFileS[Index].Name != NULL); PrintFileS[Index].FilePT = fopen(PrintFileS[Index].Name, "a"); if (PrintFileS[Index].FilePT == NULL) { printf("Unable to open %s: [%d] %s\n", PrintFileS[Index].Name, errno, strerror(errno)); exit(1); } } } #if !WIN32 /* SYSOPENFILES_BG FUNCTION - JONAS (18.07.2001) */ void sysopenfiles_bg(void) { signed long int Result = 0; unsigned short int Index = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Opening files (background)."); for (Index = 0 ; Index < PrintFileS_Len ; ++Index) { if ((PrintFileS[Index].FilePT == NULL) || (PrintFileS[Index].FilePT == stdin) || (PrintFileS[Index].FilePT == stdout) || (PrintFileS[Index].FilePT == stderr)) { continue; } Result = fclose(PrintFileS[Index].FilePT); if (Result == EOF) { sysprint(BITMASK_ERROR, "Unable to close %s: [%d] %s", PrintFileS[Index].Name, errno, strerror(errno)); exit(1); } PrintFileS[Index].FilePT = NULL; } close(0); close(1); close(2); #if 0 FD_CLR(0, &ReadFDS); FD_CLR(0, &WriteFDS); FD_CLR(1, &ReadFDS); FD_CLR(1, &WriteFDS); FD_CLR(2, &ReadFDS); FD_CLR(2, &WriteFDS); #endif for (Index = 0 ; Index < PrintFileS_Len ; ++Index) { switch (Index) { case 0: case 1: case 2: Result = open(PrintFileS[Index].Name, (O_CREAT|O_NONBLOCK|O_WRONLY|O_APPEND), (S_IRUSR|S_IWUSR|S_IRGRP)); assert(Result == Index); if (Result != Index) { abort(); } if (Index == 0) { PrintFileS[Index].FilePT = NULL; } else if (Index == 1) { PrintFileS[Index].FilePT = stdout; } else if (Index == 2) { PrintFileS[Index].FilePT = stderr; } break; default: PrintFileS[Index].FilePT = fopen(PrintFileS[Index].Name, "a"); if (PrintFileS[Index].FilePT == NULL) { sysprint(BITMASK_ERROR, "Unable to open %s: [%d] %s", PrintFileS[Index].Name, errno, strerror(errno)); exit(1); } } } } #endif /* SYSFLUSHFILES FUNCTION - JONAS (18.07.2001) */ void sysflushfiles(void) { signed long int Result = 0; unsigned long int Index = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Flushing all file descriptors..."); FlushTime = NOW; for (Index = 0 ; Index < PrintFileS_Len ; Index++) { if (PrintFileS[Index].Name == NULL) { continue; } if (PrintFileS[Index].FilePT == NULL) { continue; } Result = fflush(PrintFileS[Index].FilePT); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to flush %s: [%d] %s", PrintFileS[Index].Name, errno, strerror(errno)); exit(1); } } } #if !WIN32 /* SYSCHECKPID FUNCTION - JONAS (11.07.2001) */ void syscheckpid(void) { FILE *FilePT = NULL; char Line[LINELEN+1] = ""; char *LinePT = NULL; unsigned long int pid = 0; signed long int Result = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Checking PID file."); if ((UID_Current == 0) && (EUID_Current != 0)) { Result = seteuid(0); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to root (0): [%d] %s", errno, strerror(errno)); } else { EUID_Current = 0; } } FilePT = fopen(ConfS.PIDFile, "r"); if (FilePT == NULL) { if (errno != ENOENT) { sysprint(BITMASK_ERROR, "Unable to open %s for reading: [%d] %s", ConfS.PIDFile, errno, strerror(errno)); } } else { LinePT = fgets(Line, LINELEN, FilePT); if (LinePT != NULL) pid = atoi(LinePT); if (pid <= 1) { fclose(FilePT); } else { Result = kill(pid, SIGUSR1); if (Result != ERROR) { fclose(FilePT); printf("%s already running, PID: %ld\n", PACKAGE, (PRINT_PID_T) pid); exit(1); } fclose(FilePT); } } if (EUID_Current != EUID_Normal) { Result = seteuid(EUID_Normal); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to %ld: [%d] %s", (PRINT_UID_T) EUID_Normal, errno, strerror(errno)); exit(1); } EUID_Current = EUID_Normal; } } #endif #if !WIN32 /* SYSWRITEPID FUNCTION - JONAS (25.06.2000) */ void syswritepid(void) { signed long int Result = 0; FILE *FilePT = NULL; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Writing PID file, current PID: %ld.", (PRINT_PID_T) PID); if ((UID_Current == 0) && (EUID_Current != 0)) { Result = seteuid(0); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to root (0): [%d] %s", errno, strerror(errno)); } else { EUID_Current = 0; } } FilePT = fopen(ConfS.PIDFile, "w"); if (FilePT == NULL) { sysprint(BITMASK_ERROR, "Unable to open %s for writing: [%d] %s", ConfS.PIDFile, errno, strerror(errno)); exit(1); } fprintf(FilePT, "%ld%s", (PRINT_PID_T) PID, LINEFEED); fclose(FilePT); if (EUID_Current != EUID_Normal) { Result = seteuid(EUID_Normal); if (Result <= ERROR) { sysprint(BITMASK_ERROR, "Unable to change effective user ID to %ld: [%d] %s", (PRINT_UID_T) EUID_Normal, errno, strerror(errno)); exit(1); } EUID_Current = EUID_Normal; } } #endif /* SYSSETSIGNALS FUNCTION - JONAS (25.06.2000) */ void syssetsignals(void) { void *ResultPT = NULL; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Setting signals."); #ifdef SIGHUP ResultPT = signal(SIGHUP, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Hangup\"."); } #endif #ifdef SIGINT ResultPT = signal(SIGINT, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Interrupt\"."); } #endif #ifdef SIGQUIT ResultPT = signal(SIGQUIT, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Quit\"."); } #endif #ifdef SIGILL ResultPT = signal(SIGILL, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Illegal instruction\"."); } #endif #ifdef SIGTRAP ResultPT = signal(SIGTRAP, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Trace trap\"."); } #endif #ifdef SIGABRT ResultPT = signal(SIGABRT, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Abort\"."); } #endif #ifdef SIGIOT ResultPT = signal(SIGIOT, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Abort\"."); } #endif #ifdef SIGEMT ResultPT = signal(SIGEMT, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"EMT instruction\"."); } #endif #ifdef SIGFPE ResultPT = signal(SIGFPE, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Floating-point exception\"."); } #endif #ifdef SIGBUS ResultPT = signal(SIGBUS, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Bus error\"."); } #endif #ifdef SIGSEGV ResultPT = signal(SIGSEGV, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Segmentation violation\"."); } #endif #ifdef SIGSYS ResultPT = signal(SIGSYS, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Non-existent system call invoked\"."); } #endif #ifdef SIGPIPE ResultPT = signal(SIGPIPE, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Broken pipe\"."); } #endif #ifdef SIGALRM ResultPT = signal(SIGALRM, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Alarm clock\"."); } #endif #ifdef SIGTERM ResultPT = signal(SIGTERM, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Termination\"."); } #endif #ifdef SIGURG ResultPT = signal(SIGURG, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Urgent condition on IO channel\"."); } #endif #ifdef SIGTSTP ResultPT = signal(SIGTSTP, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Stop signal from tty\"."); } #endif #ifdef SIGCONT ResultPT = signal(SIGCONT, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Continue a stopped process\"."); } #endif #ifdef SIGCHLD ResultPT = signal(SIGCHLD, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Signal to parent on child stop or exit\"."); } #endif #ifdef SIGTTIN ResultPT = signal(SIGTTIN, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Background read from tty\"."); } #endif #ifdef SIGTTOU ResultPT = signal(SIGTTOU, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Background write to tty\"."); } #endif #ifdef SIGIO ResultPT = signal(SIGIO, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"I/O possible\"."); } #endif #ifdef SIGXCPU ResultPT = signal(SIGXCPU, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Exceeded CPU time limit\"."); } #endif #ifdef SIGXFSZ ResultPT = signal(SIGXFSZ, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Exceeded file size limit\"."); } #endif #ifdef SIGVTALRM ResultPT = signal(SIGVTALRM, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Virtual alarm clock\"."); } #endif #ifdef SIGPROF ResultPT = signal(SIGPROF, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Profiling alarm clock\"."); } #endif #ifdef SIGWINCH ResultPT = signal(SIGWINCH, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Window size change\"."); } #endif #if 0 ResultPT = signal(SIGINFO, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Information request\"."); } #endif #ifdef SIGUSR1 ResultPT = signal(SIGUSR1, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"User-defined signal 1\"."); } #endif #ifdef SIGUSR2 ResultPT = signal(SIGUSR2, SIG_IGN); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"User-defined signal 1\"."); } #endif #ifdef SIGPWR ResultPT = signal(SIGPWR, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Power failure restart\"."); } #endif #ifdef SIGSTKFLT ResultPT = signal(SIGSTKFLT, syshandlesignal); if (ResultPT == SIG_ERR) { sysprint(BITMASK_ERROR, "Unable to install signal handler for \"Stack fault\"."); } #endif } /* SYSHANDLESIGNAL FUNCTION - JONAS (26.03.2002) */ void syshandlesignal(int Signal) { signal(Signal, syshandlesignal); /* Signals telling us to rehash the configuration */ #ifdef SIGHUP if (Signal == SIGHUP) { /* Hangup */ sysprint(BITMASK_MAIN, "Caught signal %d, %s.", Signal, nlstrsignal(Signal)); main_rehash(); return; } #endif /* Signals telling us to exit normally */ if ( (1 == 2) #ifdef SIGINT || (Signal == SIGINT) /* Interrupt */ #endif #ifdef SIGTERM || (Signal == SIGTERM) /* Termination */ #endif ) { ExitSignals++; if (ExitSignals >= 3) { exit(0); } sysprint(BITMASK_MAIN, "Caught signal %d, %s.", Signal, nlstrsignal(Signal)); sysflushfiles(); main_exit("Caught signal %d, %s", Signal, nlstrsignal(Signal)); return; } /* Signals telling us something went wrong */ if ( (1 == 2) #ifdef SIGQUIT || (Signal == SIGQUIT) /* Quit */ #endif #ifdef SIGILL || (Signal == SIGILL) /* Illegal instruction */ #endif #ifdef SIGTRAP || (Signal == SIGTRAP) /* Trace trap */ #endif #ifdef SIGABRT || (Signal == SIGABRT) /* Abort */ #endif #ifdef SIGIOT || (Signal == SIGIOT) /* Abort? */ #endif #ifdef SIGEMT || (Signal == SIGEMT) /* EMT instruction */ #endif #ifdef SIGFPE || (Signal == SIGFPE) /* Floating-point exception */ #endif #ifdef SIGBUS || (Signal == SIGBUS) /* BUS error */ #endif #ifdef SIGSEGV || (Signal == SIGSEGV) /* Segmentation violation */ #endif #ifdef SIGSYS || (Signal == SIGSYS) /* Non-existent system call invoked */ #endif #ifdef SIGSTKFLT || (Signal == SIGSTKFLT) /* Stack fault */ #endif #ifdef SIGPWR || (Signal == SIGPWR) /* Power failure restart */ #endif #ifdef SIGTSTP || (Signal == SIGTSTP) /* Stop signal from tty */ #endif #ifdef SIGXCPU || (Signal == SIGXCPU) /* Exceeded CPU time limit */ #endif #ifdef SIGXFSZ || (Signal == SIGXFSZ) /* Exceeded file size limit */ #endif ) { ExitSignals++; if (ExitSignals >= 3) { exit(0); } sysprint(BITMASK_ERROR, "Caught signal %d, %s.", Signal, nlstrsignal(Signal)); sysflushfiles(); main_exit("Caught signal %d, %s", Signal, nlstrsignal(Signal)); main_loop(); return; } /* And basically just print anything else */ sysprint(BITMASK_MAIN, "Caught signal %d, %s.", Signal, nlstrsignal(Signal)); } #if !WIN32 /* SYSFORK FUNCTION - JONAS (25.06.2000) */ void sysfork(void) { DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Going into the background..."); PID = fork(); switch(PID) { case ERROR: sysprint(BITMASK_ERROR, "Unable to create a child process: [%d] %s", errno, strerror(errno)); exit(1); case SUCCESS: if (setsid() == ERROR) { sysprint(BITMASK_ERROR, "Unable to request a new session: [%d] %s", errno, strerror(errno)); exit(1); } break; default: exit(0); } sysopenfiles_bg(); PID = getpid(); syswritepid(); DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Successfully went into the background, PID: %ld", (PRINT_PID_T) PID); ScreenMode = FALSE; } #endif /* SYSPRINT FUNCTION - JONAS (25.06.2000) */ void sysprint(const unsigned long int Bitmask, const char *const LinePT, ...) { char Line[LINELEN+1] = ""; va_list Args = { 0 }; unsigned short int Index = 0; assert(LinePT != NULL); va_start(Args, LinePT); vsnprintf(Line, LINELEN+1, LinePT, Args); va_end(Args); for (Index = 0 ; Index < PrintFileS_Len ; Index++) { if (PrintFileS[Index].FilePT == NULL) { continue; } if ((ScreenMode == TRUE) && (ScreenPrint == TRUE) && ((PrintFileS[Index].FilePT == stdout) || (PrintFileS[Index].FilePT == stderr))) { continue; } if (PrintFileS[Index].Bitmask & Bitmask) { fprintf(PrintFileS[Index].FilePT, "%s *** %s%s", dtstamp(), Line, LINEFEED); fflush(PrintFileS[Index].FilePT); } } if ((ScreenMode == TRUE) && (ScreenPrint == TRUE) && (ScreenBitmask & Bitmask)) { if (ScreenDTS == TRUE) { fprintf(stdout, "%s *** %s\n", dtstamp(), Line); } else { fprintf(stdout, "%s\n", Line); } fflush(stdin); fflush(stdout); fflush(stderr); } #if DCC dcc_conn_sendall(Bitmask, "*** %s\r\n", Line); #endif } /* DEBUGPRINT FUNCTION - JONAS (01.12.2007) */ void debugprint(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, const char *const TextLinePT, ...) { char TextLine[LINELEN+1] = ""; va_list Args = { 0 }; unsigned short int Index = 0; assert(FilePT != NULL); assert(FunctionPT != NULL); assert(TextLinePT != NULL); va_start(Args, TextLinePT); vsnprintf(TextLine, LINELEN+1, TextLinePT, Args); va_end(Args); for (Index = 0 ; Index < PrintFileS_Len ; Index++) { if ((PrintFileS[Index].Bitmask & BITMASK_DEBUG) && (PrintFileS[Index].FilePT != NULL)) { fprintf(PrintFileS[Index].FilePT, "%s *** DEBUG *** FILE: %s LINE: %d FUNCTION: %s *** %s%s", dtstamp(), FilePT, Line, FunctionPT, TextLine, LINEFEED); fflush(PrintFileS[Index].FilePT); } } if ((ScreenMode == TRUE) && (ScreenPrint == TRUE) && (ScreenBitmask & BITMASK_DEBUG)) { if (ScreenDTS == TRUE) { fprintf(stdout, "%s *** DEBUG *** FILE: %s LINE: %d FUNCTION: %s *** %s%s", dtstamp(), FilePT, Line, FunctionPT, TextLine, LINEFEED); } else { fprintf(stdout, "*** DEBUG *** FILE: %s LINE: %d FUNCTION: %s *** %s%s", FilePT, Line, FunctionPT, TextLine, LINEFEED); } fflush(stdin); fflush(stdout); fflush(stderr); } #if DCC dcc_conn_sendall(BITMASK_DEBUG, "*** %s\r\n", Line); #endif } /* SYSREHASH FUNCTION - JONAS (01.07.2000) */ void sysrehash(void) { FILE *FilePT = fopen(ConfS.PIDFile, "r"); char Line[LINELEN+1] = ""; char *LinePT = NULL; pid_t pid = 0; signed long int Result = 0; if (FilePT == NULL) { printf("Cannot rehash %s: Unable to open PID file %s: [%d] %s\n", PACKAGE, ConfS.PIDFile, errno, strerror(errno)); return; } LinePT = fgets(Line, LINELEN, FilePT); if (LinePT != NULL) pid = atoi(LinePT); if (pid <= 1) { printf("Cannot rehash %s: Invalid PID: %ld.\n", PACKAGE, (PRINT_PID_T) pid); return; } Result = kill(pid, SIGHUP); if (Result == ERROR) { printf("Cannot rehash %s, PID: %ld: [%d] %s\n", PACKAGE, (PRINT_PID_T) pid, errno, strerror(errno)); fclose(FilePT); return; } printf("Sent HUP signal to %s, PID: %ld.\n", PACKAGE, (PRINT_PID_T) pid); fclose(FilePT); } /* SYSTERM FUNCTION - JONAS (01.07.2000) */ void systerm(void) { FILE *FilePT = fopen(ConfS.PIDFile, "r"); char Line[LINELEN+1] = ""; char *LinePT = NULL; pid_t pid = 0; signed long int Result = 0; if (FilePT == NULL) { printf("Cannot terminate %s: Unable to open PID file %s: [%d] %s\n", PACKAGE, ConfS.PIDFile, errno, strerror(errno)); return; } LinePT = fgets(Line, LINELEN, FilePT); if (LinePT != NULL) pid = atoi(Line); if (pid <= 1) { printf("Cannot terminate %s: Invalid PID: %ld.\n", PACKAGE, (PRINT_PID_T) pid); return; } Result = kill(pid, SIGTERM); if (Result == ERROR) { printf("Cannot terminate %s, PID: %ld: [%d] %s\n", PACKAGE, (PRINT_PID_T) pid, errno, strerror(errno)); fclose(FilePT); return; } printf("Sent TERM signal to %s, PID: %ld.\n", PACKAGE, (PRINT_PID_T) pid); fclose(FilePT); } /* SYSRUN FUNCTION - JONAS (01.07.2000) */ signed short int sysrun(const char *const CmdPT, char *ResultPT) { FILE *FilePT = NULL; signed long int Result = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Running shell command: %s", CmdPT); FilePT = popen(CmdPT, "r"); if (FilePT == NULL) { return(ERROR); } Result = fread(ResultPT, sizeof(char), RECVBUFFERLEN, FilePT); pclose(FilePT); return(Result); } #if !WIN32 /* SYSGETUIDFROMUSER FUNCTION - JONAS (01.07.2000) */ #if HAVE_GETPWNAM uid_t sysgetuidfromuser(const char *const UserPT) { struct passwd *PasswdPT = NULL; assert(UserPT != NULL); PasswdPT = getpwnam(UserPT); if (PasswdPT == NULL) { aerrno = AENOMATCH; return(0); } aerrno = AESUCCESS; return(PasswdPT->pw_uid); } #else uid_t sysgetuidfromuser(const char *const UserPT) { FILE *FilePT = NULL; char *TempPT = NULL; char Line[LINELEN+1] = ""; uid_t UID = 0; assert(UserPT != NULL); FilePT = fopen(PASSWD_FILE, "r"); if (FilePT == NULL) { sysprint(BITMASK_ERROR, "Unable to open %s: [%d] %s", PASSWD_FILE, errno, strerror(errno)); aerrno = AENORESOURCE; return(0); } FOREVERLOOP { TempPT = fgets(Line, LINELEN, FilePT); if (TempPT == NULL) { break; } while ((TempPT = strchr(Line, '\r')) != NULL) { *TempPT = '\0'; } while ((TempPT = strchr(Line, '\n')) != NULL) { *TempPT = '\0'; } if ((Line[0] == '#') || (Line[0] == ';') || (Line[0] == '\0')) { continue; } TempPT = strtok(Line, ":"); if (TempPT == NULL) { continue; } if (strcmp(TempPT, UserPT) != FALSE) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } UID = strtoul(TempPT, NULL, 0); fclose(FilePT); aerrno = AESUCCESS; return(UID); } fclose(FilePT); aerrno = AENOMATCH; return(0); } #endif /* HAVE_GETPWNAM */ #endif /* !WIN32 */ #if !WIN32 /* SYSGETNAMEFROMUSER FUNCTION - JONAS (01.07.2000) */ #if HAVE_GETPWNAM char *sysgetnamefromuser(const char *const UserPT) { struct passwd *PasswdPT = NULL; assert(UserPT != NULL); PasswdPT = getpwnam(UserPT); if (PasswdPT == NULL) { return(NULL); } TMPSTRPT = strrealloc(TMPSTRPT, PasswdPT->pw_gecos); return(TMPSTRPT); } #else char *sysgetnamefromuser(const char *const UserPT) { FILE *FilePT = NULL; char *TempPT = NULL; char Line[LINELEN+1] = ""; assert(UserPT != NULL); FilePT = fopen(PASSWD_FILE, "r"); if (FilePT == NULL) { sysprint(BITMASK_ERROR, "Unable to open %s: [%d] %s", PASSWD_FILE, errno, strerror(errno)); return(NULL); } FOREVERLOOP { TempPT = fgets(Line, LINELEN, FilePT); if (TempPT == NULL) { break; } while ((TempPT = strchr(Line, '\r')) != NULL) { *TempPT = '\0'; } while ((TempPT = strchr(Line, '\n')) != NULL) { *TempPT = '\0'; } if ((Line[0] == '#') || (Line[0] == ';') || (Line[0] == '\0')) { continue; } TempPT = strtok(Line, ":"); if (TempPT == NULL) { continue; } if (strcmp(TempPT, UserPT) != FALSE) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } fclose(FilePT); TMPSTRPT = strrealloc(TMPSTRPT, TempPT); return(TMPSTRPT); } fclose(FilePT); return(NULL); } #endif #endif #if !WIN32 /* SYSGETHOMEDIRFROMUSER FUNCTION - JONAS (01.07.2000) */ #if HAVE_GETPWNAM char *sysgethomedirfromuser(const char *const UserPT) { struct passwd *PasswdPT = NULL; assert(UserPT != NULL); PasswdPT = getpwnam(UserPT); if (PasswdPT == NULL) { return(NULL); } TMPSTRPT = strrealloc(TMPSTRPT, PasswdPT->pw_dir); return(TMPSTRPT); } #else char *sysgethomedirfromuser(const char *const UserPT) { FILE *FilePT = NULL; char *TempPT = NULL; char Line[LINELEN+1] = ""; assert(UserPT != NULL); FilePT = fopen(PASSWD_FILE, "r"); if (FilePT == NULL) { sysprint(BITMASK_ERROR, "Unable to open %s: [%d] %s", PASSWD_FILE, errno, strerror(errno)); return(NULL); } FOREVERLOOP { TempPT = fgets(Line, LINELEN, FilePT); if (TempPT == NULL) { break; } while ((TempPT = strchr(Line, '\r')) != NULL) { *TempPT = '\0'; } while ((TempPT = strchr(Line, '\n')) != NULL) { *TempPT = '\0'; } if ((Line[0] == '#') || (Line[0] == ';') || (Line[0] == '\0')) { continue; } TempPT = strtok(Line, ":"); if (TempPT == NULL) { continue; } if (strcmp(TempPT, UserPT) != FALSE) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } fclose(FilePT); TMPSTRPT = strrealloc(TMPSTRPT, TempPT); return(TMPSTRPT); } fclose(FilePT); return(NULL); } #endif #endif #if !WIN32 /* SYSGETGIDFROMGROUP FUNCTION - JONAS (01.07.2000) */ gid_t sysgetgidfromgroup(const char *const GroupPT) { FILE *FilePT = NULL; char *TempPT = NULL; char Line[LINELEN+1] = ""; gid_t GID = 0; assert(GroupPT != NULL); FilePT = fopen(GROUP_FILE, "r"); if (FilePT == NULL) { sysprint(BITMASK_ERROR, "Unable to open %s: [%d] %s", GROUP_FILE, errno, strerror(errno)); aerrno = AENORESOURCE; return(0); } FOREVERLOOP { TempPT = fgets(Line, LINELEN, FilePT); if (TempPT == NULL) { break; } while ((TempPT = strchr(Line, '\r')) != NULL) { *TempPT = '\0'; } while ((TempPT = strchr(Line, '\n')) != NULL) { *TempPT = '\0'; } if ((Line[0] == '#') || (Line[0] == ';') || (Line[0] == '\0')) { continue; } TempPT = strtok(Line, ":"); if (TempPT == NULL) { continue; } if (strcmp(TempPT, GroupPT) != FALSE) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } TempPT = strtok(NULL, ":"); if (TempPT == NULL) { continue; } GID = strtoul(TempPT, NULL, 0); fclose(FilePT); aerrno = AESUCCESS; return(GID); } aerrno = AENOMATCH; fclose(FilePT); return(0); } #endif /* SYSCLEANUP FUNCTION - JONAS (01.07.2000) */ void syscleanup(void) { unsigned short int Index = 0; DEBUGPRINT(BITMASK_DEBUG_SYSCALLS, "Freeing %s allocated memory.", __FILE__); FREE(TMPSTRPT); for (Index = 0 ; Index < PrintFileS_Len ; ++Index) { FREE(PrintFileS[Index].Name); } } /* NL_NET_ATON FUNCTION - JONAS (01.07.2000) */ int nl_net_aton(const char *HostIPS, struct in_addr *InAddr) { signed long int Result = INADDR_NONE; Result = inet_addr(HostIPS); if (Result == INADDR_NONE) { return(0); } InAddr->s_addr = Result; return(1); }