pjsip_add_use_callerid_contact: fixed alembic script
[asterisk/asterisk.git] / menuselect / strcompat.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Compatibility functions for strsep and strtoq missing on Solaris
20  */
21
22 #include "autoconfig.h"
23
24 #include <sys/types.h>
25 #include <ctype.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdarg.h>
30
31 #ifdef HAVE_ALLOCA_H
32 #include <alloca.h>
33 #endif
34
35 #ifndef HAVE_STRSEP
36 char *strsep(char **str, const char *delims)
37 {
38     char *token;
39
40     if (!*str) {
41         /* No more tokens */
42         return NULL;
43     }
44
45     token = *str;
46     while (**str != '\0') {
47         if (strchr(delims, **str)) {
48             **str = '\0';
49             (*str)++;
50             return token;
51         }
52         (*str)++;
53     }
54
55     /* There is no other token */
56     *str = NULL;
57
58     return token;
59 }
60 #endif
61
62 #ifndef HAVE_SETENV
63 int setenv(const char *name, const char *value, int overwrite)
64 {
65         unsigned char *buf;
66         int buflen;
67
68         buflen = strlen(name) + strlen(value) + 2;
69         buf = alloca(buflen);
70
71         if (!overwrite && getenv(name))
72                 return 0;
73
74         snprintf(buf, buflen, "%s=%s", name, value);
75
76         return putenv(buf);
77 }
78 #endif
79
80 #ifndef HAVE_UNSETENV
81 int unsetenv(const char *name)
82 {
83         return setenv(name, "", 0);
84 }
85 #endif
86
87 #ifndef HAVE_STRCASESTR
88 static char *upper(const char *orig, char *buf, int bufsize)
89 {
90         int i = 0;
91
92         while (i < (bufsize - 1) && orig[i]) {
93                 buf[i] = toupper(orig[i]);
94                 i++;
95         }
96
97         buf[i] = '\0';
98
99         return buf;
100 }
101
102 char *strcasestr(const char *haystack, const char *needle)
103 {
104         char *u1, *u2;
105         int u1len = strlen(haystack) + 1, u2len = strlen(needle) + 1;
106
107         u1 = alloca(u1len);
108         u2 = alloca(u2len);
109         if (u1 && u2) {
110                 char *offset;
111                 if (u2len > u1len) {
112                         /* Needle bigger than haystack */
113                         return NULL;
114                 }
115                 offset = strstr(upper(haystack, u1, u1len), upper(needle, u2, u2len));
116                 if (offset) {
117                         /* Return the offset into the original string */
118                         return ((char *)((unsigned long)haystack + (unsigned long)(offset - u1)));
119                 } else {
120                         return NULL;
121                 }
122         } else {
123                 return NULL;
124         }
125 }
126 #endif /* !HAVE_STRCASESTR */
127
128 #ifndef HAVE_STRNLEN
129 size_t strnlen(const char *s, size_t n)
130 {
131         size_t len;
132
133         for (len = 0; len < n; len++)
134                 if (s[len] == '\0')
135                         break;
136
137         return len;
138 }
139 #endif /* !HAVE_STRNLEN */
140
141 #if !defined(HAVE_STRNDUP)
142 char *strndup(const char *s, size_t n)
143 {
144         size_t len = strnlen(s, n);
145         char *new = malloc(len + 1);
146
147         if (!new)
148                 return NULL;
149
150         new[len] = '\0';
151         return memcpy(new, s, len);
152 }
153 #endif /* !defined(HAVE_STRNDUP) */
154
155 #if !defined(HAVE_VASPRINTF)
156 int vasprintf(char **strp, const char *fmt, va_list ap)
157 {
158         int size;
159         va_list ap2;
160         char s;
161
162         *strp = NULL;
163         va_copy(ap2, ap);
164         size = vsnprintf(&s, 1, fmt, ap2);
165         va_end(ap2);
166         *strp = malloc(size + 1);
167         if (!*strp)
168                 return -1;
169         vsnprintf(*strp, size + 1, fmt, ap);
170
171         return size;
172 }
173 #endif /* !defined(HAVE_VASPRINTF) */
174
175 /*
176  * Based on Code from bsd-asprintf from OpenSSH
177  * Copyright (c) 2004 Darren Tucker.
178  *
179  * Based originally on asprintf.c from OpenBSD:
180  * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
181  *
182  * Permission to use, copy, modify, and distribute this software for any
183  * purpose with or without fee is hereby granted, provided that the above
184  * copyright notice and this permission notice appear in all copies.
185  *
186  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
187  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
188  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
189  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
190  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
191  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
192  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
193  */
194 #if !defined(HAVE_ASPRINTF)
195 int asprintf(char **str, const char *fmt, ...)
196 {
197         va_list ap;
198         int ret;
199
200         *str = NULL;
201         va_start(ap, fmt);
202         ret = vasprintf(str, fmt, ap);
203         va_end(ap);
204
205         return ret;
206 }
207 #endif /* !defined(HAVE_ASPRINTF) */
208
209 #ifndef HAVE_GETLOADAVG
210 #ifdef linux
211 /*! \brief Alternative method of getting load avg on Linux only */
212 int getloadavg(double *list, int nelem)
213 {
214         FILE *LOADAVG;
215         double avg[3] = { 0.0, 0.0, 0.0 };
216         int i, res = -1;
217
218         if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
219                 fscanf(LOADAVG, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]);
220                 res = 0;
221                 fclose(LOADAVG);
222         }
223
224         for (i = 0; (i < nelem) && (i < 3); i++) {
225                 list[i] = avg[i];
226         }
227
228         return res;
229 }
230 #else /* !linux */
231 /*! \brief Return something that won't cancel the call, but still return -1, in case
232  * we correct the implementation to check return value */
233 int getloadavg(double *list, int nelem)
234 {
235         int i;
236
237         for (i = 0; i < nelem; i++) {
238                 list[i] = 0.1;
239         }
240         return -1;
241 }
242 #endif /* linux */
243 #endif /* !HAVE_GETLOADAVG */