home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / internet / socketfs_2 / C / Nameproc next >
Encoding:
Text File  |  1997-09-07  |  10.0 KB  |  397 lines

  1. /***************************************************************************/
  2. /* Program       : SocketFS                                                */
  3. /* Purpose       : Treat Internet sockets as file streams                  */
  4. /* File          : Nameproc.c                                              */
  5. /* Author        : R G Gammans                                             */
  6. /* Date Created  : 04-07-97                                                */
  7. /* Last Edited   : 07-09-97                                                */
  8. /*                                                                         */
  9. /* Copyright Date: July 1997 (C) R G Gammans                               */
  10. /*                                                                         */
  11. /***************************************************************************/
  12. /*
  13.  *   SocketFS - BSD sockets filing system for RISC-OS.
  14.  *   Copyright (C) 1997 Roger G Gammans
  15.  *
  16.  *   This program is free software; you can redistribute it and/or modify
  17.  *   it under the terms of the GNU General Public License as published by
  18.  *   the Free Software Foundation; either version 2 of the License, or
  19.  *   (at your option) any later version.
  20.  *
  21.  *
  22.  *   This program is distributed in the hope that it will be useful,
  23.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  24.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25.  *   GNU General Public License for more details.
  26.  *
  27.  *   You should have received a copy of the GNU General Public License
  28.  *   along with this program; if not, write to the Free Software
  29.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  30.  *
  31.  *   Author: R Gammans <rgammans@compsurg,demon.co.uk>
  32.  *   Snailmail  : 20 Trenches Rd, Crowborough, E Sussex, TN6 1ES UK.
  33.  */
  34.  
  35.  
  36. #include <stdio.h>
  37. #include <sys/param.h>
  38. #include <sys/file.h>
  39. #include <sys/stat.h>
  40. #include <sys/socket.h>
  41. #include <sys/ioctl.h>
  42. #include <sys/un.h>
  43. #include <netinet/in.h>
  44. #include <netdb.h>
  45. #include <pwd.h>
  46. #include <sys/syslog.h>
  47. #include <sys/wait.h>
  48. #include <sgtty.h>
  49. #include <ctype.h>
  50. #include <errnum.h>
  51. #include <string.h>
  52.  
  53. #ifndef FIOMODE
  54. #define FIOMODE FIOSLEEPTW
  55. #endif
  56.  
  57. #ifdef DEBUG
  58. #include "trackerlib.h"
  59. #endif
  60.  
  61.  
  62.  /*
  63.   * Most the code in here is pretty naff but it works.
  64.   *
  65.   * At some point this lot may as well be re-written in asm,
  66.   * which will remove our dependendcy on stubs/sharedclib.
  67.   *
  68.   * Also the exceutable will drop in size considerably
  69.   */
  70. typedef
  71.   struct {
  72.          int   addr_family;
  73.          int   proto_family;
  74.  
  75.          char* special_field;
  76.          int (*makesocket)(char* fname);
  77.  
  78.           } Thandler_struct;
  79.  
  80.  
  81. typedef
  82.   struct TS_hand {
  83.           Thandler_struct *data;
  84.           struct TS_hand *next;
  85.          } Thandler_list;
  86.  
  87. Thandler_list *handler_list_root;
  88. char* errstr;
  89.  
  90. Thandler_struct IPhandler,fdhandler;
  91. Thandler_list   IPouter,fdouter;
  92.  
  93.  
  94.  
  95. int makeInetStream(char* filename);
  96. int sock2fd(char* filename);
  97.  
  98. void inithandlerlist()
  99.   {
  100.     IPhandler.special_field="IPv4";
  101.     IPhandler.makesocket=makeInetStream;
  102.     fdhandler.special_field="s2fd";
  103.     fdhandler.makesocket=sock2fd;
  104.     IPouter.data=&IPhandler;
  105.     IPouter.next=&fdouter;
  106.     fdouter.data=&fdhandler;
  107.     fdouter.next=NULL;
  108.     handler_list_root=&IPouter;
  109.   }
  110.  
  111. int  makeSocket(char* specialfield,char* filename)
  112.   {
  113.     int             a_socket;
  114.     Thandler_list   *traversee;
  115.     int             found;
  116.  
  117.     if (!specialfield)
  118.       {
  119.         /*Default AF_INET*/
  120.         specialfield="IPv4";
  121.  
  122. #ifdef DEBUG
  123. tracker_simple(" - special reset to \"IPv4\" (or is it)\n");
  124. #endif
  125.       };
  126.  
  127.     traversee=handler_list_root;
  128.     found=0;
  129.     while ((traversee!=NULL) && !found) {
  130.       found=!strcmp(specialfield,traversee->data->special_field);
  131.        if (traversee!=NULL && !found) {
  132.          traversee=traversee->next;
  133.        }
  134.     }
  135.  
  136.     if (!found)
  137.       {
  138.          /*File not found..      */
  139.         a_socket=-1;
  140.       }
  141.       else
  142.       {
  143. #ifdef DEBUG
  144. tracker_simple("About the call makesocket for af..\n");
  145. #endif
  146.         a_socket=traversee->data->makesocket(filename);
  147.       }
  148.  
  149.     return a_socket;
  150.   }
  151.  
  152.  
  153. int makeInetStream(char* filename)
  154.  {
  155.    /* The aim here is two extract protocol over which where opening the
  156.     * connection. (assuming ICMP/TCP/UDP.)
  157.     * We also need to extract the host:port designation of both ends.
  158.     *
  159.     * We do this by processing each directory in turn.
  160.     * eg. socket#IPv4::Tcp.$.www/demon/co/uk\80        -Talk to a Httpd - from any port.
  161.     *    socket#IPv4::Tcp.$.192/168/0/3\515.auto\768  -Talk to my lpd server.. from a resvered port
  162.     */
  163.  
  164.    char   *section,*divisor,*serv,*tmpptr;
  165.    char   proto[99],lcl_host[255],lcl_serv[255],rem_host[255],rem_serv[255];
  166.    struct hostent *hp;
  167.    struct servent *sp;
  168.    struct sockaddr_in sin,sout;
  169.    int    s;
  170.    char   olddiv;
  171.    int    one =1;
  172.  
  173.    section=strstr(filename,":"); /*Should be 1st char */
  174.    divisor=strstr(filename,".$.");
  175.    if (!divisor)
  176.      return -1;
  177.  
  178.    *divisor='\0';
  179.    strcpy(proto,section+1);
  180. #ifdef DEBUG
  181.    tracker_printf("Protocol = %s\n",proto);
  182. #endif
  183.    *divisor='.';
  184.    section=divisor+3;
  185.  
  186.    serv=strstr(section,"\\");
  187.    divisor=strstr(section,".");
  188.  
  189.    if ((divisor) && (divisor<serv) || !serv)
  190.      {
  191.       /*
  192.        * We must have both a port and a host at the
  193.        * remote end.
  194.        */
  195.  
  196.       return -1;
  197.      }
  198.      else
  199.      {
  200.       /* '\' in the remote part*/
  201.  
  202.        if (divisor) {
  203.          olddiv= *divisor;
  204.          *divisor='\0';
  205.        }
  206.        strcpy(rem_serv,serv+1);
  207.        if (divisor)
  208.           *divisor=olddiv;
  209. #ifdef DEBUG
  210.    tracker_printf("Remote port name = %s\n",rem_serv);
  211. #endif
  212.        olddiv=*serv;
  213.        *serv='\0';
  214.        strcpy(rem_host,section);
  215.        *serv=olddiv;
  216. #ifdef DEBUG
  217.    tracker_printf("Remote host part = %s\n",rem_host);
  218. #endif
  219.       /* Do '.' and '/' replacement. */
  220.  
  221.        tmpptr=rem_host;
  222.        while (*tmpptr!='\0') {
  223.          if (*tmpptr=='/')
  224.            {
  225.              *tmpptr='.';
  226.            }
  227.          tmpptr++;
  228.        }
  229. #ifdef DEBUG
  230.    tracker_printf("Remote host = %s\n",rem_host);
  231. #endif
  232.        hp=gethostbyname(rem_host);
  233.        if (hp == NULL) {
  234.          errstr="Can't find remote interface\n";
  235.          return -1;
  236.        }
  237.  
  238.        bzero((char *)&sin, sizeof(sin));
  239.        bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
  240.        sin.sin_family= hp->h_addrtype;
  241.        sin.sin_port=htons(atoi(rem_serv));
  242.  
  243.        /* There is an implicit assumation here that our hosts */
  244.        /* and network representations of 0 are the same       */
  245.        /* This will be true for all big & little endian       */
  246.        /* machines, which use 2's complement                  */
  247.        if (sin.sin_port==0) {
  248.          sp=getservbyname(rem_serv,proto);
  249.          if (sp == NULL) {
  250.            errstr="Can't resolve remote service\n";
  251.            return -1;
  252.           }
  253.          sin.sin_port  = sp->s_port;
  254.         }
  255. #ifdef DEBUG
  256. tracker_printf("Remote port no = %d\n",ntohs(sin.sin_port));
  257. #endif
  258.        }
  259.  
  260.      if (*divisor=='\0')
  261.       {
  262. #ifdef DEBUG
  263. tracker_simple("Creating socket... ");
  264. #endif
  265.         s=socket(AF_INET,SOCK_STREAM,0);
  266. #ifdef DEBUG
  267. tracker_simple("done\n");
  268. #endif
  269.         if (s==-1) return s;
  270.       }
  271.       else
  272.       {
  273.        section=divisor+1;
  274.        serv=strstr(section,"\\");
  275.  
  276.        if (!serv)
  277.          {
  278.          /*
  279.           * No '\' in local part....
  280.           * Currently we ignore all then!
  281.           */
  282.  
  283.          s=socket(AF_INET,SOCK_STREAM,0);
  284.          }
  285.  
  286.          else
  287.          {
  288.          /* '\' in the local part */
  289. #ifdef DEBUG
  290. tracker_printf("local port specified - %s\n",section);
  291. #endif
  292.  
  293.           *divisor='\0';
  294.           strcpy(lcl_serv,serv+1);
  295.  
  296. #ifdef DEBUG
  297.    tracker_printf("Local port name = %s\n",lcl_serv);
  298. #endif
  299.           *serv='\0';
  300.           strcpy(lcl_host,section);
  301.  
  302. #ifdef DEBUG
  303.    tracker_printf("Local Host part = %s\n",lcl_host);
  304. #endif
  305.           /*Do '.' and '/' replacement.*/
  306.           tmpptr=lcl_host;
  307.           while (*tmpptr=='\0') {
  308.             if (*tmpptr=='/')
  309.               {
  310.                 *tmpptr='.';
  311.               }
  312.           }
  313.  
  314. #ifdef DEBUG
  315.    tracker_printf("Local host = %s\n",lcl_host);
  316. #endif
  317.           if (!strcmp(lcl_host,"auto")) {
  318.             gethostname(lcl_host,sizeof(lcl_host));
  319.             lcl_host[sizeof(lcl_host)-1]='\0';
  320.           }
  321.  
  322.           hp=gethostbyname(lcl_host);
  323.           if (hp == NULL) {
  324.             errstr="Can't find local interface\n";
  325.             return -1;
  326.           }
  327.  
  328.           s=socket(AF_INET,SOCK_STREAM,0);
  329.           if (s==-1) return s;
  330.  
  331.           bzero((char *)&sout, sizeof(sout));
  332.           bcopy(hp->h_addr, (caddr_t)&sout.sin_addr, hp->h_length);
  333.           sout.sin_family= hp->h_addrtype;
  334. #ifdef DEBUG
  335. tracker_printf("Local i/f  = %s\n",lcl_host);
  336. #endif
  337.  
  338.           if (strcmp(lcl_serv,"auto")) {
  339.             sout.sin_port=htons(atoi(lcl_serv));
  340.  
  341.        /* There is an implicit assumation here that our hosts */
  342.        /* and the network representations of 0 are the same   */
  343.        /* This will be true for all big & little endian       */
  344.        /* machines, which use 2's complement.                 */
  345.             if (sout.sin_port==0) {
  346.               sp=getservbyname(lcl_serv,proto);
  347.               if (sp == NULL) {
  348.                 errstr="Can't resolve local service\n";
  349.                 return -1;
  350.                }
  351.               sout.sin_port  = sp->s_port;
  352.             }
  353.           }
  354. #ifdef DEBUG
  355. tracker_printf("Remote port no = %d\n",ntohs(sin.sin_port));
  356. #endif
  357.  
  358. #ifdef DEBUG
  359. tracker_simple("trying to bind socket .... ");
  360. #endif
  361.             if (bind(s,&sout,sizeof(sout))==-1) return -1;
  362. #ifdef DEBUG
  363. tracker_simple("done\n");
  364. #endif
  365.  
  366.  
  367.          }
  368.       }
  369.     ioctl(s,FIOMODE,&one);
  370. #ifdef DEBUG
  371. tracker_simple("trying to connect .... ");
  372. #endif
  373.     if (connect(s,&sin,sizeof(sin))==-1) return -1;
  374. #ifdef DEBUG
  375. tracker_simple("done\n");
  376. #endif
  377.     return s;
  378.  }
  379.  
  380.  
  381. int sock2fd(char* filename)
  382.  {
  383.    char *flags,*desc;
  384.  
  385.    flags=strstr(filename,":"); /*Should be 1st char */
  386.    desc=strstr(filename,".$.");
  387.    if (!desc)
  388.      return -1;
  389.    if isdigit(desc[3])
  390.    {
  391.      return atoi(desc[3]);
  392.    }
  393.  
  394.    return -1;
  395.    /*We ignore the meaning of the flags section currently */
  396.  }
  397.