]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/net/snmp/lib/v2_0/src/system.c
Initial revision
[karo-tx-redboot.git] / packages / net / snmp / lib / v2_0 / src / system.c
1 //==========================================================================
2 //
3 //      ./lib/current/src/system.c
4 //
5 //
6 //==========================================================================
7 //####ECOSGPLCOPYRIGHTBEGIN####
8 // -------------------------------------------
9 // This file is part of eCos, the Embedded Configurable Operating System.
10 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
11 //
12 // eCos is free software; you can redistribute it and/or modify it under
13 // the terms of the GNU General Public License as published by the Free
14 // Software Foundation; either version 2 or (at your option) any later version.
15 //
16 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19 // for more details.
20 //
21 // You should have received a copy of the GNU General Public License along
22 // with eCos; if not, write to the Free Software Foundation, Inc.,
23 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 //
25 // As a special exception, if other files instantiate templates or use macros
26 // or inline functions from this file, or you compile this file and link it
27 // with other works to produce a work based on this file, this file does not
28 // by itself cause the resulting work to be covered by the GNU General Public
29 // License. However the source code for this file must still be made available
30 // in accordance with section (3) of the GNU General Public License.
31 //
32 // This exception does not invalidate any other reasons why a work based on
33 // this file might be covered by the GNU General Public License.
34 //
35 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36 // at http://sources.redhat.com/ecos/ecos-license/
37 // -------------------------------------------
38 //####ECOSGPLCOPYRIGHTEND####
39 //####UCDSNMPCOPYRIGHTBEGIN####
40 //
41 // -------------------------------------------
42 //
43 // Portions of this software may have been derived from the UCD-SNMP
44 // project,  <http://ucd-snmp.ucdavis.edu/>  from the University of
45 // California at Davis, which was originally based on the Carnegie Mellon
46 // University SNMP implementation.  Portions of this software are therefore
47 // covered by the appropriate copyright disclaimers included herein.
48 //
49 // The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
50 // -------------------------------------------
51 //
52 //####UCDSNMPCOPYRIGHTEND####
53 //==========================================================================
54 //#####DESCRIPTIONBEGIN####
55 //
56 // Author(s):    hmt
57 // Contributors: hmt
58 // Date:         2000-05-30
59 // Purpose:      Port of UCD-SNMP distribution to eCos.
60 // Description:  
61 //              
62 //
63 //####DESCRIPTIONEND####
64 //
65 //==========================================================================
66 /********************************************************************
67        Copyright 1989, 1991, 1992 by Carnegie Mellon University
68
69                           Derivative Work -
70 Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
71
72                          All Rights Reserved
73
74 Permission to use, copy, modify and distribute this software and its
75 documentation for any purpose and without fee is hereby granted,
76 provided that the above copyright notice appears in all copies and
77 that both that copyright notice and this permission notice appear in
78 supporting documentation, and that the name of CMU and The Regents of
79 the University of California not be used in advertising or publicity
80 pertaining to distribution of the software without specific written
81 permission.
82
83 CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
84 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
85 WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL CMU OR
86 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
87 INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
88 FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
89 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
90 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
91 *********************************************************************/
92 /*
93  * system.c
94  */
95 /***********************************************************
96         Copyright 1992 by Carnegie Mellon University
97
98                       All Rights Reserved
99
100 Permission to use, copy, modify, and distribute this software and its
101 documentation for any purpose and without fee is hereby granted,
102 provided that the above copyright notice appear in all copies and that
103 both that copyright notice and this permission notice appear in
104 supporting documentation, and that the name of CMU not be
105 used in advertising or publicity pertaining to distribution of the
106 software without specific, written prior permission.
107
108 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
109 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
110 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
111 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
112 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
113 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
114 SOFTWARE.
115 ******************************************************************/
116 /*
117  * System dependent routines go here
118  */
119 #include <config.h>
120 #include <stdio.h>
121 #include <ctype.h>
122
123 #if HAVE_UNISTD_H
124 #include <unistd.h>
125 #endif
126 #if HAVE_STDLIB_H
127 #include <stdlib.h>
128 #endif
129
130 #if TIME_WITH_SYS_TIME
131 # ifdef WIN32
132 #  include <sys/timeb.h>
133 # else
134 #  include <sys/time.h>
135 # endif
136 # include <time.h>
137 #else
138 # if HAVE_SYS_TIME_H
139 #  include <sys/time.h>
140 # else
141 #  include <time.h>
142 # endif
143 #endif
144
145 #include <sys/types.h>
146
147 #if HAVE_NETINET_IN_H
148 #include <netinet/in.h>
149 #endif
150
151 #if HAVE_WINSOCK_H
152 #include <winsock.h>
153 #endif
154 #if HAVE_SYS_SOCKET_H
155 #include <sys/socket.h>
156 #endif
157 #if HAVE_NET_IF_H
158 #include <net/if.h>
159 #endif
160
161 #if HAVE_SYS_SOCKIO_H
162 #include <sys/sockio.h>
163 #endif
164
165 #if HAVE_SYS_IOCTL_H
166 #include <sys/ioctl.h>
167 #endif
168
169 #ifdef HAVE_NLIST_H
170 #include <nlist.h>
171 #endif
172
173 #if HAVE_SYS_FILE_H
174 #include <sys/file.h>
175 #endif
176
177 #if HAVE_KSTAT_H
178 #include <kstat.h>
179 #endif
180
181 #if HAVE_SYS_PARAM_H
182 #include <sys/param.h>
183 #endif
184 #if HAVE_SYS_SYSCTL_H
185 #include <sys/sysctl.h>
186 #endif
187
188 #if HAVE_STRING_H
189 #include <string.h>
190 #else
191 #include <strings.h>
192 #endif
193
194 #if HAVE_DMALLOC_H
195 #include <dmalloc.h>
196 #endif
197
198 #ifdef HAVE_SYS_STAT_H
199 #include <sys/stat.h>
200 #endif
201
202 #include "asn1.h"
203 #include "snmp_api.h"
204 #include "tools.h"
205 #include "system.h"
206 #include "snmp_logging.h"
207
208 #define NUM_NETWORKS    32   /* max number of interfaces to check */
209
210 #ifndef IFF_LOOPBACK
211 #       define IFF_LOOPBACK 0
212 #endif
213
214 #define LOOPBACK    0x7f000001
215
216
217
218 /* ********************************************* */
219 #ifdef                                                  WIN32
220 #       define WIN32_LEAN_AND_MEAN
221 #       define WIN32IO_IS_STDIO
222 #       define PATHLEN  1024
223
224 #       include <tchar.h>
225 #       include <windows.h>
226
227
228 /* The idea here is to read all the directory names into a string table
229  * (separated by nulls) and when one of the other dir functions is called
230  * return the pointer to the current file name.
231  */
232 DIR *
233 opendir(const char *filename)
234 {
235     DIR            *p;
236     long            len;
237     long            idx;
238     char            scannamespc[PATHLEN];
239     char       *scanname = scannamespc;
240     struct stat     sbuf;
241     WIN32_FIND_DATA FindData;
242     HANDLE          fh;
243
244     /* check to see if filename is a directory */
245     if (stat(filename, &sbuf) < 0 || sbuf.st_mode & S_IFDIR == 0) {
246         return NULL;
247     }
248
249     /* get the file system characteristics */
250 /*  if(GetFullPathName(filename, SNMP_MAXPATH, root, &dummy)) {
251  *      if(dummy = strchr(root, '\\'))
252  *          *++dummy = '\0';
253  *      if(GetVolumeInformation(root, volname, SNMP_MAXPATH, &serial,
254  *                              &maxname, &flags, 0, 0)) {
255  *          downcase = !(flags & FS_CASE_IS_PRESERVED);
256  *      }
257  *  }
258  *  else {
259  *      downcase = TRUE;
260  *  }
261  */
262
263     /* Create the search pattern */
264     strcpy(scanname, filename);
265
266     if(strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
267         strcat(scanname, "/*");
268     else
269         strcat(scanname, "*");
270
271     /* do the FindFirstFile call */
272     fh = FindFirstFile(scanname, &FindData);
273     if(fh == INVALID_HANDLE_VALUE) {
274         return NULL;
275     }
276
277     /* Get us a DIR structure */
278     p = (DIR*)malloc(sizeof(DIR));
279     /* Newz(1303, p, 1, DIR); */
280     if(p == NULL)
281         return NULL;
282
283     /* now allocate the first part of the string table for
284      * the filenames that we find.
285      */
286     idx = strlen(FindData.cFileName)+1;
287     p->start = (char*)malloc(idx);
288     /* New(1304, p->start, idx, char);*/
289     if(p->start == NULL) {
290                 free(p);
291                 return NULL;
292     }
293     strcpy(p->start, FindData.cFileName);
294 /*  if(downcase)
295  *      strlwr(p->start);
296  */
297     p->nfiles = 0;
298
299     /* loop finding all the files that match the wildcard
300      * (which should be all of them in this directory!).
301      * the variable idx should point one past the null terminator
302      * of the previous string found.
303      */
304     while (FindNextFile(fh, &FindData)) {
305         len = strlen(FindData.cFileName);
306         /* bump the string table size by enough for the
307          * new name and it's null terminator
308          */
309         p->start = (char*)realloc((void*)p->start, idx+len+1);
310         /* Renew(p->start, idx+len+1, char);*/
311         if(p->start == NULL) {
312                 free(p);
313             return NULL;
314         }
315         strcpy(&p->start[idx], FindData.cFileName);
316 /*      if (downcase) 
317  *          strlwr(&p->start[idx]);
318  */
319                 p->nfiles++;
320                 idx += len+1;
321         }
322         FindClose(fh);
323         p->size = idx;
324         p->curr = p->start;
325         return p;
326 }
327
328
329 /* Readdir just returns the current string pointer and bumps the
330  * string pointer to the nDllExport entry.
331  */
332 struct direct *
333 readdir(DIR *dirp)
334 {
335     int         len;
336     static int  dummy = 0;
337
338     if (dirp->curr) {
339         /* first set up the structure to return */
340         len = strlen(dirp->curr);
341         strcpy(dirp->dirstr.d_name, dirp->curr);
342         dirp->dirstr.d_namlen = len;
343
344         /* Fake an inode */
345         dirp->dirstr.d_ino = dummy++;
346
347         /* Now set up for the nDllExport call to readdir */
348         dirp->curr += len + 1;
349         if (dirp->curr >= (dirp->start + dirp->size)) {
350             dirp->curr = NULL;
351         }
352
353         return &(dirp->dirstr);
354     } 
355     else
356         return NULL;
357 }
358
359 /* free the memory allocated by opendir */
360 int
361 closedir(DIR *dirp)
362 {
363     free(dirp->start);
364     free(dirp);
365     return 1;
366 }
367
368 #ifndef HAVE_GETTIMEOFDAY
369
370 int gettimeofday(struct timeval *tv,
371                  struct timezone *tz)
372 {
373     struct _timeb timebuffer;
374
375     _ftime(&timebuffer);
376     tv->tv_usec = timebuffer.millitm * 1000;
377     tv->tv_sec = timebuffer.time;
378     return(0);
379 }
380 #endif  /* !HAVE_GETTIMEOFDAY */
381
382 in_addr_t get_myaddr(void)
383 {
384   char local_host[130];
385   int result;
386   LPHOSTENT lpstHostent;
387   SOCKADDR_IN in_addr, remote_in_addr;
388   SOCKET hSock;
389   int nAddrSize = sizeof(SOCKADDR);
390
391   in_addr.sin_addr.s_addr = INADDR_ANY;
392
393   result = gethostname(local_host, sizeof(local_host));
394   if (result == 0)
395   {
396         lpstHostent = gethostbyname((LPSTR)local_host);
397         if (lpstHostent)
398         {
399           in_addr.sin_addr.s_addr = *((u_long FAR *) (lpstHostent->h_addr));
400           return((in_addr_t)in_addr.sin_addr.s_addr);
401         }
402   }
403
404   /* if we are here, than we don't have host addr */
405   hSock = socket(AF_INET, SOCK_DGRAM, 0);
406   if (hSock != INVALID_SOCKET)
407   {
408           /* connect to any port and address */
409           remote_in_addr.sin_family = AF_INET;
410           remote_in_addr.sin_len = sizeof(remote_in_addr);
411           remote_in_addr.sin_port = htons(IPPORT_ECHO);
412           remote_in_addr.sin_addr.s_addr = inet_addr("128.22.33.11");
413           result=connect(hSock,(LPSOCKADDR)&remote_in_addr,sizeof(SOCKADDR)); 
414           if (result != SOCKET_ERROR)
415           {
416               /* get local ip address */
417               getsockname(hSock, (LPSOCKADDR)&in_addr,(int FAR *)&nAddrSize);
418           }
419           closesocket(hSock);
420   }
421   return((in_addr_t)in_addr.sin_addr.s_addr);
422 }
423
424 long get_uptime (void)
425 {
426     return (0); /* not implemented */
427 }
428
429 char *
430 winsock_startup (void)
431 {
432  WORD VersionRequested;
433  WSADATA stWSAData;
434  int i;
435  static char errmsg[100];
436
437  VersionRequested = MAKEWORD(1,1);
438  i = WSAStartup(VersionRequested, &stWSAData); 
439  if (i != 0)
440  {
441   if (i == WSAVERNOTSUPPORTED)
442     sprintf(errmsg,"Unable to init. socket lib, does not support 1.1");
443   else
444   {
445     sprintf(errmsg,"Socket Startup error %d", i);
446   }
447   return(errmsg);
448  }
449  return(NULL);
450 }
451
452 void winsock_cleanup (void)
453 {
454    WSACleanup();
455 }
456
457 #else                                                   /* ! WIN32 */
458 /*******************************************************************/
459
460 /*
461  * XXX  What if we have multiple addresses?
462  * XXX  Could it be computed once then cached?
463  */
464 in_addr_t get_myaddr (void)
465 {
466     int sd;
467     struct ifconf ifc;
468     struct ifreq *ifrp, ifreq;
469     
470     struct sockaddr *sa;
471     struct sockaddr_in *in_addr;
472     char conf[1024];
473     
474     if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
475         return 0;
476     ifc.ifc_len = sizeof(conf);
477     ifc.ifc_buf = (caddr_t)conf;
478     memset(conf,0,sizeof(conf));
479     if (ioctl(sd, SIOCGIFCONF, (char *)&ifc) < 0){
480       close(sd);
481       return 0;
482     }
483
484     ifrp = ifc.ifc_req;
485     
486     while (ifc.ifc_len && ifrp->ifr_name[0]) {
487       ifreq = *ifrp;
488       if (ioctl(sd, SIOCGIFFLAGS, (char *)&ifreq) >= 0) {
489         in_addr = (struct sockaddr_in *)&ifrp->ifr_addr;
490         if ((ifreq.ifr_flags & IFF_UP)
491 #ifdef IFF_RUNNING
492             && (ifreq.ifr_flags & IFF_RUNNING)
493 #endif /* IFF_RUNNING */
494             && !(ifreq.ifr_flags & IFF_LOOPBACK)
495             && in_addr->sin_addr.s_addr != LOOPBACK){
496 #ifdef SYS_IOCTL_H_HAS_SIOCGIFADDR
497           if (ioctl(sd, SIOCGIFADDR, (char *)&ifreq) >= 0) {
498             in_addr = (struct sockaddr_in *)&(ifreq.ifr_addr);
499 #endif
500             close(sd);
501             return in_addr->sin_addr.s_addr;
502           }
503         }
504       }
505       do {
506         sa = &ifrp->ifr_addr;
507         if (sa->sa_len <= sizeof(*sa)) {          
508           ifrp++;
509         } else {
510           ifrp=(struct ifreq *)(sa->sa_len + (char *)sa);
511           ifc.ifc_len -= sa->sa_len - sizeof(*sa);
512         }
513         ifc.ifc_len -= sizeof(*ifrp);          
514         
515       } while (!ifrp->ifr_name[0] && ifc.ifc_len);      
516     }
517     close(sd);
518     return 0;
519 }
520
521
522 #if !defined(solaris2) && !defined(linux) && !defined(cygwin) && !defined(__ECOS)
523 /*
524  * Returns boottime in centiseconds(!).
525  *      Caches this for future use.
526  */
527 long get_boottime (void)
528 {
529     static long boottime_csecs = 0;
530     struct timeval boottime;
531 #ifdef  CAN_USE_SYSCTL
532     int     mib[2];
533     size_t  len;
534 #else
535     int kmem;
536     static struct nlist nl[] = {
537 #if !defined(hpux)
538             { (char*)"_boottime" },
539 #else
540             { (char*)"boottime" },
541 #endif
542             { (char*)"" }
543         };
544 #endif
545
546
547     if ( boottime_csecs != 0 )
548         return( boottime_csecs );
549
550 #ifdef CAN_USE_SYSCTL
551     mib[0] = CTL_KERN;
552     mib[1] = KERN_BOOTTIME;
553
554     len = sizeof(boottime);
555
556     sysctl(mib, 2, &boottime, &len, NULL, NULL);
557     boottime_csecs = (boottime.tv_sec * 100) + (boottime.tv_usec / 10000);
558 #else                                           /* CAN_USE_SYSCTL */
559     if ((kmem = open("/dev/kmem", 0)) < 0)
560         return 0;
561     nlist(KERNEL_LOC, nl);
562     if (nl[0].n_type == 0){
563         close(kmem);
564         return 0;
565     }
566
567     lseek(kmem, (long)nl[0].n_value, L_SET);
568     read(kmem, &boottime, sizeof(boottime));
569     close(kmem);
570     boottime_csecs = (boottime.tv_sec * 100) + (boottime.tv_usec / 10000);
571 #endif                                          /* CAN_USE_SYSCTL */
572
573     return( boottime_csecs );
574 }
575 #endif
576
577 /*
578  * Returns uptime in centiseconds(!).
579  */
580 #if !defined(__ECOS)
581 long get_uptime (void)
582 {
583 #if !defined(solaris2) && !defined(linux) && !defined(cygwin)
584     struct timeval now;
585     long boottime_csecs, nowtime_csecs;
586
587     boottime_csecs = get_boottime();
588     if (boottime_csecs == 0)
589         return 0;
590     gettimeofday(&now,(struct timezone *)0);
591     nowtime_csecs = (now.tv_sec * 100) + (now.tv_usec / 10000);
592
593     return (nowtime_csecs - boottime_csecs);
594 #endif
595
596 #ifdef solaris2
597     kstat_ctl_t *ksc = kstat_open();
598     kstat_t *ks;
599     kid_t kid;
600     kstat_named_t *named;
601     u_long lbolt = 0;
602
603     if (ksc) {
604         ks = kstat_lookup (ksc, "unix", -1, "system_misc");
605         if (ks) {
606             kid = kstat_read (ksc, ks, NULL);
607             if (kid != -1) {
608                 named = kstat_data_lookup(ks, "lbolt");
609                 if (named) {
610                     lbolt = named->value.ul;
611                 }
612             }
613         }
614         kstat_close(ksc);
615     }
616     return lbolt;
617 #endif /* solaris2 */
618
619 #ifdef linux
620    FILE *in = fopen ("/proc/uptime", "r");
621    long uptim = 0, a, b;
622    if (in) {
623        if (2 == fscanf (in, "%ld.%ld", &a, &b))
624            uptim = a * 100 + b;
625        fclose (in);
626    }
627    return uptim;
628 #endif /* linux */
629    return (0); /* not implemented */
630 }
631 #endif // not __ECOS
632
633 #ifndef HAVE_GETTIMEOFDAY
634
635 int gettimeofday(struct timeval *tv,
636                  struct timezone *tz)
637 {
638
639     tv->tv_usec = 0;
640     tv->tv_sec = time(NULL);
641     return(0);
642 }
643 #endif  /* !HAVE_GETTIMEOFDAY */
644
645
646 #endif                                                  /* ! WIN32 */
647 /*******************************************************************/
648
649 #ifndef HAVE_STRNCASECMP
650
651 /* test for NULL pointers before and NULL characters after
652  * comparing possibly non-NULL strings.
653  * WARNING: This function does NOT check for array overflow.
654  */
655 int strncasecmp(const char *s1, const char *s2, size_t nch)
656 {
657     size_t ii;
658     int res = -1;
659
660     if (!s1) {
661         if (!s2)  return 0;
662         return (-1);
663     }
664     if (!s2)
665         return (1);
666
667     for (ii = 0; (ii < nch) && *s1 && *s2; ii++, s1++, s2++)
668     {
669         res = (int) (tolower(*s1) - tolower(*s2));
670         if (res != 0) break;
671     }
672
673     if ( ii == nch ) {
674         s1--; s2--;
675     }
676
677     if (! *s1) {
678         if (! *s2)  return 0;
679         return (-1);
680     }
681     if (! *s2)
682         return (1);
683
684     return (res);
685 }
686
687 int strcasecmp(const char *s1, const char *s2)
688 {
689     return strncasecmp(s1, s2, 1000000);
690 }
691
692 #endif /* HAVE_STRNCASECMP */
693
694
695 #ifndef HAVE_STRDUP
696 char *
697 strdup(const char *src)
698 {
699     int len;
700     char *dst;
701
702     len = strlen(src) + 1;
703     if ((dst = (char *)malloc(len)) == NULL)
704         return(NULL);
705     strcpy(dst, src);
706     return(dst);
707 }
708 #endif  /* HAVE_STRDUP */
709
710 #ifndef HAVE_SETENV
711 int setenv(const char *name,
712            const char *value,
713            int overwrite)
714 {
715     char *cp;
716     int ret;
717
718     if (overwrite == 0) {
719         if (getenv(name)) return 0;
720     }
721     cp = (char*)malloc(strlen(name)+strlen(value)+2);
722     if (cp == NULL) return -1;
723     sprintf(cp, "%s=%s", name, value);
724     ret = putenv(cp);
725     return ret;
726 }
727 #endif /* HAVE_SETENV */
728
729 int
730 calculate_time_diff(struct timeval *now, struct timeval *then)
731 {
732   struct timeval tmp, diff;
733   memcpy(&tmp, now, sizeof(struct timeval));
734   tmp.tv_sec--;
735   tmp.tv_usec += 1000000L;
736   diff.tv_sec = tmp.tv_sec - then->tv_sec;
737   diff.tv_usec = tmp.tv_usec - then->tv_usec;
738   if (diff.tv_usec > 1000000L){
739     diff.tv_usec -= 1000000L;
740     diff.tv_sec++;
741   }
742   return ((diff.tv_sec * 100) + (diff.tv_usec / 10000));
743 }
744
745 #ifndef HAVE_STRCASESTR
746 /*
747  * only glibc2 has this.
748  */
749 char *strcasestr(const char *haystack, const char *needle)
750 {
751     const char *cp1=haystack, *cp2=needle;
752     const char *cx;
753     int tstch1, tstch2;
754
755     /* printf("looking for '%s' in '%s'\n", needle, haystack); */
756     if (cp1 && cp2 && *cp1 && *cp2)
757         for (cp1=haystack, cp2=needle; *cp1; ) {
758             cx = cp1; cp2 = needle;
759             do {
760                 /* printf("T'%c' ", *cp1); */
761                 if (! *cp2) { /* found the needle */
762                     /* printf("\nfound '%s' in '%s'\n", needle, cx); */
763                     return (char *)cx;
764                 }
765                 if (! *cp1)
766                     break;
767
768                 tstch1 = toupper(*cp1);
769                 tstch2 = toupper(*cp2);
770                 if (tstch1 != tstch2)
771                     break;
772                 /* printf("M'%c' ", *cp1); */
773                 cp1++; cp2++;
774             }
775             while (1);
776             if (*cp1)
777                 cp1++;
778         }
779     /* printf("\n"); */
780     if (cp1 && *cp1)
781         return (char *)cp1;
782
783     return NULL;
784 }
785 #endif
786
787 #if !defined(__ECOS)
788 int
789 mkdirhier(const char *pathname, mode_t mode, int skiplast) {
790     struct stat     sbuf;
791     char *ourcopy = strdup(pathname);
792     char *entry;
793     char buf[SNMP_MAXPATH];
794
795     entry = strtok( ourcopy, "/" );
796
797     buf[0] = '\0';
798     /* check to see if filename is a directory */
799     while ( entry ) {
800         strcat(buf,"/");
801         strcat(buf, entry);
802         entry = strtok( NULL, "/");
803         if (entry == NULL && skiplast)
804             break;
805         if (stat(buf, &sbuf) < 0) {
806             /* DNE, make it */
807             snmp_log(LOG_INFO, "Creating directory: %s\n", buf);
808 #ifdef WIN32
809             CreateDirectory(buf, NULL);
810 #else
811             mkdir(buf, mode);
812 #endif
813         } else {
814             /* exists, is it a file? */
815             if ((sbuf.st_mode & S_IFDIR) == 0) {
816                 /* ack! can't make a directory on top of a file */
817                 free(ourcopy);
818                 return SNMPERR_GENERR;
819             }
820         }
821     }
822     free(ourcopy);
823     return SNMPERR_SUCCESS;
824 }
825 #endif
826
827
828 #ifdef __ECOS
829 #include <cyg/kernel/kapi.h>
830
831 long get_boottime (void)
832 {
833     return 1l;
834 }
835
836 long get_uptime (void)
837 {
838     return cyg_current_time();
839 }
840
841 #endif
842