/[dynamips]/upstream/dynamips-0.2.7-RC2/utils.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/dynamips-0.2.7-RC2/utils.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (12 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 8831 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2005,2006 Christophe Fillot. All rights reserved.
4 *
5 * Utility functions.
6 */
7
8 #define _GNU_SOURCE
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdarg.h>
13 #include <unistd.h>
14 #include <time.h>
15 #include <signal.h>
16 #include <sys/time.h>
17 #include <sys/ioctl.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/socket.h>
21 #include <arpa/inet.h>
22 #include <netdb.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <assert.h>
26 #ifdef __CYGWIN__
27 #include <malloc.h>
28 #endif
29
30 #include "utils.h"
31
32 extern FILE *log_file;
33
34 /* Add an element to a list */
35 m_list_t *m_list_add(m_list_t **head,void *data)
36 {
37 m_list_t *item;
38
39 if ((item = malloc(sizeof(*item))) != NULL) {
40 item->data = data;
41 item->next = *head;
42 *head = item;
43 }
44
45 return item;
46 }
47
48 /* Dynamic sprintf */
49 char *dyn_sprintf(const char *fmt,...)
50 {
51 int n,size = 512;
52 va_list ap;
53 char *p,*p2;
54
55 if ((p = malloc(size)) == NULL) {
56 perror("dyn_sprintf: malloc");
57 return NULL;
58 }
59
60 for(;;)
61 {
62 /* Try to print in the allocated space */
63 va_start(ap,fmt);
64 n = vsnprintf(p,size,fmt,ap);
65 va_end(ap);
66
67 /* If that worked, return the string */
68 if ((n > -1) && (n < size))
69 return p;
70
71 /* Else try again with more space. */
72 if (n > -1)
73 size = n + 1;
74 else
75 size *= 2;
76
77 if ((p2 = realloc(p,size)) == NULL) {
78 perror("dyn_sprintf: realloc");
79 free(p);
80 return NULL;
81 }
82
83 p = p2;
84 }
85 }
86
87 /* Split a string */
88 int m_strsplit(char *str,char delim,char **array,int max_count)
89 {
90 int i,pos = 0;
91 size_t len;
92 char *ptr;
93
94 for(i=0;i<max_count;i++)
95 array[i] = NULL;
96
97 do {
98 if (pos == max_count)
99 goto error;
100
101 ptr = strchr(str,delim);
102 if (!ptr)
103 ptr = str + strlen(str);
104
105 len = ptr - str;
106
107 if (!(array[pos] = malloc(len+1)))
108 goto error;
109
110 memcpy(array[pos],str,len);
111 array[pos][len] = 0;
112
113 str = ptr + 1;
114 pos++;
115 }while(*ptr);
116
117 return(pos);
118
119 error:
120 for(i=0;i<max_count;i++)
121 free(array[i]);
122 return(-1);
123 }
124
125 /* Tokenize a string */
126 int m_strtok(char *str,char delim,char **array,int max_count)
127 {
128 int i,pos = 0;
129 size_t len;
130 char *ptr;
131
132 for(i=0;i<max_count;i++)
133 array[i] = NULL;
134
135 do {
136 if (pos == max_count)
137 goto error;
138
139 ptr = strchr(str,delim);
140 if (!ptr)
141 ptr = str + strlen(str);
142
143 len = ptr - str;
144
145 if (!(array[pos] = malloc(len+1)))
146 goto error;
147
148 memcpy(array[pos],str,len);
149 array[pos][len] = 0;
150
151 while(*ptr == delim)
152 ptr++;
153
154 str = ptr;
155 pos++;
156 }while(*ptr);
157
158 return(pos);
159
160 error:
161 for(i=0;i<max_count;i++)
162 free(array[i]);
163 return(-1);
164 }
165
166 /* Quote a string */
167 char *m_strquote(char *buffer,size_t buf_len,char *str)
168 {
169 char *p;
170
171 if (!(p = strpbrk(str," \t\"'")))
172 return str;
173
174 snprintf(buffer,buf_len,"\"%s\"",str);
175 return buffer;
176 }
177
178 /* Ugly function that dumps a structure in hexa and ascii. */
179 void mem_dump(FILE *f_output,u_char *pkt,u_int len)
180 {
181 u_int x,i = 0, tmp;
182
183 while (i < len)
184 {
185 if ((len - i) > 16)
186 x = 16;
187 else x = len - i;
188
189 fprintf(f_output,"%4.4x: ",i);
190
191 for (tmp=0;tmp<x;tmp++)
192 fprintf(f_output,"%2.2x ",pkt[i+tmp]);
193 for (tmp=x;tmp<16;tmp++) fprintf(f_output," ");
194
195 for (tmp=0;tmp<x;tmp++) {
196 char c = pkt[i+tmp];
197
198 if (((c >= 'A') && (c <= 'Z')) ||
199 ((c >= 'a') && (c <= 'z')) ||
200 ((c >= '0') && (c <= '9')))
201 fprintf(f_output,"%c",c);
202 else
203 fputs(".",f_output);
204 }
205
206 i += x;
207 fprintf(f_output,"\n");
208 }
209
210 fprintf(f_output,"\n");
211 }
212
213 /* Logging function */
214 void m_flog(FILE *fd,char *module,char *fmt,va_list ap)
215 {
216 struct timeval now;
217 static char buf[256];
218 time_t ct;
219
220 gettimeofday(&now,0);
221 ct = now.tv_sec;
222 strftime(buf,sizeof(buf),"%b %d %H:%M:%S",localtime(&ct));
223 if (fd) {
224 fprintf(fd,"%s.%03ld %s: ",buf,(long)now.tv_usec/1000,module);
225 vfprintf(fd,fmt,ap);
226 fflush(fd);
227 }
228 }
229
230 /* Logging function */
231 void m_log(char *module,char *fmt,...)
232 {
233 va_list ap;
234
235 va_start(ap,fmt);
236 m_flog(log_file,module,fmt,ap);
237 va_end(ap);
238 }
239
240 /* Returns a line from specified file (remove trailing '\n') */
241 char *m_fgets(char *buffer,int size,FILE *fd)
242 {
243 int len;
244
245 buffer[0] = '\0';
246 fgets(buffer,size,fd);
247
248 if ((len = strlen(buffer)) == 0)
249 return NULL;
250
251 /* remove trailing '\n' */
252 if (buffer[len-1] == '\n')
253 buffer[len-1] = '\0';
254
255 return buffer;
256 }
257
258 /* Read a file and returns it in a buffer */
259 ssize_t m_read_file(char *filename,char **buffer)
260 {
261 char tmp[256],*ptr,*nptr;
262 size_t len,tot_len;
263 FILE *fd;
264
265 *buffer = ptr = NULL;
266 tot_len = 0;
267
268 /* Open file for reading */
269 if ((fd = fopen(filename,"r")) == NULL)
270 return(-1);
271
272 while((len = fread(tmp,1,sizeof(tmp),fd)) > 0)
273 {
274 /* Reallocate memory */
275 nptr = realloc(ptr,tot_len+len+1);
276 if (nptr == NULL) {
277 if (ptr) free(ptr);
278 fclose(fd);
279 return(-1);
280 }
281
282 ptr = nptr;
283
284 /* Ok, memory could be allocated */
285 memcpy(&ptr[tot_len],tmp,len);
286 tot_len += len;
287 }
288
289 fclose(fd);
290 *buffer = ptr;
291 return(tot_len);
292 }
293
294 /* Allocate aligned memory */
295 void *m_memalign(size_t boundary,size_t size)
296 {
297 void *p;
298
299 #ifdef __linux__
300 if (posix_memalign((void *)&p,boundary,size))
301 #else
302 #if defined(__CYGWIN__) || defined(SUNOS)
303 if (!(p = memalign(boundary,size)))
304 #else
305 if (!(p = malloc(size)))
306 #endif
307 #endif
308 return NULL;
309
310 assert(((m_iptr_t)p & (boundary-1)) == 0);
311 return p;
312 }
313
314 /* Block specified signal for calling thread */
315 int m_signal_block(int sig)
316 {
317 sigset_t sig_mask;
318 sigemptyset(&sig_mask);
319 sigaddset(&sig_mask,sig);
320 return(pthread_sigmask(SIG_BLOCK,&sig_mask,NULL));
321 }
322
323 /* Unblock specified signal for calling thread */
324 int m_signal_unblock(int sig)
325 {
326 sigset_t sig_mask;
327 sigemptyset(&sig_mask);
328 sigaddset(&sig_mask,sig);
329 return(pthread_sigmask(SIG_UNBLOCK,&sig_mask,NULL));
330 }
331
332 /* Set non-blocking mode on a file descriptor */
333 int m_fd_set_non_block(int fd)
334 {
335 int flags;
336
337 if ((flags = fcntl(fd,F_GETFL,0)) < 1)
338 return(-1);
339
340 return(fcntl(fd,F_SETFL, flags | O_NONBLOCK));
341 }
342
343 /* Map a memory zone from a file */
344 u_char *memzone_map_file(int fd,size_t len)
345 {
346 return(mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,(off_t)0));
347 }
348
349 /* Map a memory zone from a file, with copy-on-write (COW) */
350 u_char *memzone_map_cow_file(int fd,size_t len)
351 {
352 return(mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,(off_t)0));
353 }
354
355 /* Create a file to serve as a memory zone */
356 int memzone_create_file(char *filename,size_t len,u_char **ptr)
357 {
358 int fd;
359
360 if ((fd = open(filename,O_CREAT|O_RDWR,S_IRWXU)) == -1) {
361 perror("memzone_create_file: open");
362 return(-1);
363 }
364
365 if (ftruncate(fd,len) == -1) {
366 perror("memzone_create_file: ftruncate");
367 close(fd);
368 return(-1);
369 }
370
371 *ptr = memzone_map_file(fd,len);
372
373 if (!*ptr) {
374 close(fd);
375 fd = -1;
376 }
377
378 return(fd);
379 }
380
381 /* Open a file to serve as a COW memory zone */
382 int memzone_open_cow_file(char *filename,size_t len,u_char **ptr)
383 {
384 int fd;
385
386 if ((fd = open(filename,O_RDWR,S_IRWXU)) == -1) {
387 perror("memzone_open_file: open");
388 return(-1);
389 }
390
391 *ptr = memzone_map_cow_file(fd,len);
392
393 if (!*ptr) {
394 close(fd);
395 fd = -1;
396 }
397
398 return(fd);
399 }
400
401 /* Open a file and map it in memory */
402 int memzone_open_file(char *filename,u_char **ptr,off_t *fsize)
403 {
404 struct stat fprop;
405 int fd;
406
407 if ((fd = open(filename,O_RDWR,S_IRWXU)) == -1)
408 return(-1);
409
410 if (fstat(fd,&fprop) == -1)
411 goto err_fstat;
412
413 *fsize = fprop.st_size;
414 if (!(*ptr = memzone_map_file(fd,*fsize)))
415 goto err_mmap;
416
417 return(fd);
418
419 err_mmap:
420 err_fstat:
421 close(fd);
422 return(-1);
423 }
424
425 /* Compute NVRAM checksum */
426 m_uint16_t nvram_cksum(m_uint16_t *ptr,size_t count)
427 {
428 m_uint32_t sum = 0;
429
430 while(count > 1) {
431 sum = sum + ntohs(*ptr);
432 ptr++;
433 count -= sizeof(m_uint16_t);
434 }
435
436 if (count > 0)
437 sum = sum + ((ntohs(*ptr) & 0xFF) << 8);
438
439 while(sum>>16)
440 sum = (sum & 0xffff) + (sum >> 16);
441
442 return(~sum);
443 }
444
445 /* Byte-swap a memory block */
446 void mem_bswap32(void *ptr,size_t len)
447 {
448 m_uint32_t *p = ptr;
449 size_t count = len >> 2;
450 int i;
451
452 for(i=0;i<count;i++,p++)
453 *p = swap32(*p);
454 }
455
456 /* Reverse a byte */
457 m_uint8_t m_reverse_u8(m_uint8_t val)
458 {
459 m_uint8_t res = 0;
460 int i;
461
462 for(i=0;i<8;i++)
463 if (val & (1 << i))
464 res |= 1 << (7 - i);
465
466 return(res);
467 }

  ViewVC Help
Powered by ViewVC 1.1.26