home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 February / PCWorld_2003-02_cd.bin / Komunik / sambar / sambar53b3.exe / samples / source / netutils.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-07-15  |  12.7 KB  |  590 lines

  1. /*
  2. ** NETUTILS
  3. **
  4. **      HTTP Wrapper for some basic Network Utilities
  5. **        (Not yet ported to UNIX)
  6. **
  7. **        Confidential Property of Tod Sambar
  8. **        (c) Copyright Tod Sambar 1997
  9. **        All rights reserved.
  10. **
  11. **
  12. ** Public Functions:
  13. **
  14. **        netutils_init
  15. **        ipname_lookup
  16. **        ipname_scalar
  17. **        whois_lookup
  18. **        finger_lookup
  19. **
  20. **
  21. ** History:
  22. ** Chg#    Date    Description                                                Resp
  23. ** ----    -------    -------------------------------------------------------    ----
  24. **         2FEB97    Created                                                    sambar
  25. */
  26.  
  27. #include    <stdio.h>
  28. #include    <memory.h>
  29. #include    <string.h>
  30. #include    <stdlib.h>
  31. #ifdef    WIN32
  32. #include    <winsock.h>
  33. #include    <direct.h>
  34. #endif    /* WIN32 */
  35. #include    <errno.h>
  36. #include    <netutils.h>
  37.  
  38. /*
  39. ** WHOIS defines
  40. */
  41. #define WHOIS_PORT        43
  42. #define WHOIS_SERVER    "198.41.0.6"        /* rs.internic.net */
  43.  
  44. /*
  45. ** Network Utility RPC Commands
  46. */
  47. typedef struct netutils__rpcs
  48. {
  49.     SA_CHAR        *name;
  50.     SA_RPCPARAM    *params;
  51.     SA_INT        numparams;
  52.     SA_INT        auth;
  53.     SA_VOID        *func;
  54.     SA_CHAR        *descr;
  55. } NETUTILS__RPCS;
  56.  
  57. static SA_RPCPARAM        ipnamep [] =
  58. {
  59.     { "ipaddr",        1,    "IP Address to lookup." }
  60. };
  61. static SA_RPCPARAM        whoisp [] =
  62. {
  63.     { "sitename",    1,    "Site name to lookup." },
  64.     { "nameserver",    0,    "Name server to use (rs.internic.net is default)" }
  65. };
  66. static SA_RPCPARAM        fingerp [] =
  67. {
  68.     { "user",        0,    "User name to lookup (may be NULL)." },
  69.     { "host",        1,    "Site to lookup user on (must have finger daemon)." }
  70. };
  71.  
  72. static NETUTILS__RPCS     netutils_rpcs [] =
  73. {
  74.     { "ipname",        ipnamep,    sizeof(ipnamep) / sizeof(SA_RPCPARAM),
  75.       SA_AUTHORIZATION_SCRIPT,    (SA_VOID *)ipname_lookup,
  76.       "Lookup the DNS name associated with an IP address." },
  77.     { "whois",        whoisp,        sizeof(ipnamep) / sizeof(SA_RPCPARAM),
  78.       SA_AUTHORIZATION_SCRIPT,    (SA_VOID *)whois_lookup,
  79.       "Perform a whois lookup given a network domain name." },
  80.     { "finger",        fingerp,        sizeof(fingerp) / sizeof(SA_RPCPARAM),
  81.       SA_AUTHORIZATION_SCRIPT,    (SA_VOID *)finger_lookup,
  82.       "Perform a finger lookup given a user and host." }
  83. };
  84.  
  85. /*
  86. ** Network Scalar Methods
  87. */
  88. typedef struct netutils__scalars
  89. {
  90.     SA_CHAR            *name;
  91.     SA_SCALARARG    *args;
  92.     SA_INT            numargs;
  93.     SA_VOID            *func;
  94.     SA_CHAR            *descr;
  95. } NETUTILS__SCALARS;
  96.  
  97. static SA_SCALARARG    ipscalarp [] =
  98. {
  99.     { "ipaddr",     "IP Address to lookup." }
  100. };
  101.  
  102. static NETUTILS__SCALARS netutils_scalars [] =
  103. {
  104.     { "ipname",    ipscalarp,        sizeof(ipscalarp)/sizeof(SA_SCALARARG),
  105.       (SA_VOID *)ipname_scalar,
  106.       "Lookup the DNS name associated with an IP address." },
  107. };
  108.  
  109.  
  110. /*
  111. **  NETUTILS_INIT
  112. **
  113. **    Initialize the Network Utilities.
  114. **
  115. **  Parameters:
  116. **    sactx        Sambar Server context
  117. **
  118. **  Returns:
  119. **    SA_SUCCEED | SA_FAIL
  120. */
  121. SA_RETCODE SA_PUBLIC
  122. netutils_init(sactx)
  123. SA_CTX        *sactx;
  124. {
  125.     int            i;
  126.  
  127.     /* Register the Network Uitlities RPCs with the application            */
  128.     for (i = 0; i < sizeof(netutils_rpcs) / sizeof(NETUTILS__RPCS); i++)
  129.     {
  130.         if (sa_cmd_init(sactx, netutils_rpcs[i].name, 
  131.             netutils_rpcs[i].params, netutils_rpcs[i].numparams,
  132.             netutils_rpcs[i].auth, netutils_rpcs[i].descr, 
  133.             (SA_RPCFUNC)netutils_rpcs[i].func) != SA_SUCCEED)
  134.         {
  135.             sa_log2(sactx, SA_LOG_ERROR,
  136.                 "Unable to initialize Network Utility RPCs");
  137.             return (SA_FAIL);
  138.         }
  139.     } 
  140.  
  141.     /* Register the Scalar methods with the server                        */
  142.     for (i = 0; i < sizeof(netutils_scalars) / sizeof(NETUTILS__SCALARS); i++)
  143.     {
  144.         if (sa_scalar_init(sactx, netutils_scalars[i].name, 
  145.             netutils_scalars[i].args, netutils_scalars[i].numargs, 
  146.             netutils_scalars[i].descr, netutils_scalars[i].func) != SA_SUCCEED)
  147.         {
  148.             sa_log2(sactx, SA_LOG_ERROR,
  149.                 "Unable to initialize Network Utility Scalars");
  150.             return (SA_FAIL);
  151.         } 
  152.     }
  153.  
  154.     sa_log2(sactx, SA_LOG_TRACE, "Network Utilities Initialized");
  155.  
  156.     return (SA_SUCCEED);
  157. }
  158.  
  159. /*
  160. **  IPNAME_LOOKUP
  161. **
  162. **    Get the host name associated with an IP address.
  163. **
  164. **  Parameters:
  165. **    sactx        Sambar Server context
  166. **    saconn        Sambar Server connection
  167. **    saparams    RPC Parameters
  168. **    infop        Error parameters
  169. **
  170. **  Returns:
  171. **    SA_SUCCEED | SA_FAIL
  172. */
  173. SA_RETCODE SA_PUBLIC
  174. ipname_lookup(sactx, saconn, saparams, infop)
  175. SA_CTX        *sactx;
  176. SA_CONN        *saconn;
  177. SA_PARAMS    *saparams;
  178. SA_INT        *infop;
  179. {
  180. #ifndef    WIN32
  181.     return (SA_FAIL);
  182. #else
  183.     unsigned long    addr;
  184.     SA_INT            datalen;
  185.     SA_CHAR            *data;
  186.     struct hostent    *hent;
  187.  
  188.     /* Get the ip address to lookup                                        */
  189.     if ((sa_param(sactx, saparams, "ipaddr", &data, &datalen) != SA_SUCCEED) 
  190.         || (datalen == 0) || (datalen > 255))
  191.     {
  192.         *infop = SA_E_INVALIDDATA;
  193.         return (SA_FAIL);
  194.     }
  195.  
  196.     addr = (int)inet_addr((char *)data);
  197.     if (addr == -1)
  198.     {
  199.         *infop = SA_E_INVALIDDATA;
  200.         return (SA_FAIL);
  201.     }
  202.  
  203.     hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
  204.     if (hent != NULL)
  205.     {
  206.         if (sa_conn_send(saconn, hent->h_name, SA_NULLTERM) != SA_SUCCEED)
  207.             return (SA_FAIL);
  208.     }
  209.     else
  210.     {
  211.         if (sa_conn_send(saconn, "unknown", SA_NULLTERM) != SA_SUCCEED)
  212.             return (SA_FAIL);
  213.     }
  214.  
  215.     return (SA_SUCCEED);
  216. #endif    /* WIN32 */
  217. }
  218.  
  219. /*
  220. **  WHOIS_LOOKUP
  221. **
  222. **    Perform a whois search.
  223. **
  224. **  Parameters:
  225. **    sactx        Sambar Server context
  226. **    saconn        Sambar Server connection
  227. **    saparams    RPC Parameters
  228. **    infop        Error parameters
  229. **
  230. **  Returns:
  231. **    SA_SUCCEED | SA_FAIL
  232. */
  233. SA_RETCODE SA_PUBLIC
  234. whois_lookup(sactx, saconn, saparams, infop)
  235. SA_CTX        *sactx;
  236. SA_CONN        *saconn;
  237. SA_PARAMS    *saparams;
  238. SA_INT        *infop;
  239. {
  240. #ifndef    WIN32
  241.     return (SA_FAIL);
  242. #else    
  243.     int                    timeo;
  244.     SA_INT                buflen;
  245.     SA_INT                datalen;
  246.     SA_BOOL                finished;
  247.     SOCKET                sock;
  248.     unsigned long        addr;
  249.     SA_CHAR                *data;
  250.     SA_CHAR                *nameserver;
  251.     struct sockaddr_in    sin;
  252.     struct hostent        *hent;
  253.     SA_CHAR                buffer[1024];
  254.  
  255.     /* Get the (optional) name server to use.                            */
  256.     datalen = 0;
  257.     (void)sa_param(sactx, saparams, "nameserver", &data, &datalen);
  258.     if ((datalen > 0) && (datalen < 255))
  259.         nameserver = data;
  260.     else
  261.         nameserver = WHOIS_SERVER;
  262.  
  263.     /* Get the site name                                                */
  264.     if ((sa_param(sactx, saparams, "sitename", &data, &datalen) != SA_SUCCEED)
  265.         || (datalen == 0) || (datalen > 255))
  266.     {
  267.         *infop = SA_E_INVALIDDATA;
  268.         return (SA_FAIL);
  269.     }
  270.  
  271.     /* Get the WHOIS server address for the query                        */
  272.     addr = (int)inet_addr(nameserver);
  273.     if (addr == -1)
  274.     {
  275.         /* Try gethostbyname()                                            */
  276.         hent = gethostbyname(nameserver);
  277.         if (hent == NULL)
  278.         {
  279.             *infop = SA_E_INVALIDDATA;
  280.             return (SA_FAIL);
  281.         }
  282.  
  283.         addr = (int)hent->h_addr;
  284.     }
  285.  
  286.     hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
  287.     if (hent == NULL)
  288.     {
  289.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  290.             SA_NULLTERM) != SA_SUCCEED)
  291.         {
  292.             return (SA_FAIL);
  293.         }
  294.  
  295.         return (SA_SUCCEED);
  296.     }
  297.  
  298.     /* Create a socket                                                     */
  299.     sock = socket(hent->h_addrtype, SOCK_STREAM, 0);
  300.     if (sock == INVALID_SOCKET)
  301.     {
  302.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  303.             SA_NULLTERM) != SA_SUCCEED)
  304.         {
  305.             return (SA_FAIL);
  306.         }
  307.  
  308.         return (SA_SUCCEED);
  309.     }
  310.  
  311.     /* Connect to the WHOIS server                                        */
  312.     sin.sin_family = AF_INET;
  313.     sin.sin_port = htons((u_short)WHOIS_PORT);
  314.     memcpy(&sin.sin_addr, hent->h_addr, hent->h_length);
  315.  
  316.     /* Now, connect to that WHOIS server                                */
  317.     if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) 
  318.     {
  319.         closesocket(sock);
  320.  
  321.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  322.             SA_NULLTERM) != SA_SUCCEED)
  323.         {
  324.             return (SA_FAIL);
  325.         }
  326.  
  327.         return (SA_SUCCEED);
  328.     }
  329.  
  330.      /* Set the socket recv timeout to 10 seconds            */
  331.      timeo = 10000;
  332.      (void)setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeo,
  333.          sizeof(int));
  334.  
  335.     /* Send the request.                                                */
  336.     sprintf(buffer, "%s\r\n", data);
  337.     buflen = strlen(buffer);
  338.  
  339.     if (send(sock, buffer, buflen, 0) != buflen)
  340.     {
  341.         closesocket(sock);
  342.  
  343.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  344.             SA_NULLTERM) != SA_SUCCEED)
  345.         {
  346.             return (SA_FAIL);
  347.         }
  348.  
  349.         return (SA_SUCCEED);
  350.     }
  351.  
  352.     /* Receive the response.                                            */
  353.     finished = 0;
  354.     while (!finished)
  355.     {
  356.         buflen = recv(sock, buffer, 1024, 0);
  357.         if ((buflen < 0) && (errno == EINTR))
  358.             continue;
  359.  
  360.         if (buflen == SOCKET_ERROR)
  361.         {
  362.             closesocket(sock);
  363.             return (SA_FAIL);
  364.         }
  365.  
  366.         if (buflen > 0)
  367.         {
  368.             if (sa_conn_send(saconn, buffer, buflen) != SA_SUCCEED)
  369.             {
  370.                 closesocket(sock);
  371.                 return (SA_FAIL);
  372.             }
  373.         }
  374.         else
  375.         {
  376.             finished = 1;
  377.         }
  378.     }
  379.  
  380.     closesocket(sock);
  381.  
  382.     if (!finished)
  383.     {
  384.         if (sa_conn_send(saconn, "The WHOIS server is not available.", 
  385.             SA_NULLTERM) != SA_SUCCEED)
  386.         {
  387.             return (SA_FAIL);
  388.         }
  389.     }
  390.  
  391.     return (SA_SUCCEED);
  392. #endif    /* WIN32 */
  393. }
  394.  
  395. /*
  396. **  FINGER_LOOKUP
  397. **
  398. **    Perform a 'finger' search.
  399. **
  400. **  Parameters:
  401. **    sactx        Sambar Server context
  402. **    saconn        Sambar Server connection
  403. **    saparams    RPC Parameters
  404. **    infop        Error parameters
  405. **
  406. **  Returns:
  407. **    SA_SUCCEED | SA_FAIL
  408. */
  409. SA_RETCODE SA_PUBLIC
  410. finger_lookup(sactx, saconn, saparams, infop)
  411. SA_CTX        *sactx;
  412. SA_CONN        *saconn;
  413. SA_PARAMS    *saparams;
  414. SA_INT        *infop;
  415. {
  416. #ifndef    WIN32
  417.     return (SA_FAIL);
  418. #else
  419.     int                    timeo;
  420.     SA_INT                buflen;
  421.     SA_INT                userlen;
  422.     SA_INT                hostlen;
  423.     SA_BOOL                finished;
  424.     SOCKET                sock;
  425.     SA_CHAR                *host;
  426.     SA_CHAR                *user;
  427.     struct sockaddr_in    sin;
  428.     struct hostent        *hent;
  429.     SA_CHAR                buffer[1024];
  430.  
  431.     /* Get the host where the finger server is running                    */
  432.     if ((sa_param(sactx, saparams, "host", &host, &hostlen) != SA_SUCCEED)
  433.         || (hostlen == 0) || (hostlen > 255))
  434.     {
  435.         *infop = SA_E_INVALIDDATA;
  436.         return (SA_FAIL);
  437.     }
  438.  
  439.     (void)sa_param(sactx, saparams, "user", &user, &userlen);
  440.  
  441.     /* Get the finger server address                                */
  442.     hent = gethostbyname(host);
  443.     if (hent == NULL)
  444.     {
  445.         sprintf(buffer, "Unable to locate the specified host: '%s'", host);
  446.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  447.             return (SA_FAIL);
  448.  
  449.         return (SA_SUCCEED);
  450.     }
  451.  
  452.     /* Open a socket                                                     */
  453.     sock = socket(PF_INET, SOCK_STREAM, 0);
  454.     if (sock == INVALID_SOCKET)
  455.     {
  456.         if (sa_conn_send(saconn, "Unable to create a new TCP/IP socket.", 
  457.             SA_NULLTERM) != SA_SUCCEED)
  458.         {
  459.             return (SA_FAIL);
  460.         }
  461.  
  462.         return (SA_SUCCEED);
  463.     }
  464.  
  465.     /* Connect to the finger server                                        */
  466.     sin.sin_family = AF_INET;
  467.     sin.sin_port = htons((u_short)IPPORT_FINGER);
  468.     memcpy(&sin.sin_addr, hent->h_addr, hent->h_length);
  469.  
  470.     /* Now, connect to that WHOIS server                                */
  471.     if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) 
  472.     {
  473.         closesocket(sock);
  474.         sprintf(buffer, "Unable to connect to the host: '%s'", host);
  475.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  476.             return (SA_FAIL);
  477.  
  478.         return (SA_SUCCEED);
  479.     }
  480.  
  481.      /* Set the socket recv timeout to 10 seconds            */
  482.      timeo = 10000;
  483.      (void)setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeo,
  484.          sizeof(int));
  485.  
  486.     /* Send the request.                                                */
  487.     sprintf(buffer, "%s\r\n", (userlen > 0 && userlen < 255) ? user : "");
  488.     buflen = strlen(buffer);
  489.  
  490.     if (send(sock, buffer, buflen, 0) != buflen)
  491.     {
  492.         closesocket(sock);
  493.  
  494.         sprintf(buffer, "Failure connecting to finger daemon at: '%s'", host);
  495.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  496.             return (SA_FAIL);
  497.  
  498.         return (SA_SUCCEED);
  499.     }
  500.  
  501.     /* Receive the response.                                            */
  502.     finished = 0;
  503.     while (!finished)
  504.     {
  505.         buflen = recv(sock, buffer, 1024, 0);
  506.         if ((buflen < 0) && (errno == EINTR))
  507.             continue;
  508.  
  509.         if (buflen == SOCKET_ERROR)
  510.         {
  511.             closesocket(sock);
  512.             return (SA_FAIL);
  513.         }
  514.  
  515.         if (buflen > 0)
  516.         {
  517.             if (sa_conn_send(saconn, buffer, buflen) != SA_SUCCEED)
  518.             {
  519.                 closesocket(sock);
  520.                 return (SA_FAIL);
  521.             }
  522.         }
  523.         else
  524.         {
  525.             finished = 1;
  526.         }
  527.     }
  528.  
  529.     closesocket(sock);
  530.  
  531.     if (!finished)
  532.     {
  533.         sprintf(buffer, "Finger daemon at host '%s' is not available.", host);
  534.         if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
  535.             return (SA_FAIL);
  536.     }
  537.  
  538.     return (SA_SUCCEED);
  539. #endif    /* WIN32 */
  540. }
  541.  
  542. /*
  543. **  IPNAME_SCALAR
  544. **
  545. **    Scalar to retrieve the IP address associated with a host name.
  546. **
  547. **    Usage:    <RC@ipname(host)>
  548. **
  549. **  Parameters:
  550. **    sactx        Sambar Server context
  551. **    saconn        Sambar Server connection
  552. **    saargs        Scalar arguments
  553. **    value        Result buffer (maximum 1000 bytes).
  554. **
  555. **  Returns:
  556. **    SA_SUCCEED | SA_FAIL
  557. */
  558. SA_RETCODE SA_PUBLIC
  559. ipname_scalar(sactx, saconn, filename, saargs, value)
  560. SA_CTX        *sactx;
  561. SA_CONN        *saconn;
  562. SA_CHAR        *filename;
  563. SA_ARG        *saargs;
  564. SA_CHAR        *value;
  565. {
  566. #ifndef    WIN32
  567.     return (SA_FAIL);
  568. #else
  569.     unsigned long    addr;
  570.     SA_CHAR            *data;
  571.     struct hostent    *hent;
  572.  
  573.     data = saargs->value;
  574.     if (data == NULL)
  575.         return (SA_FAIL);
  576.  
  577.     addr = (int)inet_addr((char *)data);
  578.     if (addr == -1)
  579.         return (SA_FAIL);
  580.  
  581.     hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
  582.     if (hent != NULL)
  583.         strcpy(value, hent->h_name);
  584.     else
  585.         strcpy(value, "unknown");
  586.  
  587.     return (SA_SUCCEED);
  588. #endif    /* WIN32 */
  589. }
  590.