The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ip/chandial.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include        "u.h"
    2 #include        "../port/lib.h"
    3 #include        "mem.h"
    4 #include        "dat.h"
    5 #include        "fns.h"
    6 #include        "../port/error.h"
    7 #include        "../ip/ip.h"
    8 
    9 typedef struct DS DS;
   10 static Chan*    call(char*, char*, DS*);
   11 static void     _dial_string_parse(char*, DS*);
   12 
   13 enum
   14 {
   15         Maxstring=      128,
   16 };
   17 
   18 struct DS
   19 {
   20         char    buf[Maxstring];                 /* dist string */
   21         char    *netdir;
   22         char    *proto;
   23         char    *rem;
   24         char    *local;                         /* other args */
   25         char    *dir;
   26         Chan    **ctlp;
   27 };
   28 
   29 /*
   30  *  the dialstring is of the form '[/net/]proto!dest'
   31  */
   32 Chan*
   33 chandial(char *dest, char *local, char *dir, Chan **ctlp)
   34 {
   35         DS ds;
   36         char clone[Maxpath];
   37 
   38         ds.local = local;
   39         ds.dir = dir;
   40         ds.ctlp = ctlp;
   41 
   42         _dial_string_parse(dest, &ds);
   43         if(ds.netdir == 0)
   44                 ds.netdir = "/net";
   45 
   46         /* no connection server, don't translate */
   47         snprint(clone, sizeof(clone), "%s/%s/clone", ds.netdir, ds.proto);
   48         return call(clone, ds.rem, &ds);
   49 }
   50 
   51 static Chan*
   52 call(char *clone, char *dest, DS *ds)
   53 {
   54         int n;
   55         Chan *dchan, *cchan;
   56         char name[Maxpath], data[Maxpath], *p;
   57 
   58         cchan = namec(clone, Aopen, ORDWR, 0);
   59 
   60         /* get directory name */
   61         if(waserror()){
   62                 cclose(cchan);
   63                 nexterror();
   64         }
   65         n = devtab[cchan->type]->read(cchan, name, sizeof(name)-1, 0);
   66         name[n] = 0;
   67         for(p = name; *p == ' '; p++)
   68                 ;
   69         sprint(name, "%lud", strtoul(p, 0, 0));
   70         p = strrchr(clone, '/');
   71         *p = 0;
   72         if(ds->dir)
   73                 snprint(ds->dir, Maxpath, "%s/%s", clone, name);
   74         snprint(data, sizeof(data), "%s/%s/data", clone, name);
   75 
   76         /* connect */
   77         if(ds->local)
   78                 snprint(name, sizeof(name), "connect %s %s", dest, ds->local);
   79         else
   80                 snprint(name, sizeof(name), "connect %s", dest);
   81         devtab[cchan->type]->write(cchan, name, strlen(name), 0);
   82 
   83         /* open data connection */
   84         dchan = namec(data, Aopen, ORDWR, 0);
   85         if(ds->ctlp)
   86                 *ds->ctlp = cchan;
   87         else
   88                 cclose(cchan);
   89         poperror();
   90         return dchan;
   91 
   92 }
   93 
   94 /*
   95  *  parse a dial string
   96  */
   97 static void
   98 _dial_string_parse(char *str, DS *ds)
   99 {
  100         char *p, *p2;
  101 
  102         strncpy(ds->buf, str, Maxstring);
  103         ds->buf[Maxstring-1] = 0;
  104 
  105         p = strchr(ds->buf, '!');
  106         if(p == 0) {
  107                 ds->netdir = 0;
  108                 ds->proto = "net";
  109                 ds->rem = ds->buf;
  110         } else {
  111                 if(*ds->buf != '/' && *ds->buf != '#'){
  112                         ds->netdir = 0;
  113                         ds->proto = ds->buf;
  114                 } else {
  115                         for(p2 = p; *p2 != '/'; p2--)
  116                                 ;
  117                         *p2++ = 0;
  118                         ds->netdir = ds->buf;
  119                         ds->proto = p2;
  120                 }
  121                 *p = 0;
  122                 ds->rem = p + 1;
  123         }
  124 }

Cache object: 41c3376bf248504dd012eb5b57b94791


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.