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