Obsolete option --no-sig-create-check.
[gnupg.git] / util / compat.c
1 /* compat.c - Simple compatibility functions
2  * Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
3  *
4  * The origin of this code is GnuPG.
5  *
6  * This file is free software; as a special exception the author gives
7  * unlimited permission to copy and/or distribute it, with or without
8  * modifications, as long as this notice is preserved.
9  *
10  * This file is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
12  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * History:
15  * 2006-09-28 dshaw  Created.  Added function hextobyte from GnuPG.
16  * 2007-04-16 dshaw  Added ascii_toupper, ascii_tolower, ascii_strcasecmp,
17  *                   ascii_strncasecmp from GnuPG.
18  * 2009-08-25 wk     License changed by GnuPG maintainer from GPL with 
19  *                   OpenSSL exception to this all permissive license.
20  * 2009-08-25 wk     Wrote new function xstrconcat.
21  */
22
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <errno.h>
28 #include <sys/types.h>
29
30 /* We require an external malloc function named xtrymalloc.  */
31 void *xtrymalloc (size_t n);
32
33
34 #ifndef DIM
35 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
36 #endif
37
38
39
40 int
41 hextobyte (const char *s)
42 {
43   int c;
44
45   if ( *s >= '0' && *s <= '9' )
46     c = 16 * (*s - '0');
47   else if ( *s >= 'A' && *s <= 'F' )
48     c = 16 * (10 + *s - 'A');
49   else if ( *s >= 'a' && *s <= 'f' )
50     c = 16 * (10 + *s - 'a');
51   else
52     return -1;
53   s++;
54   if ( *s >= '0' && *s <= '9' )
55     c += *s - '0';
56   else if ( *s >= 'A' && *s <= 'F' )
57     c += 10 + *s - 'A';
58   else if ( *s >= 'a' && *s <= 'f' )
59     c += 10 + *s - 'a';
60   else
61     return -1;
62   return c;
63 }
64
65 int 
66 ascii_toupper (int c)
67 {
68     if (c >= 'a' && c <= 'z')
69         c &= ~0x20;
70     return c;
71 }
72
73 int 
74 ascii_tolower (int c)
75 {
76     if (c >= 'A' && c <= 'Z')
77         c |= 0x20;
78     return c;
79 }
80
81 int
82 ascii_strcasecmp (const char *a, const char *b)
83 {
84   const unsigned char *p1 = (const unsigned char *)a;
85   const unsigned char *p2 = (const unsigned char *)b;
86   unsigned char c1, c2;
87
88   if (p1 == p2)
89     return 0;
90
91   do
92     {
93       c1 = ascii_tolower (*p1);
94       c2 = ascii_tolower (*p2);
95
96       if (c1 == '\0')
97         break;
98
99       ++p1;
100       ++p2;
101     }
102   while (c1 == c2);
103   
104   return c1 - c2;
105 }
106
107 int 
108 ascii_strncasecmp (const char *a, const char *b, size_t n)
109 {
110   const unsigned char *p1 = (const unsigned char *)a;
111   const unsigned char *p2 = (const unsigned char *)b;
112   unsigned char c1, c2;
113
114   if (p1 == p2 || !n )
115     return 0;
116
117   do
118     {
119       c1 = ascii_tolower (*p1);
120       c2 = ascii_tolower (*p2);
121
122       if ( !--n || c1 == '\0')
123         break;
124
125       ++p1;
126       ++p2;
127     }
128   while (c1 == c2);
129   
130   return c1 - c2;
131 }
132
133
134 static char *
135 do_strconcat (const char *s1, va_list arg_ptr)
136 {
137   const char *argv[48];
138   size_t argc;
139   size_t needed;
140   char *buffer, *p;
141   const char *r;
142
143   argc = 0;
144   argv[argc++] = s1;
145   needed = strlen (s1);
146   while (((argv[argc] = va_arg (arg_ptr, const char *))))
147     {
148       needed += strlen (argv[argc]);
149       if (argc >= DIM (argv)-1)
150         {
151           errno = EINVAL;
152           return NULL;
153         }
154       argc++;
155     }
156   needed++;
157   buffer = xtrymalloc (needed);
158   if (buffer)
159     {
160       for (p = buffer, argc=0; argv[argc]; argc++)
161         {
162           for (r = argv[argc]; *r; )
163             *p++ = *r++;
164           *p = 0;
165         }
166     }
167   return buffer;
168 }
169
170
171 /* Concatenate the string S1 with all the following strings up to a
172    NULL.  Returns a malloced buffer.  */
173 char *
174 xstrconcat (const char *s1, ...)
175 {
176   va_list arg_ptr;
177   char *result;
178
179   if (!s1)
180     {
181       result = xtrymalloc (1);
182       if (result)
183         *result = 0;
184     }
185   else
186     {
187       va_start (arg_ptr, s1);
188       result = do_strconcat (s1, arg_ptr);
189       va_end (arg_ptr);
190     }
191   if (!result)
192     {
193       if (errno == EINVAL)
194         fputs ("\nfatal: too many args for xstrconcat\n", stderr);
195       else
196         fputs ("\nfatal: out of memory\n", stderr);
197       exit (2);
198     }
199   return result;
200 }
201