diff packages/net/snmp/lib/current/src/system.c @ 103:95f3e12a6327 ecos-sw-2000-06-23

Merge from eCos master repository on 2000-06-23-16:41:10-BST
author jlarmour
date Fri, 23 Jun 2000 17:06:31 +0000
parents
children e0c0827131d1
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/net/snmp/lib/current/src/system.c
@@ -0,0 +1,818 @@
+//==========================================================================
+//
+//      ./lib/current/src/system.c
+//
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//####UCDSNMPCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from the UCD-SNMP
+// project,  <http://ucd-snmp.ucdavis.edu/>  from the University of
+// California at Davis, which was originally based on the Carnegie Mellon
+// University SNMP implementation.  Portions of this software are therefore
+// covered by the appropriate copyright disclaimers included herein.
+//
+// The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
+// -------------------------------------------
+//
+//####UCDSNMPCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    hmt
+// Contributors: hmt
+// Date:         2000-05-30
+// Purpose:      Port of UCD-SNMP distribution to eCos.
+// Description:  
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+/********************************************************************
+       Copyright 1989, 1991, 1992 by Carnegie Mellon University
+
+			  Derivative Work -
+Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
+
+			 All Rights Reserved
+
+Permission to use, copy, modify and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appears in all copies and
+that both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU and The Regents of
+the University of California not be used in advertising or publicity
+pertaining to distribution of the software without specific written
+permission.
+
+CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL CMU OR
+THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
+INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*********************************************************************/
+/*
+ * system.c
+ */
+/***********************************************************
+        Copyright 1992 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of CMU not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+******************************************************************/
+/*
+ * System dependent routines go here
+ */
+#include <config.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if TIME_WITH_SYS_TIME
+# ifdef WIN32
+#  include <sys/timeb.h>
+# else
+#  include <sys/time.h>
+# endif
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#include <sys/types.h>
+
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#if HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+
+#if HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_NLIST_H
+#include <nlist.h>
+#endif
+
+#if HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+
+#if HAVE_KSTAT_H
+#include <kstat.h>
+#endif
+
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#if HAVE_DMALLOC_H
+#include <dmalloc.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "asn1.h"
+#include "snmp_api.h"
+#include "tools.h"
+#include "system.h"
+#include "snmp_logging.h"
+
+#define NUM_NETWORKS    32   /* max number of interfaces to check */
+
+#ifndef IFF_LOOPBACK
+#	define IFF_LOOPBACK 0
+#endif
+
+#define LOOPBACK    0x7f000001
+
+
+
+/* ********************************************* */
+#ifdef							WIN32
+#	define WIN32_LEAN_AND_MEAN
+#	define WIN32IO_IS_STDIO
+#	define PATHLEN	1024
+
+#	include <tchar.h>
+#	include <windows.h>
+
+
+/* The idea here is to read all the directory names into a string table
+ * (separated by nulls) and when one of the other dir functions is called
+ * return the pointer to the current file name.
+ */
+DIR *
+opendir(const char *filename)
+{
+    DIR            *p;
+    long            len;
+    long            idx;
+    char            scannamespc[PATHLEN];
+    char       *scanname = scannamespc;
+    struct stat     sbuf;
+    WIN32_FIND_DATA FindData;
+    HANDLE          fh;
+
+    /* check to see if filename is a directory */
+    if (stat(filename, &sbuf) < 0 || sbuf.st_mode & S_IFDIR == 0) {
+	return NULL;
+    }
+
+    /* get the file system characteristics */
+/*  if(GetFullPathName(filename, SNMP_MAXPATH, root, &dummy)) {
+ *	if(dummy = strchr(root, '\\'))
+ *	    *++dummy = '\0';
+ *	if(GetVolumeInformation(root, volname, SNMP_MAXPATH, &serial,
+ *				&maxname, &flags, 0, 0)) {
+ *	    downcase = !(flags & FS_CASE_IS_PRESERVED);
+ *	}
+ *  }
+ *  else {
+ *	downcase = TRUE;
+ *  }
+ */
+
+    /* Create the search pattern */
+    strcpy(scanname, filename);
+
+    if(strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
+	strcat(scanname, "/*");
+    else
+	strcat(scanname, "*");
+
+    /* do the FindFirstFile call */
+    fh = FindFirstFile(scanname, &FindData);
+    if(fh == INVALID_HANDLE_VALUE) {
+	return NULL;
+    }
+
+    /* Get us a DIR structure */
+    p = (DIR*)malloc(sizeof(DIR));
+    /* Newz(1303, p, 1, DIR); */
+    if(p == NULL)
+	return NULL;
+
+    /* now allocate the first part of the string table for
+     * the filenames that we find.
+     */
+    idx = strlen(FindData.cFileName)+1;
+    p->start = (char*)malloc(idx);
+    /* New(1304, p->start, idx, char);*/
+    if(p->start == NULL) {
+		free(p);
+		return NULL;
+    }
+    strcpy(p->start, FindData.cFileName);
+/*  if(downcase)
+ *	strlwr(p->start);
+ */
+    p->nfiles = 0;
+
+    /* loop finding all the files that match the wildcard
+     * (which should be all of them in this directory!).
+     * the variable idx should point one past the null terminator
+     * of the previous string found.
+     */
+    while (FindNextFile(fh, &FindData)) {
+	len = strlen(FindData.cFileName);
+	/* bump the string table size by enough for the
+	 * new name and it's null terminator
+	 */
+	p->start = (char*)realloc((void*)p->start, idx+len+1);
+	/* Renew(p->start, idx+len+1, char);*/
+	if(p->start == NULL) {
+		free(p);
+	    return NULL;
+	}
+	strcpy(&p->start[idx], FindData.cFileName);
+/*	if (downcase) 
+ *	    strlwr(&p->start[idx]);
+ */
+		p->nfiles++;
+		idx += len+1;
+	}
+	FindClose(fh);
+	p->size = idx;
+	p->curr = p->start;
+	return p;
+}
+
+
+/* Readdir just returns the current string pointer and bumps the
+ * string pointer to the nDllExport entry.
+ */
+struct direct *
+readdir(DIR *dirp)
+{
+    int         len;
+    static int  dummy = 0;
+
+    if (dirp->curr) {
+	/* first set up the structure to return */
+	len = strlen(dirp->curr);
+	strcpy(dirp->dirstr.d_name, dirp->curr);
+	dirp->dirstr.d_namlen = len;
+
+	/* Fake an inode */
+	dirp->dirstr.d_ino = dummy++;
+
+	/* Now set up for the nDllExport call to readdir */
+	dirp->curr += len + 1;
+	if (dirp->curr >= (dirp->start + dirp->size)) {
+	    dirp->curr = NULL;
+	}
+
+	return &(dirp->dirstr);
+    } 
+    else
+	return NULL;
+}
+
+/* free the memory allocated by opendir */
+int
+closedir(DIR *dirp)
+{
+    free(dirp->start);
+    free(dirp);
+    return 1;
+}
+
+#ifndef HAVE_GETTIMEOFDAY
+
+int gettimeofday(struct timeval *tv,
+		 struct timezone *tz)
+{
+    struct _timeb timebuffer;
+
+    _ftime(&timebuffer);
+    tv->tv_usec = timebuffer.millitm * 1000;
+    tv->tv_sec = timebuffer.time;
+    return(0);
+}
+#endif	/* !HAVE_GETTIMEOFDAY */
+
+in_addr_t get_myaddr(void)
+{
+  char local_host[130];
+  int result;
+  LPHOSTENT lpstHostent;
+  SOCKADDR_IN in_addr, remote_in_addr;
+  SOCKET hSock;
+  int nAddrSize = sizeof(SOCKADDR);
+
+  in_addr.sin_addr.s_addr = INADDR_ANY;
+
+  result = gethostname(local_host, sizeof(local_host));
+  if (result == 0)
+  {
+	lpstHostent = gethostbyname((LPSTR)local_host);
+	if (lpstHostent)
+	{
+	  in_addr.sin_addr.s_addr = *((u_long FAR *) (lpstHostent->h_addr));
+	  return((in_addr_t)in_addr.sin_addr.s_addr);
+	}
+  }
+
+  /* if we are here, than we don't have host addr */
+  hSock = socket(AF_INET, SOCK_DGRAM, 0);
+  if (hSock != INVALID_SOCKET)
+  {
+	  /* connect to any port and address */
+	  remote_in_addr.sin_family = AF_INET;
+	  remote_in_addr.sin_port = htons(IPPORT_ECHO);
+	  remote_in_addr.sin_addr.s_addr = inet_addr("128.22.33.11");
+	  result=connect(hSock,(LPSOCKADDR)&remote_in_addr,sizeof(SOCKADDR)); 
+	  if (result != SOCKET_ERROR)
+	  {
+	      /* get local ip address */
+	      getsockname(hSock, (LPSOCKADDR)&in_addr,(int FAR *)&nAddrSize);
+	  }
+	  closesocket(hSock);
+  }
+  return((in_addr_t)in_addr.sin_addr.s_addr);
+}
+
+long get_uptime (void)
+{
+    return (0); /* not implemented */
+}
+
+char *
+winsock_startup (void)
+{
+ WORD VersionRequested;
+ WSADATA stWSAData;
+ int i;
+ static char errmsg[100];
+
+ VersionRequested = MAKEWORD(1,1);
+ i = WSAStartup(VersionRequested, &stWSAData); 
+ if (i != 0)
+ {
+  if (i == WSAVERNOTSUPPORTED)
+    sprintf(errmsg,"Unable to init. socket lib, does not support 1.1");
+  else
+  {
+    sprintf(errmsg,"Socket Startup error %d", i);
+  }
+  return(errmsg);
+ }
+ return(NULL);
+}
+
+void winsock_cleanup (void)
+{
+   WSACleanup();
+}
+
+#else							/* ! WIN32 */
+/*******************************************************************/
+
+/*
+ * XXX	What if we have multiple addresses?
+ * XXX	Could it be computed once then cached?
+ */
+in_addr_t get_myaddr (void)
+{
+    int sd;
+    struct ifconf ifc;
+    struct ifreq conf[NUM_NETWORKS], *ifrp, ifreq;
+    struct sockaddr_in *in_addr;
+    int count;
+    int interfaces;             /* number of interfaces returned by ioctl */
+
+    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+        return 0;
+    ifc.ifc_len = sizeof(conf);
+    ifc.ifc_buf = (caddr_t)conf;
+    if (ioctl(sd, SIOCGIFCONF, (char *)&ifc) < 0){
+        close(sd);
+        return 0;
+    }
+    ifrp = ifc.ifc_req;
+    interfaces = ifc.ifc_len / sizeof(struct ifreq);
+    for(count = 0; count < interfaces; count++, ifrp++){
+        ifreq = *ifrp;
+        if (ioctl(sd, SIOCGIFFLAGS, (char *)&ifreq) < 0)
+            continue;
+        in_addr = (struct sockaddr_in *)&ifrp->ifr_addr;
+        if ((ifreq.ifr_flags & IFF_UP)
+#ifdef IFF_RUNNING
+          && (ifreq.ifr_flags & IFF_RUNNING)
+#endif /* IFF_RUNNING */
+          && !(ifreq.ifr_flags & IFF_LOOPBACK)
+          && in_addr->sin_addr.s_addr != LOOPBACK){
+#ifdef SYS_IOCTL_H_HAS_SIOCGIFADDR
+	    if (ioctl(sd, SIOCGIFADDR, (char *)&ifreq) < 0)
+		continue;
+	    in_addr = (struct sockaddr_in *)&(ifreq.ifr_addr);
+#endif
+	    close(sd);
+	    return in_addr->sin_addr.s_addr;
+	}
+    }
+    close(sd);
+    return 0;
+}
+
+
+#if !defined(solaris2) && !defined(linux) && !defined(cygwin) && !defined(__ECOS)
+/*
+ * Returns boottime in centiseconds(!).
+ *	Caches this for future use.
+ */
+long get_boottime (void)
+{
+    static long boottime_csecs = 0;
+    struct timeval boottime;
+#ifdef	CAN_USE_SYSCTL
+    int	    mib[2];
+    size_t  len;
+#else
+    int kmem;
+    static struct nlist nl[] = {
+#if !defined(hpux)
+	    { (char*)"_boottime" },
+#else
+	    { (char*)"boottime" },
+#endif
+	    { (char*)"" }
+	};
+#endif
+
+
+    if ( boottime_csecs != 0 )
+	return( boottime_csecs );
+
+#ifdef CAN_USE_SYSCTL
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_BOOTTIME;
+
+    len = sizeof(boottime);
+
+    sysctl(mib, 2, &boottime, &len, NULL, NULL);
+    boottime_csecs = (boottime.tv_sec * 100) + (boottime.tv_usec / 10000);
+#else						/* CAN_USE_SYSCTL */
+    if ((kmem = open("/dev/kmem", 0)) < 0)
+	return 0;
+    nlist(KERNEL_LOC, nl);
+    if (nl[0].n_type == 0){
+	close(kmem);
+	return 0;
+    }
+
+    lseek(kmem, (long)nl[0].n_value, L_SET);
+    read(kmem, &boottime, sizeof(boottime));
+    close(kmem);
+    boottime_csecs = (boottime.tv_sec * 100) + (boottime.tv_usec / 10000);
+#endif						/* CAN_USE_SYSCTL */
+
+    return( boottime_csecs );
+}
+#endif
+
+/*
+ * Returns uptime in centiseconds(!).
+ */
+#if !defined(__ECOS)
+long get_uptime (void)
+{
+#if !defined(solaris2) && !defined(linux) && !defined(cygwin)
+    struct timeval now;
+    long boottime_csecs, nowtime_csecs;
+
+    boottime_csecs = get_boottime();
+    if (boottime_csecs == 0)
+	return 0;
+    gettimeofday(&now,(struct timezone *)0);
+    nowtime_csecs = (now.tv_sec * 100) + (now.tv_usec / 10000);
+
+    return (nowtime_csecs - boottime_csecs);
+#endif
+
+#ifdef solaris2
+    kstat_ctl_t *ksc = kstat_open();
+    kstat_t *ks;
+    kid_t kid;
+    kstat_named_t *named;
+    u_long lbolt = 0;
+
+    if (ksc) {
+	ks = kstat_lookup (ksc, "unix", -1, "system_misc");
+	if (ks) {
+	    kid = kstat_read (ksc, ks, NULL);
+	    if (kid != -1) {
+		named = kstat_data_lookup(ks, "lbolt");
+		if (named) {
+		    lbolt = named->value.ul;
+		}
+	    }
+	}
+	kstat_close(ksc);
+    }
+    return lbolt;
+#endif /* solaris2 */
+
+#ifdef linux
+   FILE *in = fopen ("/proc/uptime", "r");
+   long uptim = 0, a, b;
+   if (in) {
+       if (2 == fscanf (in, "%ld.%ld", &a, &b))
+	   uptim = a * 100 + b;
+       fclose (in);
+   }
+   return uptim;
+#endif /* linux */
+   return (0); /* not implemented */
+}
+#endif // not __ECOS
+
+#ifndef HAVE_GETTIMEOFDAY
+
+int gettimeofday(struct timeval *tv,
+		 struct timezone *tz)
+{
+
+    tv->tv_usec = 0;
+    tv->tv_sec = time(NULL);
+    return(0);
+}
+#endif	/* !HAVE_GETTIMEOFDAY */
+
+
+#endif							/* ! WIN32 */
+/*******************************************************************/
+
+#ifndef HAVE_STRNCASECMP
+
+/* test for NULL pointers before and NULL characters after
+ * comparing possibly non-NULL strings.
+ * WARNING: This function does NOT check for array overflow.
+ */
+int strncasecmp(const char *s1, const char *s2, size_t nch)
+{
+    size_t ii;
+    int res = -1;
+
+    if (!s1) {
+        if (!s2)  return 0;
+        return (-1);
+    }
+    if (!s2)
+        return (1);
+
+    for (ii = 0; (ii < nch) && *s1 && *s2; ii++, s1++, s2++)
+    {
+        res = (int) (tolower(*s1) - tolower(*s2));
+        if (res != 0) break;
+    }
+
+    if ( ii == nch ) {
+        s1--; s2--;
+    }
+
+    if (! *s1) {
+        if (! *s2)  return 0;
+        return (-1);
+    }
+    if (! *s2)
+        return (1);
+
+    return (res);
+}
+
+int strcasecmp(const char *s1, const char *s2)
+{
+    return strncasecmp(s1, s2, 1000000);
+}
+
+#endif /* HAVE_STRNCASECMP */
+
+
+#ifndef HAVE_STRDUP
+char *
+strdup(const char *src)
+{
+    int len;
+    char *dst;
+
+    len = strlen(src) + 1;
+    if ((dst = (char *)malloc(len)) == NULL)
+	return(NULL);
+    strcpy(dst, src);
+    return(dst);
+}
+#endif	/* HAVE_STRDUP */
+
+#ifndef HAVE_SETENV
+int setenv(const char *name,
+	   const char *value,
+	   int overwrite)
+{
+    char *cp;
+    int ret;
+
+    if (overwrite == 0) {
+	if (getenv(name)) return 0;
+    }
+    cp = (char*)malloc(strlen(name)+strlen(value)+2);
+    if (cp == NULL) return -1;
+    sprintf(cp, "%s=%s", name, value);
+    ret = putenv(cp);
+    return ret;
+}
+#endif /* HAVE_SETENV */
+
+int
+calculate_time_diff(struct timeval *now, struct timeval *then)
+{
+  struct timeval tmp, diff;
+  memcpy(&tmp, now, sizeof(struct timeval));
+  tmp.tv_sec--;
+  tmp.tv_usec += 1000000L;
+  diff.tv_sec = tmp.tv_sec - then->tv_sec;
+  diff.tv_usec = tmp.tv_usec - then->tv_usec;
+  if (diff.tv_usec > 1000000L){
+    diff.tv_usec -= 1000000L;
+    diff.tv_sec++;
+  }
+  return ((diff.tv_sec * 100) + (diff.tv_usec / 10000));
+}
+
+#ifndef HAVE_STRCASESTR
+/*
+ * only glibc2 has this.
+ */
+char *strcasestr(const char *haystack, const char *needle)
+{
+    const char *cp1=haystack, *cp2=needle;
+    const char *cx;
+    int tstch1, tstch2;
+
+    /* printf("looking for '%s' in '%s'\n", needle, haystack); */
+    if (cp1 && cp2 && *cp1 && *cp2)
+        for (cp1=haystack, cp2=needle; *cp1; ) {
+            cx = cp1; cp2 = needle;
+            do {
+                /* printf("T'%c' ", *cp1); */
+                if (! *cp2) { /* found the needle */
+                    /* printf("\nfound '%s' in '%s'\n", needle, cx); */
+                    return (char *)cx;
+                }
+                if (! *cp1)
+                    break;
+
+                tstch1 = toupper(*cp1);
+                tstch2 = toupper(*cp2);
+                if (tstch1 != tstch2)
+                    break;
+                /* printf("M'%c' ", *cp1); */
+                cp1++; cp2++;
+            }
+            while (1);
+            if (*cp1)
+                cp1++;
+        }
+    /* printf("\n"); */
+    if (cp1 && *cp1)
+        return (char *)cp1;
+
+    return NULL;
+}
+#endif
+
+#if !defined(__ECOS)
+int
+mkdirhier(const char *pathname, mode_t mode, int skiplast) {
+    struct stat     sbuf;
+    char *ourcopy = strdup(pathname);
+    char *entry;
+    char buf[SNMP_MAXPATH];
+
+    entry = strtok( ourcopy, "/" );
+
+    buf[0] = '\0';
+    /* check to see if filename is a directory */
+    while ( entry ) {
+        strcat(buf,"/");
+        strcat(buf, entry);
+        entry = strtok( NULL, "/");
+        if (entry == NULL && skiplast)
+            break;
+        if (stat(buf, &sbuf) < 0) {
+            /* DNE, make it */
+            snmp_log(LOG_INFO, "Creating directory: %s\n", buf);
+#ifdef WIN32
+	    CreateDirectory(buf, NULL);
+#else
+            mkdir(buf, mode);
+#endif
+        } else {
+            /* exists, is it a file? */
+            if ((sbuf.st_mode & S_IFDIR) == 0) {
+                /* ack! can't make a directory on top of a file */
+                free(ourcopy);
+                return SNMPERR_GENERR;
+            }
+        }
+    }
+    free(ourcopy);
+    return SNMPERR_SUCCESS;
+}
+#endif
+
+
+#ifdef __ECOS
+#include <cyg/kernel/kapi.h>
+
+long get_boottime (void)
+{
+    return 1l;
+}
+
+long get_uptime (void)
+{
+    return cyg_current_time();
+}
+
+#endif
+