home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Online / DaytimeDemo / dayserv.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-04-08  |  4.0 KB  |  178 lines

  1. /*
  2.  *    dayserv.c
  3.  *
  4.  * server for tcp daytime service (Amiga® format)
  5.  *
  6.  * adapted from "UNIX Network Programming, Vol.1, 2nd Edition" by W. Richard Stevens
  7.  * for Amiga® OS with AmiTCP 4.x compatible network stacks
  8.  *
  9.  *    important changes:
  10.  *        · returns a "seconds.microseconds" format, not the unix standard format
  11.  *
  12.  * should work with any compiler:
  13.  *     · link additional startup routine "startup.c" for Maxon C/C++ only
  14.  *        · uses (small & fast) external routine SPrintF for Maxon C/C++ only
  15.  */
  16.  
  17. #include <pragma/exec_lib.h>
  18. #include <pragma/dos_lib.h>
  19. #include <pragma/intuition_lib.h>
  20. #include <pragma/socket_lib.h>
  21. #include <sys/socket.h>
  22. #include <string.h>
  23.  
  24.  
  25. #define DAYTIMEPORT    13
  26. #define LISTENQUEUE    5    /* this is a table entry - "5" means the predefined TCP/IP queue count ! */
  27.  
  28. #ifdef __MAXON__
  29. #define vsprintf(a,b,c) SPrintF(b,c,a)
  30. #else
  31. #include <stdio.h>
  32. #endif
  33.  
  34.  
  35. struct Library *SocketBase = NULL, *IntuitionBase = NULL;
  36.  
  37.  
  38. /* external assembler function */
  39. #ifdef __MAXON__
  40. void SPrintF(register __a0 STRPTR fmtstring, register __a1 APTR data, register __a3 UBYTE *buffer);
  41. #endif
  42.  
  43.  
  44. /* resource handling */
  45. BOOL openLib(void)
  46. {
  47.     BOOL rw = FALSE;
  48.     
  49.     SocketBase = OpenLibrary(SOCKETNAME, 4U);
  50.     IntuitionBase = OpenLibrary("intuition.library", 37U);
  51.     
  52.     if(SocketBase && IntuitionBase)
  53.     {
  54.         rw = TRUE;
  55.     }
  56.     
  57.     return(rw);
  58. }
  59.  
  60. void closeLib(void)
  61. {
  62.     CloseLibrary(IntuitionBase);
  63.     IntuitionBase = NULL;
  64.     
  65.     CloseLibrary(SocketBase);
  66.     SocketBase = NULL;
  67. }
  68.  
  69.  
  70. /* main function */
  71. LONG main(LONG argc, APTR argv)
  72. {
  73.     struct RDArgs *rdargs;
  74.     STRPTR tmpl = "PORT/N";
  75.     LONG arg[1] = {0L};
  76.     LONG rw;
  77.     int serviceport = DAYTIMEPORT;
  78.     
  79.     /* shell only - this is a learning demo */
  80.     if(argc)
  81.     {
  82.         /* get port number - usually 13 is already used */
  83.         rdargs = ReadArgs(tmpl, arg, NULL);
  84.         if(rdargs)
  85.         {
  86.             serviceport = arg[0] ? *((LONG *) arg[0]) : serviceport;
  87.         }
  88.         
  89.         /* open libraries */
  90.         if(openLib())
  91.         {
  92.             long listenfd, connfd;
  93.             struct sockaddr_in servaddr;
  94.             
  95.             /* create listener socket */
  96.             listenfd = socket(AF_INET, SOCK_STREAM, 0L);
  97.             if(listenfd >= 0L)
  98.             {
  99.                 /* specify service and interface */
  100.                 memset(&servaddr, 0L, sizeof(struct sockaddr_in));
  101.                 servaddr.sin_family            = AF_INET;
  102.                 servaddr.sin_port                = htons(serviceport);
  103.                 servaddr.sin_addr.s_addr    = htonl(INADDR_ANY);    /* sin_addr == s_addr */
  104.                 
  105.                 /* add our server to the port... */
  106.                 if(bind(listenfd, (const struct sockaddr *) &servaddr, sizeof(servaddr)) >= 0L)
  107.                 {
  108.                     /* ...and start listening for requests */
  109.                     if(listen(listenfd, LISTENQUEUE) >= 0L)
  110.                     {
  111.                         /* there is no normal exit from an endless loop, so RETURN_OK is never used */
  112.                         for(;;)
  113.                         {
  114.                             /* standard for()-loop emergency break */
  115.                             if(CheckSignal(SIGBREAKF_CTRL_C))
  116.                             {
  117.                                 PutStr("^C -- user break\n");
  118.                                 rw = RETURN_WARN;
  119.                                 break;
  120.                             }
  121.                             
  122.                             /* serve client - accept() has a ctrl_c handling itself */
  123.                             connfd = accept(listenfd, NULL, NULL);
  124.                             if(connfd >= 0L)
  125.                             {
  126.                                 char buf[20];
  127.                                 ULONG c[2];
  128.                                 
  129.                                 CurrentTime(&(c[0]), &(c[1]));
  130.                                 vsprintf(buf, "%10ld.%06ld\r\n", c);
  131.                                 
  132.                                 /* return timeval format (seconds.microseconds) */
  133.                                 send(connfd, buf, strlen(buf), 0L);
  134.                                 
  135.                                 /* the server closes the client connection */
  136.                                 CloseSocket(connfd);
  137.                             }
  138.                             else
  139.                             {
  140.                                 Printf("Error code %ld while receiving request\n", connfd);
  141.                             }
  142.                         }/* for() */
  143.                     }
  144.                     else
  145.                     {
  146.                         Printf("Could not start server on port %ld\n", serviceport);
  147.                         rw = RETURN_FAIL; 
  148.                     }
  149.                 }
  150.                 else
  151.                 {
  152.                     Printf("Could not reserve port %ld\n", serviceport);
  153.                     rw = RETURN_FAIL;
  154.                 }
  155.             }
  156.             else
  157.             {
  158.                 Printf("Error code %ld while opening network socket\n", listenfd);
  159.                 rw = RETURN_FAIL;
  160.             }
  161.             
  162.             closeLib();
  163.         }
  164.         else
  165.         {
  166.             Printf(    "Error opening \"%s\" version %ld\n"
  167.                         "You must start AmiTCP 4.x, or a compatible TCP/IP stack\n",
  168.                          SOCKETNAME, 4L);
  169.             
  170.             rw = RETURN_FAIL;
  171.         }
  172.         
  173.         FreeArgs(rdargs);
  174.     }
  175.     
  176.     return(rw);
  177. }
  178.