aboutsummaryrefslogtreecommitdiff
path: root/vendor/voclient/libsamp/sampLog.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/voclient/libsamp/sampLog.c')
-rw-r--r--vendor/voclient/libsamp/sampLog.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/vendor/voclient/libsamp/sampLog.c b/vendor/voclient/libsamp/sampLog.c
new file mode 100644
index 00000000..851c85e1
--- /dev/null
+++ b/vendor/voclient/libsamp/sampLog.c
@@ -0,0 +1,270 @@
+/**
+ * SAMPLOG.C -- SAMP trace and logging interface.
+ *
+ * @file sampLog.c
+ * @author Mike Fitzpatrick
+ * @date 6/10/09
+ *
+ * @brief SAMP trace and logging interface.
+ *
+ */
+/*****************************************************************************/
+
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "samp.h"
+
+
+#define SZ_FMTSPEC 25 /* max size single format spec */
+#define EOS 0
+
+#define T_INT 0 /* the only types we support */
+#define T_DOUBLE 1
+#define T_CHAR 2
+
+
+
+/* Private methods.
+*/
+static void samp_encodeString (char *buf, char *format, va_list *argp);
+static char *samp_doarg (va_list **argp, int dtype);
+static char *logtime ();
+
+
+
+/**
+ * SAMPLOG -- SAMP message logger.
+ *
+ * @brief SAMP message logger.
+ * @fn sampLog (handle_t handle, char *format, ...)
+ *
+ * @param handle SAMP handle
+ * @param format message format string
+ * @return nothing
+ */
+void
+sampLog (handle_t handle, char *format, ...)
+{
+ Samp *sampP = samp_H2P (handle); /* get struct pointer */
+ char *buf;
+ int len;
+ va_list argp;
+
+
+ va_start (argp, format); /* encode as a single string */
+ buf = calloc (1, (4 * SZ_LINE) );
+ (void) samp_encodeString (buf, format, &argp);
+ va_end (argp);
+
+ len = strlen (buf); /* ensure a newline */
+ if (strcmp ("\n", &buf[len-1]))
+ strcat (buf, "\n");
+
+ if (sampP->logfd)
+ fprintf (sampP->logfd, "[%s] %s", logtime(), buf);
+
+ if (sampP->debug)
+ fprintf (stderr, "[%s] %s", logtime(), buf);
+
+ if (buf) free ((void *) buf);
+}
+
+
+/**
+ * SAMPTRACE -- SAMP tracer.
+ *
+ * @brief SAMP tracer.
+ * @fn sampTrace (handle_t handle, char *format, ...)
+ *
+ * @param handle SAMP handle
+ * @param format message format string
+ * @return nothing
+ */
+void
+sampTrace (handle_t handle, char *format, ...)
+{
+ Samp *sampP = samp_H2P (handle); /* get struct pointer */
+ char *buf;
+ int len;
+ va_list argp;
+
+
+ if (!sampP->trace)
+ return;
+
+ va_start (argp, format); /* encode as a single string */
+ buf = calloc (1, (4 * SZ_LINE) );
+ (void) samp_encodeString (buf, format, &argp);
+ va_end (argp);
+
+ len = strlen (buf); /* ensure a newline */
+ if (strcmp ("\n", &buf[len-1]))
+ strcat (buf, "\n");
+
+ fprintf (stderr, "[%s] %s", logtime(), buf);
+
+ if (buf) free ((void *) buf);
+}
+
+
+
+/**************************************************************************
+ * Private Methods
+ *************************************************************************/
+
+/**
+ * SAMP_ENCODESTRING -- Process the format to the output file, taking arguments
+ * from the list pointed to by argp as % format specs are encountered in
+ * the input.
+ *
+ * @fn samp_encodeString (char *buf, char *format, va_list *argp)
+ *
+ * @param buf formatted output buffer
+ * @param format format string
+ * @param argp variable-length arguments
+ * @return
+ */
+static void
+samp_encodeString (char *buf, char *format, va_list *argp)
+{
+ register int ch; /* next format char reference */
+ char formspec[SZ_FMTSPEC]; /* copy of single format spec */
+ char *fsp; /* pointer into formspec */
+ char cbuf[10];
+ int done; /* one when at end of a format */
+ int nch = SZ_LINE; /* one when at end of a format */
+
+
+ while ((ch = *format++) && nch > 0) {
+ if (ch == '%') {
+ fsp = formspec;
+ *fsp++ = ch;
+ done = 0;
+
+ while (!done) {
+ ch = *fsp++ = *format++;
+
+ switch (ch) {
+ case EOS:
+ --format;
+ done++;
+ break;
+
+ case 'l':
+ fsp--; /* arg size modifier; ignored for now */
+ break;
+
+ case 'b': /* nonstandard UNIX */
+ case 'c':
+ case 'd':
+ case 'o':
+ case 'x':
+ case 'u':
+ *fsp = EOS;
+ strcat (buf, samp_doarg (&argp, T_INT));
+ done++;
+ break;
+
+ case 'E': /* ANSI emulation */
+ *(fsp-1) = 'e';
+ goto rval;
+ case 'G': /* ANSI emulation */
+ *(fsp-1) = 'g';
+ goto rval;
+
+ case 'e':
+ case 'f':
+ case 'g':
+rval:
+ *fsp = EOS;
+ strcat (buf, samp_doarg (&argp, T_DOUBLE));
+ done++;
+ break;
+
+ case 's':
+ *fsp = EOS;
+ strcat (buf, samp_doarg (&argp, T_CHAR));
+ done++;
+ break;
+ }
+ }
+
+ } else {
+ memset (cbuf, 0, 10);
+ sprintf (cbuf, "%c", ch);
+ strcat (buf, cbuf);
+ }
+
+ nch = SZ_LINE - strlen (buf); /* prevent overflow */
+ }
+}
+
+
+/**
+ * SAMP_DOARG -- Encode a single argument acording to the data type.
+ *
+ * @fn static char *samp_doarg (va_list **argp, int dtype)
+ *
+ * @param argp argument list
+ * @param dtype data type
+ *
+ */
+static char *
+samp_doarg (va_list **argp, int dtype)
+{
+ int ival;
+ double dval;
+ char *cptr;
+ static char val[128];
+
+
+ /* Pass the data value to be encoded, bump argument pointer by the
+ ** size of the data object. If there is no data value the case
+ ** is a no-op.
+ */
+ memset (val, 0, 128);
+
+ switch (dtype) {
+ case T_INT:
+ ival = va_arg ((**argp), int);
+ sprintf (val, "%d", ival);
+ break;
+ case T_DOUBLE:
+ dval = va_arg ((**argp), double);
+ sprintf (val, "%g", dval);
+ break;
+ case T_CHAR:
+ cptr = va_arg ((**argp), char *);
+ sprintf (val, "%s", cptr);
+ break;
+ }
+
+ return (val);
+}
+
+
+
+/**
+ * LOGTIME - Generate a time string for the log.
+ *
+ * @fn static char *logtime()
+ */
+static char *
+logtime ()
+{
+ time_t t = time (NULL);
+ struct tm *tm = gmtime (&t);
+ static char tstr[128];
+
+ memset (tstr, 0, 128);
+ strftime (tstr, 128, "%m%d %T", tm);
+
+ return (tstr);
+}