/* * ---------------------------------------------------------------- * Night Light File Descriptor Debugging Functions * ---------------------------------------------------------------- * Copyright (C) 2003-2007 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 (02.07.2003) * */ #define FDCALLS_C #define NEED_SYS_TYPES_H 1 /* Extra types */ #define NEED_SYS_PARAM_H 1 /* Some systems need this */ #define NEED_LIMITS_H 0 /* 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 0 /* in_addr, sockaddr_in, etc */ #define NEED_ARPA_INET_H 0 /* 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 0 /* 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 0 /* ioctl(), etc */ #define NEED_SYS_FILIO_H 0 /* 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 0 /* 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 0 /* Functions to retrive system passwords */ #include "includes.h" #if !FDDEBUG #error "fdcalls.h included, but FDDEBUG not defined TRUE." #endif #ifdef SOCKET_REDEFINE #error "Sanity check: socket() can't be redefined in here!" #endif /* VARIABLES - JONAS (01.07.2003) */ struct FDTable_Struct *FDTable_Head = NULL; struct FDTable_Struct *FDTable_Tail = NULL; struct SockTable_Struct *SockTable_Head = NULL; struct SockTable_Struct *SockTable_Tail = NULL; unsigned long int G_FDs = 0; unsigned long int G_Sockets = 0; /* FDTABLE_ADD - JONAS (01.07.2003) */ void fdtable_add(FILE *FD, const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, const char *const PathPT, const char *const ModePT) { struct FDTable_Struct *FDTableS = NULL; struct FDTable_Struct *FDTableS_NEW = NULL; assert(FD != NULL); assert(FilePT != NULL); assert(FunctionPT != NULL); assert(PathPT != NULL); assert(ModePT != NULL); FDTableS_NEW = malloc(sizeof(struct FDTable_Struct)); if (FDTableS_NEW == NULL) { return; } memset(FDTableS_NEW, 0, sizeof(struct FDTable_Struct)); FDTableS_NEW->FD = FD; FDTableS_NEW->File = (const char *const) FilePT; FDTableS_NEW->Line = (const unsigned short int) Line; FDTableS_NEW->Function = (const char *const) FunctionPT; FDTableS_NEW->Time = NOW; if (FDTable_Head == NULL) { FDTable_Head = FDTableS_NEW; FDTable_Tail = FDTableS_NEW; } else { FDTableS = FDTable_Tail; FDTableS->Next = FDTableS_NEW; FDTableS_NEW->Prev = FDTableS; FDTable_Tail = FDTableS_NEW; } G_FDs++; DEBUGPRINT(BITMASK_DEBUG_FD, "FD DEBUG: Function: %s() - FD: %p - File: %s - Line: %d - Function: %s - Path: %s - Mode: %s", __FUNCTION__, FD, FilePT, Line, FunctionPT, PathPT, ModePT); } /* FDTABLE_REM - JONAS (01.07.2003) */ void fdtable_rem(struct FDTable_Struct *FDTableS) { assert(FDTableS != NULL); if (FDTableS->Prev == NULL) { FDTable_Head = FDTableS->Next; } else { FDTableS->Prev->Next = FDTableS->Next; } if (FDTableS->Next == NULL) { FDTable_Tail = FDTableS->Prev; } else { FDTableS->Next->Prev = FDTableS->Prev; } G_FDs--; DEBUGPRINT(BITMASK_DEBUG_FD, "FD DEBUG: Function: %s() - FD: %p - File: %s - Line: %d - Function: %s", __FUNCTION__, FDTableS->FD, FDTableS->File, FDTableS->Line, FDTableS->Function); free(FDTableS); } /* FDTABLE_GET - JONAS (01.07.2003) */ struct FDTable_Struct *fdtable_get(const FILE *const FD) { struct FDTable_Struct *FDTable = NULL; for (FDTable = FDTable_Head ; FDTable != NULL ; FDTable = FDTable->Next) { if (FDTable->FD == FD) { return(FDTable); } } return(NULL); } /* FDTABLE_CLEAR - JONAS (01.07.2003) */ void fdtable_clear(void) { while (FDTable_Head != NULL) { fdtable_rem(FDTable_Head); } } /* OPENFD - JONAS (01.07.2003) */ FILE *openfd(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, const char *const PathPT, const char *const ModePT) { FILE *FD = NULL; DEBUGPRINT(BITMASK_DEBUG_FD, "FD DEBUG: Function: %s() - File: %s - Line: %d - Function: %s - Path: %s - Mode: %s", __FUNCTION__, FilePT, Line, FunctionPT, PathPT, ModePT); FD = fopen(PathPT, ModePT); if (FD != NULL) { fdtable_add(FD, FilePT, Line, FunctionPT, PathPT, ModePT); } return(FD); } /* CLOSEFD - JONAS (01.07.2003) */ signed short int closefd(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, FILE *FD) { struct FDTable_Struct *FDTableS = NULL; signed short int Result = 0; DEBUGPRINT(BITMASK_DEBUG_FD, "FD DEBUG: Function: %s() - File: %s - Line: %d - Function: %s - Pointer: %p", __FUNCTION__, FilePT, Line, FunctionPT, FD); if (FD == NULL) { return(SUCCESS); } FDTableS = fdtable_get(FD); if (FDTableS == NULL) { sysprint(BITMASK_ERROR, "Wild FD %p from function %s (%s:%d) passed to function fclose().", FD, FunctionPT, FilePT, Line); return(ERROR); } Result = fclose(FD); if (Result == SUCCESS) { fdtable_rem(FDTableS); } return(Result); } /* SOCKTABLE_ADD - JONAS (01.07.2003) */ void socktable_add(signed long int Socket, const char *const FilePT, const unsigned short int Line, const char *const FunctionPT) { struct SockTable_Struct *SockTableS = NULL; struct SockTable_Struct *SockTableS_NEW = NULL; assert(FilePT != NULL); assert(FunctionPT != NULL); SockTableS_NEW = malloc(sizeof(struct SockTable_Struct)); if (SockTableS_NEW == NULL) { return; } memset(SockTableS_NEW, 0, sizeof(struct SockTable_Struct)); SockTableS_NEW->Socket = Socket; SockTableS_NEW->File = (const char *const) FilePT; SockTableS_NEW->Line = (const unsigned short int) Line; SockTableS_NEW->Function = (const char *const) FunctionPT; SockTableS_NEW->Time = NOW; if (SockTable_Head == NULL) { SockTable_Head = SockTableS_NEW; SockTable_Tail = SockTableS_NEW; } else { SockTableS = SockTable_Tail; SockTableS->Next = SockTableS_NEW; SockTableS_NEW->Prev = SockTableS; SockTable_Tail = SockTableS_NEW; } G_Sockets++; DEBUGPRINT(BITMASK_DEBUG_FD, "SOCKET DEBUG: Function: %s() - Socket: %ld - File: %s - Line: %d - Function: %s", __FUNCTION__, Socket, FilePT, Line, FunctionPT); } /* SOCKTABLE_REM - JONAS (01.07.2003) */ void socktable_rem(struct SockTable_Struct *SockTableS) { assert(SockTableS != NULL); if (SockTableS->Prev == NULL) { SockTable_Head = SockTableS->Next; } else { SockTableS->Prev->Next = SockTableS->Next; } if (SockTableS->Next == NULL) { SockTable_Tail = SockTableS->Prev; } else { SockTableS->Next->Prev = SockTableS->Prev; } G_Sockets--; DEBUGPRINT(BITMASK_DEBUG_FD, "SOCKET DEBUG: Function: %s() - Socket: %ld - File: %s - Line: %d - Function: %s", __FUNCTION__, SockTableS->Socket, SockTableS->File, SockTableS->Line, SockTableS->Function); free(SockTableS); } /* SOCKTABLE_GET - JONAS (01.07.2003) */ struct SockTable_Struct *socktable_get(signed long int Socket) { struct SockTable_Struct *SockTable = NULL; for (SockTable = SockTable_Head ; SockTable != NULL ; SockTable = SockTable->Next) { if (SockTable->Socket == Socket) { return(SockTable); } } return(NULL); } /* SOCKTABLE_CLEAR - JONAS (01.07.2003) */ void socktable_clear(void) { while (SockTable_Head != NULL) { socktable_rem(SockTable_Head); } } /* OPENSOCK - JONAS (01.07.2003) */ signed short int opensock(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, signed short int Domain, signed short int Type, signed short int Protocol) { signed long int Socket = 0; DEBUGPRINT(BITMASK_DEBUG_FD, "SOCKET DEBUG: Function: %s() - File: %s - Line: %d - Function: %s", __FUNCTION__, FilePT, Line, FunctionPT); Socket = socket(Domain, Type, Protocol); if (Socket > ERROR) { socktable_add(Socket, FilePT, Line, FunctionPT); } return(Socket); } /* ACCEPTSOCK - JONAS (01.07.2003) */ signed short int acceptsock(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, signed short int ListenSocket, struct sockaddr *SockAddr, accept_addrlen_type *SockAddrLen) { signed long int NewSocket = 0; DEBUGPRINT(BITMASK_DEBUG_FD, "SOCKET DEBUG: Function: %s() - File: %s - Line: %d - Function: %s", __FUNCTION__, FilePT, Line, FunctionPT); NewSocket = accept(ListenSocket, SockAddr, SockAddrLen); if (NewSocket > ERROR) { socktable_add(NewSocket, FilePT, Line, FunctionPT); } return(NewSocket); } /* CLOSESOCK - JONAS (01.07.2003) */ signed short int closesock(const char *const FilePT, const unsigned short int Line, const char *const FunctionPT, signed short int Socket) { struct SockTable_Struct *SockTableS = NULL; signed short int Result = 0; DEBUGPRINT(BITMASK_DEBUG_FD, "SOCKET DEBUG: Function: %s() - File: %s - Line: %d - Function: %s - Socket: %d", __FUNCTION__, FilePT, Line, FunctionPT, Socket); SockTableS = socktable_get(Socket); if (SockTableS == NULL) { sysprint(BITMASK_ERROR, "Wild socket %d from function %s (%s:%d) passed to function close().", Socket, FunctionPT, FilePT, Line); return(ERROR); } Result = close(Socket); if (Result == SUCCESS) { socktable_rem(SockTableS); } return(Result); } /* FD_PRINT - JONAS (01.07.2003) */ void fd_print(void) { struct FDTable_Struct *FDTableS = NULL; struct SockTable_Struct *SockTableS = NULL; DEBUGPRINT(BITMASK_DEBUG_FD, "%s()", __FUNCTION__); for (FDTableS = FDTable_Head ; FDTableS != NULL ; FDTableS = FDTableS->Next) { if ((FDTableS->FD == stdin) || (FDTableS->FD == stdout) || (FDTableS->FD == stderr)) { continue; } if ((strcmp(FDTableS->File, "syscalls.c") == FALSE) && (strcmp(FDTableS->Function, "sysopenfiles_fg") == FALSE)) { continue; } if ((strcmp(FDTableS->File, "syscalls.c") == FALSE) && (strcmp(FDTableS->Function, "sysopenfiles_bg") == FALSE)) { continue; } sysprint(BITMASK_ERROR, "Open file descriptor: %p File: %s Line: %d Function: %s", FDTableS->FD, FDTableS->File, FDTableS->Line, FDTableS->Function); } for (SockTableS = SockTable_Head ; SockTableS != NULL ; SockTableS = SockTableS->Next) { if (SockTableS->Socket <= 2) { continue; } sysprint(BITMASK_ERROR, "Open socket: %ld File: %s Line: %d Function: %s", SockTableS->Socket, SockTableS->File, SockTableS->Line, SockTableS->Function); } }