00001 #include "efence.h"
00002 #include <stdlib.h>
00003 #include <unistd.h>
00004 #include <stdarg.h>
00005 #include <string.h>
00006 #include <signal.h>
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define NUMBER_BUFFER_SIZE (sizeof(ef_number) * NBBY)
00019
00020 static void
00021 printNumber(ef_number number, ef_number base)
00022 {
00023 char buffer[NUMBER_BUFFER_SIZE];
00024 char * s = &buffer[NUMBER_BUFFER_SIZE];
00025 int size;
00026
00027 do {
00028 ef_number digit;
00029
00030 if ( --s == buffer )
00031 EF_Abort("Internal error printing number.");
00032
00033 digit = number % base;
00034
00035 if ( digit < 10 )
00036 *s = '0' + digit;
00037 else
00038 *s = 'a' + digit - 10;
00039
00040 } while ( (number /= base) > 0 );
00041
00042 size = &buffer[NUMBER_BUFFER_SIZE] - s;
00043
00044 if ( size > 0 )
00045 write(2, s, size);
00046 }
00047
00048 static void
00049 vprint(const char * pattern, va_list args)
00050 {
00051 static const char bad_pattern[] =
00052 "\nBad pattern specifier %%%c in EF_Print().\n";
00053 const char * s = pattern;
00054 char c;
00055
00056 while ( (c = *s++) != '\0' ) {
00057 if ( c == '%' ) {
00058 c = *s++;
00059 switch ( c ) {
00060 case '%':
00061 (void) write(2, &c, 1);
00062 break;
00063 case 'a':
00064
00065
00066
00067
00068
00069
00070 printNumber(
00071 (ef_number)va_arg(args, void *)
00072 ,0x10);
00073 break;
00074 case 's':
00075 {
00076 const char * string;
00077 size_t length;
00078
00079 string = va_arg(args, char *);
00080 length = strlen(string);
00081
00082 (void) write(2, string, length);
00083 }
00084 break;
00085 case 'd':
00086 {
00087 int n = va_arg(args, int);
00088
00089 if ( n < 0 ) {
00090 char c = '-';
00091 write(2, &c, 1);
00092 n = -n;
00093 }
00094 printNumber(n, 10);
00095 }
00096 break;
00097 case 'x':
00098 printNumber(va_arg(args, u_int), 0x10);
00099 break;
00100 case 'c':
00101 {
00102 char c = va_arg(args, int);
00103
00104 (void) write(2, &c, 1);
00105 }
00106 break;
00107 default:
00108 {
00109 EF_Print(bad_pattern, c);
00110 }
00111
00112 }
00113 }
00114 else
00115 (void) write(2, &c, 1);
00116 }
00117 }
00118
00119 void
00120 EF_Abort(const char * pattern, ...)
00121 {
00122 va_list args;
00123
00124 va_start(args, pattern);
00125
00126 EF_Print("\nElectricFence Aborting: ");
00127 vprint(pattern, args);
00128 EF_Print("\n");
00129
00130 va_end(args);
00131
00132
00133
00134
00135
00136
00137 kill(getpid(), SIGILL);
00138
00139 _exit(-1);
00140 }
00141
00142 void
00143 EF_Exit(const char * pattern, ...)
00144 {
00145 va_list args;
00146
00147 va_start(args, pattern);
00148
00149 EF_Print("\nElectricFence Exiting: ");
00150 vprint(pattern, args);
00151 EF_Print("\n");
00152
00153 va_end(args);
00154
00155
00156
00157
00158
00159 _exit(-1);
00160 }
00161
00162 void
00163 EF_Print(const char * pattern, ...)
00164 {
00165 va_list args;
00166
00167 va_start(args, pattern);
00168 vprint(pattern, args);
00169 va_end(args);
00170 }