/*
* ----------------------------------------------------------------
* Night Light File Descriptor Debugging Functions
* ----------------------------------------------------------------
* Copyright (C) 2003-2007 Jonas Kvinge <jonas@night-light.net>
* 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);
}
}
syntax highlighted by Code2HTML, v. 0.9.1