cifscmd.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "headers.h"
  10. #include <bio.h>
  11. SmbClient *c;
  12. Biobuf bin, bout;
  13. static int verbose = 1;
  14. #define SEP(c) (((c)==' ')||((c)=='\t')||((c)=='\n'))
  15. typedef struct Slut {
  16. char *name;
  17. int val;
  18. } Slut;
  19. static char *
  20. tokenise(char *s, char **start, char **end)
  21. {
  22. char *to;
  23. Rune r;
  24. int n;
  25. while(*s && SEP(*s)) /* skip leading white space */
  26. s++;
  27. to = *start = s;
  28. while(*s){
  29. n = chartorune(&r, s);
  30. if(SEP(r)){
  31. if(to != *start) /* we have data */
  32. break;
  33. s += n; /* null string - keep looking */
  34. while(*s && SEP(*s))
  35. s++;
  36. to = *start = s;
  37. }
  38. else if(r == '\''){
  39. s += n; /* skip leading quote */
  40. while(*s){
  41. n = chartorune(&r, s);
  42. if(r == '\''){
  43. if(s[1] != '\'')
  44. break;
  45. s++; /* embedded quote */
  46. }
  47. while (n--)
  48. *to++ = *s++;
  49. }
  50. if(!*s) /* no trailing quote */
  51. break;
  52. s++; /* skip trailing quote */
  53. }
  54. else {
  55. while(n--)
  56. *to++ = *s++;
  57. }
  58. }
  59. *end = to;
  60. return s;
  61. }
  62. static int
  63. parse(char *s, char *fields[], int nfields)
  64. {
  65. int c, argc;
  66. char *start, *end;
  67. argc = 0;
  68. c = *s;
  69. while(c){
  70. s = tokenise(s, &start, &end);
  71. c = *s++;
  72. if(*start == 0)
  73. break;
  74. if(argc >= nfields-1)
  75. return -1;
  76. *end = 0;
  77. fields[argc++] = start;
  78. }
  79. fields[argc] = 0;
  80. Bprint(&bout, "parse returns %d\n", argc);
  81. return argc;
  82. }
  83. typedef struct {
  84. char *name;
  85. int32_t (*f)(SmbClient *, int, char *[]);
  86. int connected;
  87. char *help;
  88. } Cmd;
  89. static Cmd cmd[];
  90. static int32_t
  91. cmdhelp(SmbClient *s, int argc, char *argv[])
  92. {
  93. Cmd *cp;
  94. char *p;
  95. if(argc)
  96. p = argv[0];
  97. else
  98. p = 0;
  99. for (cp = cmd; cp->name; cp++) {
  100. if (p == 0 || strcmp(p, cp->name) == 0)
  101. Bprint(&bout, "%s\n", cp->help);
  102. }
  103. return 0;
  104. }
  105. static Slut sharemodeslut[] = {
  106. { "compatibility", SMB_OPEN_MODE_SHARE_COMPATIBILITY },
  107. { "exclusive", SMB_OPEN_MODE_SHARE_EXCLUSIVE },
  108. { "denywrite", SMB_OPEN_MODE_SHARE_DENY_WRITE },
  109. { "denyread", SMB_OPEN_MODE_SHARE_DENY_READOREXEC },
  110. { "denynone", SMB_OPEN_MODE_SHARE_DENY_NONE },
  111. { 0 }
  112. };
  113. static Slut openmodeslut[] = {
  114. { "oread", OREAD },
  115. { "owrite", OWRITE },
  116. { "ordwr", ORDWR },
  117. { "oexec", OEXEC },
  118. { 0 }
  119. };
  120. static int
  121. slut(Slut *s, char *pat)
  122. {
  123. while (s->name) {
  124. if (cistrcmp(s->name, pat) == 0)
  125. return s->val;
  126. s++;
  127. }
  128. Bprint(&bout, "%s unrecognised\n", pat);
  129. return -1;
  130. }
  131. static int32_t
  132. cmdopen(SmbClient *c, int argc, char *argv[])
  133. {
  134. char *errmsg;
  135. int sm, om;
  136. int rv;
  137. uint8_t errclass;
  138. uint16_t error;
  139. uint16_t fid, attr;
  140. uint32_t mtime, size;
  141. uint16_t accessallowed;
  142. if (argc != 3) {
  143. Bprint(&bout, "wrong number of arguments\n");
  144. return -1;
  145. }
  146. sm = slut(sharemodeslut, argv[1]);
  147. if (sm < 0)
  148. return -1;
  149. om = slut(openmodeslut, argv[2]);
  150. if (om < 0)
  151. return -1;
  152. errmsg = nil;
  153. rv = smbclientopen(c, (sm << 3) | om, argv[0], &errclass, &error, &fid, &attr, &mtime, &size, &accessallowed, &errmsg);
  154. if (rv == 0) {
  155. if (errmsg) {
  156. print("local error %s\n", errmsg);
  157. free(errmsg);
  158. return -1;
  159. }
  160. return (errclass << 16) | error;
  161. }
  162. print("fid 0x%.4x attr 0x%.4x time %ld size %lu accessallowed %u\n",
  163. fid, attr, mtime, size, accessallowed);
  164. return 0;
  165. }
  166. static Cmd cmd[] = {
  167. { "help", cmdhelp, 0, "help" },
  168. { "open", cmdopen, 1, "open name sharemode openmode" },
  169. { 0, 0 },
  170. };
  171. void
  172. threadmain(int argc, char *argv[])
  173. {
  174. char *errmsg;
  175. int ac;
  176. char *ap, *av[256];
  177. Cmd *cp;
  178. int32_t status;
  179. if (argc > 3) {
  180. print("usage: cifscmd [to [share]]\n");
  181. exits("args");
  182. }
  183. smbglobalsguess(1);
  184. errmsg = nil;
  185. if (Binit(&bin, 0, OREAD) == Beof || Binit(&bout, 1, OWRITE) == Beof) {
  186. fprint(2, "%s: can't init bio: %r\n", argv0);
  187. threadexits("Binit");
  188. }
  189. if (argc > 1) {
  190. c = smbconnect(argv[1], argc == 3 ? argv[2] : nil, &errmsg);
  191. if (c == nil)
  192. fprint(2, "failed to connect: %s\n", errmsg);
  193. }
  194. while ((ap = Brdline(&bin, '\n'))) {
  195. ap[Blinelen(&bin) - 1] = 0;
  196. switch (ac = parse(ap, av, nelem(av))) {
  197. default:
  198. for (cp = cmd; cp->name; cp++) {
  199. if (strcmp(cp->name, av[0]) == 0)
  200. break;
  201. }
  202. if (cp->name == 0) {
  203. Bprint(&bout, "eh?\n");
  204. break;
  205. }
  206. if (c == 0 && cp->connected) {
  207. Bprint(&bout, "not currently connected\n");
  208. break;
  209. }
  210. if ((status = (*cp->f)(c, ac - 1, &av[1])) != -1) {
  211. if(verbose)
  212. Bprint(&bout, "ok %ld/%ld\n", status >> 16, status & 0xffff);
  213. break;
  214. }
  215. break;
  216. case -1:
  217. Bprint(&bout, "eh?\n");
  218. break;
  219. case 0:
  220. break;
  221. }
  222. Bflush(&bout);
  223. }
  224. threadexits(0);
  225. }