main.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:16k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Main-level NOS program:
  2.  *  initialization
  3.  *  keyboard processing
  4.  *  generic user commands
  5.  *
  6.  * Copyright 1986-1995 Phil Karn, KA9Q
  7.  */
  8. #include <stdio.h>
  9. #include <time.h>
  10. #include <ctype.h>
  11. #if defined(__TURBOC__) && defined(MSDOS)
  12. #include <io.h>
  13. #include <conio.h>
  14. #endif
  15. #include "global.h"
  16. #include <stdarg.h>
  17. #include "mbuf.h"
  18. #include "timer.h"
  19. #include "proc.h"
  20. #include "iface.h"
  21. #include "ip.h"
  22. #include "tcp.h"
  23. #include "udp.h"
  24. #include "ax25.h"
  25. #include "kiss.h"
  26. #include "enet.h"
  27. #include "netrom.h"
  28. #include "ftpcli.h"
  29. #include "telnet.h"
  30. #include "tty.h"
  31. #include "session.h"
  32. #include "hardware.h"
  33. #include "usock.h"
  34. #include "socket.h"
  35. #include "cmdparse.h"
  36. #include "commands.h"
  37. #include "daemon.h"
  38. #include "devparam.h"
  39. #include "domain.h"
  40. #include "files.h"
  41. #include "main.h"
  42. #include "remote.h"
  43. #include "trace.h"
  44. #include "display.h"
  45. extern struct cmds Cmds[],Startcmds[],Stopcmds[],Attab[];
  46. #ifndef MSDOS /* PC uses F-10 key always */
  47. static char Escape = 0x1d; /* default escape character is ^] */
  48. #endif
  49. char Badhost[] = "Unknown host %sn";
  50. char *Hostname;
  51. char Nospace[] = "No space!!n"; /* Generic malloc fail message */
  52. struct proc *Cmdpp;
  53. struct proc *Display;
  54. char *Cmdline; /* Copy of most recent command line */
  55. int main_exit = FALSE; /* from main program (flag) */
  56. static char Prompt[] = "net> ";
  57. static FILE *Logfp;
  58. static time_t StartTime; /* time that NOS was started */
  59. static int Verbose;
  60. static int keychar(int c);
  61. static void pass(char *,int len);
  62. static void passchar(int c);
  63. int
  64. main(argc,argv)
  65. int argc;
  66. char *argv[];
  67. {
  68. FILE *fp;
  69. struct daemon *tp;
  70. int c;
  71. char cmdbuf[256];
  72. long hinit = 102400;
  73. unsigned chunk;
  74. void **list;
  75. StartTime = time(&StartTime);
  76. while((c = getopt(argc,argv,"f:s:d:bvh:")) != EOF){
  77. switch(c){
  78. case 'h': /* Heap initialization */
  79. hinit = atol(optarg);
  80. break;
  81. case 'f': /* Number of files */
  82. Nfiles = atoi(optarg);
  83. break;
  84. case 's': /* Number of sockets */
  85. Nsock = atoi(optarg);
  86. break;
  87. case 'd': /* Root directory for various files */
  88. initroot(optarg);
  89. break;
  90. #ifdef __TURBOC__
  91. case 'b': /* Use BIOS for screen output */
  92. directvideo = 0;
  93. break;
  94. #endif
  95. case 'v':
  96. Verbose = 1;
  97. break;
  98. }
  99. }
  100. /* Get some memory on the heap so interrupt calls to malloc
  101.  * won't fail unnecessarily
  102.  */
  103. list = calloc(sizeof(void *),(hinit / 32768L) + 1);
  104. for(c=0;hinit > 0;hinit -= chunk){
  105. chunk = min(hinit,32768U);
  106. list[c++] = malloc(chunk);
  107. }
  108. while(c > 0)
  109. free(list[--c]);
  110. free(list);
  111. kinit();
  112. ipinit();
  113. ioinit();
  114. sockinit();
  115. Cmdpp = mainproc("cmdintrp");
  116. Sessions = (struct session **)callocw(Nsessions,sizeof(struct session *));
  117. Command = Lastcurr = newsession("command interpreter",COMMAND,1);
  118. Display = newproc("display",350,display,0,NULL,NULL,0);
  119. printf("KA9Q NOS version %sn",Version);
  120. #ifdef CPU386
  121. printf("Compiled for 386/486 CPUn");
  122. #endif
  123. printf("Copyright 1986-1995 by Phil Karn, KA9Qn");
  124. usercvt();
  125. /* Start background Daemons */
  126. for(tp=Daemons;;tp++){
  127. if(tp->name == NULL)
  128. break;
  129. newproc(tp->name,tp->stksize,tp->fp,0,NULL,NULL,0);
  130. }
  131. Encap.txproc = newproc("encap tx",512,if_tx,0,&Encap,NULL,0);
  132. if(optind < argc){
  133. /* Read startup file named on command line */
  134. if((fp = fopen(argv[optind],READ_TEXT)) == NULL){
  135. printf("Can't read config file %s",argv[optind]);
  136. perror("");
  137. }
  138. } else {
  139. fp = fopen(Startup,READ_TEXT);
  140. }
  141. if(fp != NULL){
  142. while(fgets(cmdbuf,sizeof(cmdbuf),fp) != NULL){
  143. rip(cmdbuf);
  144. if(Cmdline != NULL)
  145. free(Cmdline);
  146. Cmdline = strdup(cmdbuf);
  147. if(Verbose)
  148. printf("%sn",Cmdline);
  149. if(cmdparse(Cmds,cmdbuf,NULL) != 0){
  150. printf("input line: %sn",Cmdline);
  151. }
  152. }
  153. fclose(fp);
  154. }
  155. /* Now loop forever, processing commands */
  156. for(;;){
  157. printf(Prompt);
  158. fflush(stdout);
  159. if(fgets(cmdbuf,sizeof(cmdbuf),stdin) != NULL){
  160. rip(cmdbuf);
  161. if(Cmdline)
  162. free(Cmdline);
  163. Cmdline = strdup(cmdbuf);
  164. (void)cmdparse(Cmds,cmdbuf,Lastcurr);
  165. }
  166. }
  167. }
  168. /* Keyboard input process */
  169. void
  170. keyboard(i,v1,v2)
  171. int i;
  172. void *v1;
  173. void *v2;
  174. {
  175. int c;
  176. int j;
  177. /* Keyboard process loop */
  178. loop:
  179. c = kbread();
  180. #ifdef MSDOS
  181. if(c >= 256){
  182. /* Pass all special characters to app upcall */
  183. if(Current->ctlproc != NULL && (c = (*Current->ctlproc)(c)) == 0)
  184. goto loop; /* Upcall took them */
  185. c -= 256;
  186. if(Current->scrollmode == SCROLL_INBAND){
  187. /* In inband scroll mode, pass escape sequences
  188.  * for cursor control keys. Otherwise fall thru
  189.  */ 
  190. switch(c){
  191. case CURSHOM:
  192. pass("33O",3);
  193. goto loop;
  194. case CURSUP:
  195. pass("33OA",3);
  196. goto loop;
  197. case PAGEUP:
  198. pass("33[5~",4);
  199. goto loop;
  200. case CURSEND:
  201. pass("33OU",3);
  202. goto loop;
  203. case CURSDWN:
  204. pass("33OB",3);
  205. goto loop;
  206. case PAGEDWN:
  207. pass("33[6~",4);
  208. goto loop;
  209. case CURSRIGHT:
  210. pass("33OC",3);
  211. goto loop;
  212. case CURSLEFT:
  213. pass("33OD",3);
  214. goto loop;
  215. }
  216. }
  217. /* In local scroll mode, we can get here with cursor
  218.  * control keys
  219.  */
  220. switch(c){
  221. case CURSHOM:
  222. dhome(Current->output->ptr);
  223. break;
  224. case CURSUP:
  225. dcursup(Current->output->ptr);
  226. break;
  227. case PAGEUP:
  228. dpgup(Current->output->ptr);
  229. break;
  230. case CURSEND:
  231. dend(Current->output->ptr);
  232. break;
  233. case CURSDWN:
  234. dcursdown(Current->output->ptr);
  235. break;
  236. case PAGEDWN:
  237. dpgdown(Current->output->ptr);
  238. break;
  239. case F10: /* F-10 (go to command mode) */
  240. if(Current != Command){
  241. /* Save current tty mode and set cooked */
  242. Lastcurr = Current;
  243. Current = Command;
  244. alert(Display,1);
  245. }
  246. break;
  247. case F9: /* F-9 (resume last current session) */
  248. if(Current == Command && Lastcurr != NULL){
  249. Current = Lastcurr;
  250. alert(Display,1);
  251. }
  252. break;
  253. case F8: /* F-8 (next session) */
  254. for(j = Current->index+1;j != Current->index;j++){
  255. if(j >= Nsessions)
  256. j = 0;
  257. if(Sessions[j] != NULL){
  258. Current = Sessions[j];
  259. alert(Display,1);
  260. break;
  261. }
  262. }
  263. break;
  264. case F7: /* F-7 (prev session) */
  265. for(j = Current->index-1;j != Current->index;j--){
  266. if(j == -1)
  267. j = Nsessions-1;
  268. if(Sessions[j] != NULL){
  269. Current = Sessions[j];
  270. alert(Display,1);
  271. break;
  272. }
  273. }
  274. break;
  275. case F6: /* Toggle scroll mode */
  276. if(Current == NULL)
  277. break;
  278. Current->scrollmode = !Current->scrollmode;
  279. dscrollmode(Current->output->ptr,Current->scrollmode);
  280. break;
  281. case F5: /* Kick current session */
  282. if(Current != NULL)
  283. dokick(0,NULL,Current);
  284. break;
  285. case AF1:
  286. case AF2:
  287. case AF3:
  288. case AF4:
  289. case AF5:
  290. case AF6:
  291. case AF7:
  292. case AF8:
  293. case AF9:
  294. case AF10: /* Alt-F1 thru Alt-F10 */
  295. c -= 103;
  296. if(c < Nsessions && Sessions[c] != NULL){
  297. Current = Sessions[c];
  298. alert(Display,1);
  299. }
  300. break;
  301. case AF11: /* Alt-F11 or Alt-F12 */
  302. case AF12:
  303. c -= 128;
  304. if(c < Nsessions && Sessions[c] != NULL){
  305. Current = Sessions[c];
  306. alert(Display,1);
  307. }
  308. break;
  309. default: /* else ignore */
  310. break;
  311. }
  312. goto loop;
  313. }
  314. #else
  315. if(c == Escape && Escape != 0 && Current != Command){
  316. /* Save current tty mode and set cooked */
  317. Lastcurr = Current;
  318. Current = Command;
  319. alert(Display,1);
  320. goto loop;
  321. }
  322. #endif
  323. passchar(c);
  324. goto loop;
  325. }
  326. static void
  327. pass(s,len)
  328. char *s;
  329. int len;
  330. {
  331. while(len-- != 0)
  332. passchar(*s++);
  333. }
  334. static void
  335. passchar(c)
  336. int c;
  337. {
  338. int cnt;
  339. /* If a normal-character upcall exists, give it the character.
  340.  * if the upcall returns 0, don't pass it to the regular tty editor
  341.  */
  342. if(Current->inproc != NULL && (*Current->inproc)(c) == 0)
  343. return;
  344. /* Ordinary ASCII character, hand to tty editor */
  345. if((cnt = ttydriv(Current,(char)c)) != 0){
  346. /* Input ready to hand to process */
  347. fwrite(Current->ttystate.line,1,cnt,Current->input);
  348. fflush(Current->input);
  349. }
  350. }
  351. /* Standard commands called from main */
  352. int
  353. dorepeat(argc,argv,p)
  354. int argc;
  355. char *argv[];
  356. void *p;
  357. {
  358. int32 interval;
  359. int ret;
  360. struct session *sp;
  361. if(isdigit(argv[1][0])){
  362. interval = atol(argv[1]);
  363. argc--;
  364. argv++;
  365. } else {
  366. interval = MSPTICK;
  367. }
  368. if((sp = newsession(Cmdline,REPEAT,1)) == NULL){
  369. printf("Too many sessionsn");
  370. return 1;
  371. }
  372. sp->inproc = keychar; /* Intercept ^C */
  373. /* Set enough buffering to handle an entire screen so it'll get
  374.  * displayed in one quick update when we flush
  375.  */
  376. setvbuf(sp->output,NULL,_IOFBF,2048);
  377. while(sp->inproc == keychar){ /* ^C will clear sp->inproc */
  378. printf("%c[2J",ESC); /* Clear screen */
  379. ret = subcmd(Cmds,argc,argv,p);
  380. fflush(sp->output);
  381. if(ret != 0 || ppause(interval) == -1)
  382. break;
  383. }
  384. keywait(NULL,1);
  385. freesession(sp);
  386. return 0;
  387. }
  388. static int
  389. keychar(c)
  390. int c;
  391. {
  392. if(c != CTLC)
  393. return 1; /* Ignore all but ^C */
  394. fprintf(Current->output,"^Cn");
  395. alert(Current->proc,EABORT);
  396. Current->inproc = NULL;
  397. return 0;
  398. }
  399. int
  400. dodelete(argc,argv,p)
  401. int argc;
  402. char *argv[];
  403. void *p;
  404. {
  405. int i;
  406. for(i=1;i < argc; i++){
  407. if(unlink(argv[i]) == -1){
  408. printf("Can't delete %s",argv[i]);
  409. perror("");
  410. }
  411. }
  412. return 0;
  413. }
  414. int
  415. dorename(argc,argv,p)
  416. int argc;
  417. char *argv[];
  418. void *p;
  419. {
  420. if(rename(argv[1],argv[2]) == -1){
  421. printf("Can't rename %s",argv[1]);
  422. perror("");
  423. }
  424. return 0;
  425. }
  426. int
  427. doexit(argc,argv,p)
  428. int argc;
  429. char *argv[];
  430. void *p;
  431. {
  432. int i;
  433. time_t StopTime;
  434. struct session *sp;
  435. StopTime = time(&StopTime);
  436. main_exit = TRUE; /* let everyone know we're out of here */
  437. /* Alert each session task that we're aborting */
  438. for(i=0;i<Nsessions;i++){
  439. if((sp = Sessions[i]) == NULL)
  440. continue;
  441. alert(sp->proc,EABORT);
  442. alert(sp->proc1,EABORT);
  443. alert(sp->proc2,EABORT);
  444. }
  445. reset_all();
  446. if(Dfile_updater != NULL)
  447. alert(Dfile_updater,0); /* don't wait for timeout */
  448. for(i=0;i<100;i++)
  449. kwait(NULL); /* Allow tasks to complete */
  450. shuttrace();
  451. logmsg(-1,"NOS was stopped at %s", ctime(&StopTime));
  452. if(Logfp){
  453. fclose(Logfp);
  454. Logfp = NULL;
  455. }
  456. clrscr();
  457. iostop();
  458. exit(0);
  459. return 0; /* To satisfy lint */
  460. }
  461. int
  462. dohostname(argc,argv,p)
  463. int argc;
  464. char *argv[];
  465. void *p;
  466. {
  467. if(argc < 2)
  468. printf("%sn",Hostname);
  469. else {
  470. struct iface *ifp;
  471. char *name;
  472. if((ifp = if_lookup(argv[1])) != NULL){
  473. if((name = resolve_a(ifp->addr, FALSE)) == NULL){
  474. printf("Interface address not resolvedn");
  475. return 1;
  476. } else {
  477. if(Hostname != NULL)
  478. free(Hostname);
  479. Hostname = name;
  480. /* remove trailing dot */
  481. if ( Hostname[strlen(Hostname)] == '.' ) {
  482. Hostname[strlen(Hostname)] = '';
  483. }
  484. printf("Hostname set to %sn", name );
  485. }
  486. } else {
  487. if(Hostname != NULL)
  488. free(Hostname);
  489. Hostname = strdup(argv[1]);
  490. }
  491. }
  492. return 0;
  493. }
  494. int
  495. dolog(argc,argv,p)
  496. int argc;
  497. char *argv[];
  498. void *p;
  499. {
  500. static char *logname;
  501. if(argc < 2){
  502. if(Logfp)
  503. printf("Logging to %sn",logname);
  504. else
  505. printf("Logging offn");
  506. return 0;
  507. }
  508. if(Logfp){
  509. logmsg(-1,"NOS log closed");
  510. fclose(Logfp);
  511. Logfp = NULL;
  512. free(logname);
  513. logname = NULL;
  514. }
  515. if(strcmp(argv[1],"stop") != 0){
  516. logname = strdup(argv[1]);
  517. Logfp = fopen(logname,APPEND_TEXT);
  518. logmsg(-1,"NOS was started at %s", ctime(&StartTime));
  519. }
  520. return 0;
  521. }
  522. int
  523. dohelp(argc,argv,p)
  524. int argc;
  525. char *argv[];
  526. void *p;
  527. {
  528. register struct cmds *cmdp;
  529. int i;
  530. char buf[66];
  531. printf("Main commands:n");
  532. memset(buf,' ',sizeof(buf));
  533. buf[64] = 'n';
  534. buf[65] = '';
  535. for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i = (i+1)%4){
  536. strncpy(&buf[i*16],cmdp->name,strlen(cmdp->name));
  537. if(i == 3){
  538. printf(buf);
  539. memset(buf,' ',sizeof(buf));
  540. buf[64] = 'n';
  541. buf[65] = '';
  542. }
  543. }
  544. if(i != 0)
  545. printf(buf);
  546. return 0;
  547. }
  548. /* Attach an interface
  549.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  550.  */
  551. int
  552. doattach(argc,argv,p)
  553. int argc;
  554. char *argv[];
  555. void *p;
  556. {
  557. return subcmd(Attab,argc,argv,p);
  558. }
  559. /* Manipulate I/O device parameters */
  560. int
  561. doparam(argc,argv,p)
  562. int argc;
  563. char *argv[];
  564. void *p;
  565. {
  566. register struct iface *ifp;
  567. int param;
  568. int32 val;
  569. if((ifp = if_lookup(argv[1])) == NULL){
  570. printf("Interface "%s" unknownn",argv[1]);
  571. return 1;
  572. }
  573. if(ifp->ioctl == NULL){
  574. printf("Not supportedn");
  575. return 1;
  576. }
  577. if(argc < 3){
  578. for(param=1;param<=16;param++){
  579. val = (*ifp->ioctl)(ifp,param,FALSE,0L);
  580. if(val != -1)
  581. printf("%s: %ldn",parmname(param),val);
  582. }
  583. return 0;
  584. }
  585. if((param = devparam(argv[2])) == -1){
  586. printf("Unknown parameter %sn",argv[2]);
  587. return 1;
  588. }
  589. if(argc < 4){
  590. /* Read specific parameter */
  591. val = (*ifp->ioctl)(ifp,param,FALSE,0L);
  592. if(val == -1){
  593. printf("Parameter %s not supportedn",argv[2]);
  594. } else {
  595. printf("%s: %ldn",parmname(param),val);
  596. }
  597. return 0;
  598. }
  599. /* Set parameter */
  600. (*ifp->ioctl)(ifp,param,TRUE,atol(argv[3]));
  601. return 0;
  602. }
  603. #ifndef MSDOS
  604. int
  605. doescape(argc,argv,p)
  606. int argc;
  607. char *argv[];
  608. void *p;
  609. {
  610. if(argc < 2)
  611. printf("0x%xn",Escape);
  612. else
  613. Escape = *argv[1];
  614. return 0;
  615. }
  616. #endif MSDOS
  617. /* Generate system command packet. Synopsis:
  618.  * remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
  619.  */
  620. int
  621. doremote(argc,argv,p)
  622. int argc;
  623. char *argv[];
  624. void *p;
  625. {
  626. struct sockaddr_in fsock;
  627. int s,c;
  628. uint8 *data,x;
  629. uint16 port,len;
  630. char *key = NULL;
  631. int klen;
  632. int32 addr = 0;
  633. char *cmd,*host;
  634. port = IPPORT_REMOTE; /* Set default */
  635. optind = 1; /* reinit getopt() */
  636. while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
  637. switch(c){
  638. case 'a':
  639. addr = resolve(optarg);
  640. break;
  641. case 'p':
  642. port = atoi(optarg);
  643. break;
  644. case 'k':
  645. key = optarg;
  646. klen = strlen(key);
  647. break;
  648. case 's':
  649. Rempass = strdup(optarg);
  650. return 0; /* Only set local password */
  651. }
  652. }
  653. if(optind > argc - 2){
  654. printf("Insufficient argsn");
  655. return -1;
  656. }
  657. host = argv[optind++];
  658. cmd = argv[optind];
  659. if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
  660. perror("socket failed");
  661. return 1;
  662. }
  663. len = 1;
  664. /* Did the user include a password or kickme target? */
  665. if(addr != 0)
  666. len += sizeof(int32);
  667. if(key != NULL)
  668. len += klen;
  669. if(len == 1)
  670. data = &x;
  671. else
  672. data = mallocw(len);
  673. fsock.sin_family = AF_INET;
  674. fsock.sin_addr.s_addr = resolve(host);
  675. fsock.sin_port = port;
  676. switch(cmd[0]){
  677. case 'r':
  678. data[0] = SYS_RESET;
  679. if(key != NULL)
  680. strncpy((char *)&data[1],key,klen);
  681. break;
  682. case 'e':
  683. data[0] = SYS_EXIT;
  684. if(key != NULL)
  685. strncpy((char *)&data[1],key,klen);
  686. break;
  687. case 'k':
  688. data[0] = KICK_ME;
  689. if(addr != 0)
  690. put32(&data[1],addr);
  691. break;
  692. default:
  693. printf("Unknown command %sn",cmd);
  694. goto cleanup;
  695. }
  696. /* Form the command packet and send it */
  697. if(sendto(s,data,len,0,(struct sockaddr *)&fsock,sizeof(fsock)) == -1){
  698. perror("sendto failed");
  699. goto cleanup;
  700. }
  701. cleanup:
  702. if(data != &x)
  703. free(data);
  704. close_s(s);
  705. return 0;
  706. }
  707. /* Execute a command with output piped to more */
  708. int
  709. dopage(argc,argv,p)
  710. int argc;
  711. char *argv[];
  712. void *p;
  713. {
  714. FILE *fp;
  715. FILE *outsav;
  716. fp = tmpfile();
  717. outsav = stdout;
  718. stdout = fp;
  719. subcmd(Cmds,argc,argv,p);
  720. stdout = outsav;
  721. newproc("view",512,view,0,(void *)fp,NULL,0); /* View closes fp */
  722. return 0;
  723. }
  724. /* Set kernel process debug flag */
  725. int
  726. dodebug(argc,argv,p)
  727. int argc;
  728. char *argv[];
  729. void *p;
  730. {
  731. setbool(&Kdebug,"kernel debug",argc,argv);
  732. return 0;
  733. }
  734. /* Set temp file wipe-on-close flag */
  735. int
  736. dowipe(argc,argv,p)
  737. int argc;
  738. char *argv[];
  739. void *p;
  740. {
  741. setbool(&_clrtmp,"tmp file wiping",argc,argv);
  742. return 0;
  743. }
  744. /* No-op command */
  745. int
  746. donothing(argc,argv,p)
  747. int argc;
  748. char *argv[];
  749. void *p;
  750. {
  751. return 0;
  752. }
  753. /* Log messages of the form
  754.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  755.  */
  756. void
  757. logmsg(int s,char *fmt, ...)
  758. {
  759. va_list ap;
  760. char *cp;
  761. long t;
  762. int i;
  763. struct sockaddr fsocket;
  764. #ifdef MSDOS
  765. int fd;
  766. #endif
  767. if(Logfp == NULL)
  768. return;
  769. time(&t);
  770. cp = ctime(&t);
  771. rip(cp);
  772. i = SOCKSIZE;
  773. fprintf(Logfp,"%s",cp);
  774. if(getpeername(s,&fsocket,&i) != -1)
  775. fprintf(Logfp," %s",psocket(&fsocket));
  776. fprintf(Logfp," - ");
  777. va_start(ap,fmt);
  778. vfprintf(Logfp,fmt,ap);
  779. va_end(ap);
  780. fprintf(Logfp,"n");
  781. fflush(Logfp);
  782. #ifdef MSDOS
  783. /* MS-DOS doesn't really flush files until they're closed */
  784. fd = fileno(Logfp);
  785. if((fd = dup(fd)) != -1)
  786. close(fd);
  787. #endif
  788. }