From: Nathan Bryant Date: Wed, 7 Oct 1998 23:46:11 +0000 (+0000) Subject: * snprintf.c, snprintf.h: new files X-Git-Tag: v7.86~8297 X-Git-Url: https://code.citadel.org/?a=commitdiff_plain;h=1fa6e9def6d5eb1e85a4a24af9d49a5b82951d22;p=citadel.git * snprintf.c, snprintf.h: new files * Makefile.in, configure.in, dynloader.c, sysdep.c: support for the above; citserver now builds and runs on Digital Unix 4.0d with the GNU-style configure script. there is a bug with the hostname display in the wholist. * netproc.c: sillyness fix * room_ops.h: prototype delete_room() --- diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 63eb1f3e2..36cde8e48 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,3 +1,12 @@ +1998-10-07 Nathan Bryant + * snprintf.c, snprintf.h: new files + * Makefile.in, configure.in, dynloader.c, sysdep.c: support for the + above; citserver now builds and runs on Digital Unix 4.0d with the + GNU-style configure script. there is a bug with the hostname display + in the wholist. + * netproc.c: sillyness fix + * room_ops.h: prototype delete_room() + Mon Oct 5 17:01:32 EDT 1998 Art Cancro * Began fixing the stuff I broke diff --git a/citadel/Makefile.in b/citadel/Makefile.in index 0ffce1b9c..7a9b1545c 100644 --- a/citadel/Makefile.in +++ b/citadel/Makefile.in @@ -28,6 +28,7 @@ LIBS=@LIBS@ LDFLAGS=@LDFLAGS@ SERVER_LDFLAGS=@SERVER_LDFLAGS@ CURSES=@CURSES@ +SNPRINTF=@SNPRINTF@ PTHREAD_DEFS=-D_REENTRANT client: $(CLIENT_TARGETS) @@ -86,17 +87,20 @@ serv_info.o: serv_info.c citserver: citserver.o user_ops.o support.o room_ops.o file_ops.o \ msgbase.o config.o sysdep.o locate_host.o \ housekeeping.o database.o control.o logging.o \ - dynloader.o + dynloader.o $(SNPRINTF) $(CC) \ citserver.o user_ops.o room_ops.o file_ops.o support.o \ msgbase.o config.o sysdep.o locate_host.o \ housekeeping.o database.o control.o logging.o \ - dynloader.o \ + dynloader.o $(SNPRINTF)\ $(LDFLAGS) $(SERVER_LDFLAGS) $(LIBS) -o citserver citserver.o: citserver.c $(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) $(PTHREAD_DEFS) -c citserver.c +snprintf.o: snprintf.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) $(PTHREAD_DEFS) -c snprintf.c + user_ops.o: user_ops.c $(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) $(PTHREAD_DEFS) -c user_ops.c diff --git a/citadel/configure.in b/citadel/configure.in index 90613572f..813325cd6 100644 --- a/citadel/configure.in +++ b/citadel/configure.in @@ -68,10 +68,15 @@ AC_FUNC_GETPGRP AC_PROG_GCC_TRADITIONAL AC_TYPE_SIGNAL AC_FUNC_VPRINTF -AC_CHECK_FUNCS(mkdir mktime rmdir select socket strerror) +AC_CHECK_FUNCS(snprintf mkdir mktime rmdir select socket strerror) + +if test "$ac_cv_func_snprintf" = no; then + SNPRINTF=snprintf.o +fi AC_SUBST(CURSES) AC_SUBST(TARGETS) AC_SUBST(SERVER_LDFLAGS) +AC_SUBST(SNPRINTF) AC_CONFIG_HEADER(sysdep.h) AC_OUTPUT(Makefile) diff --git a/citadel/dynloader.c b/citadel/dynloader.c index c8ed926d4..0f492be0b 100644 --- a/citadel/dynloader.c +++ b/citadel/dynloader.c @@ -21,6 +21,11 @@ #include "server.h" #include "sysdep_decls.h" +#ifndef HAVE_SNPRINTF +#include +#include "snprintf.h" +#endif + struct CleanupFunctionHook *CleanupHookTable = NULL; struct SessionFunctionHook *SessionHookTable = NULL; struct UserFunctionHook *UserHookTable = NULL; diff --git a/citadel/netproc.c b/citadel/netproc.c index a665961e5..83dd9c72c 100644 --- a/citadel/netproc.c +++ b/citadel/netproc.c @@ -1217,7 +1217,7 @@ int main(int argc, char **argv) /* * Change directories if specified */ - if (argv > 0) for (a=1; a + */ + +/* + * Replacements for snprintf() and vsnprintf() + * + * Use it only if you have the "spare" cycles needed to effectively + * do every snprintf operation twice! Why is that? Because everything + * is first vfprintf()'d to /dev/null to determine the number of bytes. + * Perhaps a bit slow for demanding applications on slow machines, + * no problem for a fast machine with some spare cycles. + * + * You don't have a /dev/null? Every Linux contains one for free! + * + * Because the format string is never even looked at, all current and + * possible future printf-conversions should be handled just fine. + * + * Written July 1997 by Sten Gunterberg (gunterberg@ergon.ch) + */ + +#include +#include +#include +#include + +static int +needed (const char *fmt, va_list argp) +{ + static FILE *sink = NULL; + + /* ok, there's a small race here that could result in the sink being + * opened more than once if we're threaded, but I'd rather ignore it than + * spend cycles synchronizing :-) */ + + if (sink == NULL) + { + if ((sink = fopen("/dev/null", "w")) == NULL) + { + perror("/dev/null"); + exit(1); + } + } + + return vfprintf(sink, fmt, argp); +} + +int +snprintf (char *buf, size_t max, const char *fmt, ...) +{ + va_list argp; + int bytes; + + va_start(argp, fmt); + bytes = vsnprintf(buf, max, fmt, argp); + va_end(argp); + + return bytes; +} + +int +vsnprintf (char *buf, size_t max, const char *fmt, va_list argp) +{ + char *p; + int size; + + if ((p = malloc(needed(fmt, argp) + 1)) == NULL) + { + fprintf(stderr, "vsnprintf: malloc failed, aborting\n"); + abort(); + } + + if ((size = vsprintf(p, fmt, argp)) >= max) + size = -1; + + strncpy(buf, p, max); + buf[max - 1] = 0; + free(p); + return size; +} diff --git a/citadel/snprintf.h b/citadel/snprintf.h new file mode 100644 index 000000000..29fee8562 --- /dev/null +++ b/citadel/snprintf.h @@ -0,0 +1,2 @@ +int snprintf (char *buf, size_t max, const char *fmt, ...); +int vsnprintf (char *buf, size_t max, const char *fmt, va_list argp); diff --git a/citadel/sysdep.c b/citadel/sysdep.c index 9f5adf9bf..8b8ad314b 100644 --- a/citadel/sysdep.c +++ b/citadel/sysdep.c @@ -44,6 +44,10 @@ #include #endif +#ifndef HAVE_SNPRINTF +#include "snprintf.h" +#endif + pthread_mutex_t Critters[MAX_SEMAPHORES]; /* Things needing locking */ pthread_key_t MyConKey; /* TSD key for MyContext() */