chandial.c 2.2 KB

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