cifscmd.c 4.3 KB

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