mirror of
https://github.com/NishiOwO/ncsa-httpd.git
synced 2025-04-21 16:54:46 +00:00
299 lines
6.0 KiB
C
299 lines
6.0 KiB
C
/************************************************************************
|
|
* NCSA HTTPd Server
|
|
* Software Development Group
|
|
* National Center for Supercomputing Applications
|
|
* University of Illinois at Urbana-Champaign
|
|
* 605 E. Springfield, Champaign, IL 61820
|
|
* httpd@ncsa.uiuc.edu
|
|
*
|
|
* Copyright (C) 1995, Board of Trustees of the University of Illinois
|
|
*
|
|
************************************************************************
|
|
*
|
|
* fdwrap.c,v 1.11 1995/11/28 09:01:44 blong Exp
|
|
*
|
|
************************************************************************
|
|
*
|
|
* fdwrap.c used to wrap file descriptors so that we can keep track
|
|
* of open ones and close them when errors happen. Should
|
|
* make leaks next to impossible.
|
|
*
|
|
* 08-15-95 guillory
|
|
* initial code
|
|
*
|
|
* 08-16-95 blong
|
|
* added headers, etc.
|
|
*
|
|
* 09-07-97 mshapiro
|
|
* added includes for <malloc.h> / <sys/malloc.h>
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "portability.h"
|
|
|
|
#include <stdio.h>
|
|
#ifndef NO_STDLIB_H
|
|
# include <stdlib.h>
|
|
#endif /* NO_STDLIB_H */
|
|
#ifdef DBM_SUPPORT
|
|
# ifndef _DBMSUPPORT_H /* moronic OSs which don't protect their own include */
|
|
# define _DBMSUPPORT_H /* files from being multiply included */
|
|
# include <ndbm.h>
|
|
# endif /* _DBMSUPPORT_H */
|
|
#endif /* DBM_SUPPORT */
|
|
#ifndef NO_MALLOC_H
|
|
# ifdef NEED_SYS_MALLOC_H
|
|
# include <sys/malloc.h>
|
|
# else
|
|
# include <malloc.h>
|
|
# endif /* NEED_SYS_MALLOC_H */
|
|
#endif /* NO_MALLOC_H */
|
|
|
|
#include "constants.h"
|
|
#include "fdwrap.h"
|
|
#include "host_config.h"
|
|
#include "http_log.h"
|
|
|
|
static FDTABLE* FdTab;
|
|
static int nSize;
|
|
|
|
void fd_error(char *err_msg)
|
|
{
|
|
char S[MAX_STRING_LEN];
|
|
sprintf(S,"fdwrap error: %s\n",err_msg);
|
|
log_error(S,gConfiguration->error_log);
|
|
exit(1);
|
|
}
|
|
|
|
void fd_warn(char *err_msg)
|
|
{
|
|
char S[MAX_STRING_LEN];
|
|
sprintf(S,"fdwrap warn: %s\n",err_msg);
|
|
log_error(S,gConfiguration->error_log);
|
|
}
|
|
|
|
/* Can't call fd_error in Init since error_log isn't opened yet. */
|
|
void InitFdTable (void)
|
|
{
|
|
int ndx;
|
|
|
|
/* take care of failure here */
|
|
FdTab = (FDTABLE*) malloc (INITIAL_TABSIZE * sizeof(FDTABLE));
|
|
if (!FdTab) {
|
|
fprintf(stderr,
|
|
"HTTPd: Could not allocate memory for file descriptor tracking\n");
|
|
perror("malloc");
|
|
exit(1);
|
|
}
|
|
nSize = INITIAL_TABSIZE;
|
|
|
|
for (ndx = 0; ndx < INITIAL_TABSIZE; ndx++) {
|
|
FdTab[ndx].bOpen = FDW_CLOSED;
|
|
FdTab[ndx].fp = NULL;
|
|
}
|
|
}
|
|
|
|
int GrowTable (int fd)
|
|
{
|
|
int ndx;
|
|
|
|
/* take care of failure here */
|
|
FdTab = (FDTABLE*) realloc ((char*)FdTab,
|
|
((fd + 10) * sizeof(FDTABLE)));
|
|
if (!FdTab) {
|
|
fd_warn("GrowTable Failed");
|
|
return 0;
|
|
}
|
|
|
|
for (ndx = nSize; ndx < fd + 10; ndx++) {
|
|
FdTab[ndx].bOpen = FDW_CLOSED;
|
|
FdTab[ndx].fp = NULL;
|
|
}
|
|
nSize = fd + 10;
|
|
return 1;
|
|
}
|
|
|
|
FILE* FOpen (char* fname, char* mode)
|
|
{
|
|
FILE* fp;
|
|
int fd;
|
|
|
|
if ((fp = fopen (fname, mode))) {
|
|
fd = fileno(fp);
|
|
if (fd >= nSize)
|
|
if (!GrowTable(fd)) {
|
|
fclose(fp);
|
|
return NULL;
|
|
}
|
|
|
|
FdTab[fd].bOpen = FDW_FILE_PTR;
|
|
FdTab[fd].fp = fp;
|
|
return fp;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
DIR* Opendir(char* dirname)
|
|
{
|
|
DIR* dp;
|
|
int fd;
|
|
if ((dp = opendir(dirname))) {
|
|
fd = DIR_FILENO(dp);
|
|
if (fd >= nSize)
|
|
if (!GrowTable(fd)) {
|
|
closedir(dp);
|
|
return NULL;
|
|
}
|
|
FdTab[fd].bOpen = FDW_DIR_PTR;
|
|
FdTab[fd].fp = dp;
|
|
return dp;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
int Pipe (int* pd)
|
|
{
|
|
if (pipe(pd) < 0)
|
|
return -1;
|
|
|
|
if (pd[0] >= nSize || pd[1] >= nSize)
|
|
if (!GrowTable(pd[0] > pd[1] ? pd[0] : pd[1])) {
|
|
close(pd[0]);
|
|
close(pd[1]);
|
|
return -1;
|
|
}
|
|
FdTab[pd[0]].bOpen = FDW_FILE_DESC;
|
|
FdTab[pd[0]].fp = NULL;
|
|
FdTab[pd[1]].bOpen = FDW_FILE_DESC;
|
|
FdTab[pd[1]].fp = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
FILE* FdOpen(int fd, char* mode)
|
|
{
|
|
FILE* fp;
|
|
|
|
if ((fp = fdopen(fd, mode))) {
|
|
FdTab[fd].bOpen = FDW_FILE_PTR;
|
|
FdTab[fd].fp = fp;
|
|
return fp;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
|
|
#ifdef DBM_SUPPORT
|
|
DBM* DBM_Open (char *dbm_name, int flags, int mode)
|
|
{
|
|
DBM* dp;
|
|
int fd;
|
|
|
|
if ((dp = dbm_open (dbm_name, flags, mode))) {
|
|
fd = dbm_dirfno(dp); /* Hope this is portable across implementations */
|
|
if (fd >= nSize)
|
|
if (!GrowTable(fd)) {
|
|
dbm_close(dp);
|
|
return NULL;
|
|
}
|
|
FdTab[fd].bOpen = FDW_DBM_PTR;
|
|
FdTab[fd].fp = dp;
|
|
return dp;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
#endif /* DBM_SUPPORT */
|
|
|
|
int FClose (FILE* fp)
|
|
{
|
|
int fd;
|
|
|
|
if (fp != NULL) {
|
|
fd = fileno(fp);
|
|
|
|
FdTab[fd].bOpen = FDW_CLOSED;
|
|
if (FdTab[fd].fp != fp) {
|
|
fd_warn("Mismatched File Pointer (FILE), closing both");
|
|
if (FdTab[fd].fp != NULL) fclose(FdTab[fd].fp);
|
|
}
|
|
FdTab[fd].fp = NULL;
|
|
return fclose(fp);
|
|
} else return -1;
|
|
}
|
|
|
|
int Closedir (DIR *dp)
|
|
{
|
|
int fd = DIR_FILENO(dp);
|
|
|
|
FdTab[fd].bOpen = FDW_CLOSED;
|
|
if (FdTab[fd].fp != dp) {
|
|
fd_warn("Mismatched File Pointer (FILE), closing both");
|
|
fclose(FdTab[fd].fp);
|
|
}
|
|
FdTab[fd].fp = NULL;
|
|
#ifndef APOLLO
|
|
return closedir(dp);
|
|
#else
|
|
closedir(dp);
|
|
return;
|
|
#endif /* APOLLO */
|
|
}
|
|
|
|
|
|
#ifdef DBM_SUPPORT
|
|
void DBM_Close (DBM *db)
|
|
{
|
|
int fd = dbm_dirfno(db);
|
|
|
|
FdTab[fd].bOpen = FDW_CLOSED;
|
|
if (FdTab[fd].fp != db) {
|
|
fd_warn("Mismatched File Pointer (DBM), closing both");
|
|
if (FdTab[fd].fp != NULL) dbm_close(FdTab[fd].fp);
|
|
}
|
|
FdTab[fd].fp = NULL;
|
|
if (db != NULL) dbm_close(db);
|
|
}
|
|
#endif /* DBM_SUPPORT */
|
|
|
|
int Close(int fd)
|
|
{
|
|
FdTab[fd].bOpen = FDW_CLOSED;
|
|
return close(fd);
|
|
}
|
|
|
|
int CloseAll(void)
|
|
{
|
|
int ndx;
|
|
int nAny = 0;
|
|
|
|
for (ndx = 0; ndx < nSize; ndx++) {
|
|
if (FdTab[ndx].bOpen) {
|
|
nAny = 1;
|
|
switch (FdTab[ndx].bOpen) {
|
|
case FDW_FILE_DESC: close(ndx);
|
|
break;
|
|
case FDW_FILE_PTR: fclose(FdTab[ndx].fp);
|
|
break;
|
|
case FDW_DIR_PTR: closedir(FdTab[ndx].fp);
|
|
break;
|
|
#ifdef DBM_SUPPORT
|
|
case FDW_DBM_PTR: dbm_close(FdTab[ndx].fp);
|
|
break;
|
|
#endif /* DBM_SUPPORT */
|
|
}
|
|
FdTab[ndx].bOpen = FDW_CLOSED;
|
|
FdTab[ndx].fp = NULL;
|
|
}
|
|
}
|
|
return nAny;
|
|
}
|
|
|
|
void DestroyFdTab(void)
|
|
{
|
|
free (FdTab);
|
|
}
|