*** empty log message ***
[arla.git] / arlad / arla-cli.c
blob3f6fbbdda634064b9caee9a3ce535c37d8112f3d
1 /*
2 * Copyright (c) 1995 - 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include <arla_local.h>
35 #include <sl.h>
36 #include <getarg.h>
37 #include <vers.h>
39 RCSID("$Id$");
41 char *default_log_file = "/dev/stderr";
42 char *default_arla_cachedir = ".arlacache";
43 int client_port = 4712;
46 /* creds used for all the interactive usage */
48 static CredCacheEntry *ce;
50 static VenusFid cwd;
51 static VenusFid rootcwd;
53 static int arla_chdir(int, char **);
54 static int arla_ls(int, char **);
55 static int arla_cat(int, char **);
56 static int arla_cp(int, char **);
57 static int arla_sleep(int, char **);
58 static int arla_wc(int, char **);
59 static int help(int, char **);
60 static int arla_quit(int, char **);
61 static int arla_checkserver(int, char **);
62 static int arla_conn_status(int, char **);
63 static int arla_connect(int, char **);
64 static int arla_vol_status(int, char **);
65 static int arla_cred_status(int, char **);
66 static int arla_fcache_status(int, char **);
67 static int arla_cell_status (int, char **);
68 static int arla_sysname(int, char**);
69 static int arla_mkdir (int, char**);
70 static int arla_rmdir (int, char**);
71 static int arla_rm (int, char**);
72 static int arla_put (int, char**);
73 static int arla_get (int, char**);
74 #ifdef RXDEBUG
75 static int arla_rx_status(int argc, char **argv);
76 #endif
77 static int arla_flushfid(int argc, char **argv);
79 static char *copy_dirname(const char *s);
80 static char *copy_basename(const char *s);
83 static SL_cmd cmds[] = {
84 {"chdir", arla_chdir, "chdir directory"},
85 {"cd"},
86 {"ls", arla_ls, "ls"},
87 {"cat", arla_cat, "cat file"},
88 {"cp", arla_cp, "copy file"},
89 {"sleep", arla_sleep, "sleep seconds"},
90 {"wc", arla_wc, "wc file"},
91 {"mkdir", arla_mkdir, "mkdir dir"},
92 {"rmdir", arla_rmdir, "rmdir dir"},
93 {"rm", arla_rm, "rm file"},
94 {"put", arla_put, "put localfile [afsfile]"},
95 {"get", arla_get, "get afsfile [localfile]"},
96 {"help", help, "help"},
97 {"?"},
98 {"checkservers", arla_checkserver, "poll servers are down"},
99 {"conn-status", arla_conn_status, "connection status"},
100 {"vol-status", arla_vol_status, "volume cache status"},
101 {"cred-status", arla_cred_status, "credentials status"},
102 {"fcache-status", arla_fcache_status, "file cache status"},
103 {"cell-status", arla_cell_status, "cell status"},
104 #ifdef RXDEBUG
105 {"rx-status", arla_rx_status, "rx connection status"},
106 #endif
107 {"flushfid", arla_flushfid, "flush a fid from the cache"},
108 {"quit", arla_quit, "quit"},
109 {"exit"},
110 {"sysname", arla_sysname, "sysname"},
111 {"connect", arla_connect,
112 "connect [connected|fetch-only|disconnected|callback-connected]"},
113 { NULL }
117 * Return a malloced copy of the dirname of `s'
120 static char *
121 copy_dirname (const char *s)
123 const char *p;
124 char *res;
126 p = strrchr (s, '/');
127 if (p == NULL)
128 return strdup(".");
129 res = malloc (p - s + 1);
130 if (res == NULL)
131 return NULL;
132 memmove (res, s, p - s);
133 res[p - s] = '\0';
134 return res;
138 * Return the basename of `s'.
139 * The result is malloc'ed.
142 static char *
143 copy_basename (const char *s)
145 const char *p, *q;
146 char *res;
148 p = strrchr (s, '/');
149 if (p == NULL)
150 p = s;
151 else
152 ++p;
153 q = s + strlen (s);
154 res = malloc (q - p + 1);
155 if (res == NULL)
156 return NULL;
157 memmove (res, p, q - p);
158 res[q - p] = '\0';
159 return res;
166 static int
167 arla_quit (int argc, char **argv)
169 printf("Thank you for using arla\n");
170 return -2;
173 static int
174 arla_flushfid(int argc, char **argv)
176 AFSCallBack broken_callback = {0, 0, CBDROPPED};
177 VenusFid fid;
179 if (argc != 2) {
180 fprintf(stderr, "flushfid fid\n");
181 return 0;
184 if ((sscanf(argv[1], "%d.%d.%d.%d", &fid.Cell, &fid.fid.Volume,
185 &fid.fid.Vnode, &fid.fid.Unique)) == 4) {
187 } else if ((sscanf(argv[1], "%d.%d.%d", &fid.fid.Volume,
188 &fid.fid.Vnode, &fid.fid.Unique)) == 3) {
189 fid.Cell = cwd.Cell;
190 } else {
191 fprintf(stderr, "flushfid fid\n");
192 return 0;
195 fcache_stale_entry(fid, broken_callback);
197 return 0;
201 static int
202 arla_chdir (int argc, char **argv)
204 if (argc != 2) {
205 printf ("usage: %s dir\n", argv[0]);
206 return 0;
209 if(cm_walk (cwd, argv[1], &cwd))
210 printf ("walk %s failed\n", argv[1]);
211 return 0;
214 static int
215 print_dir (VenusFid *fid, const char *name, void *v)
217 printf("(%d, %d, %d, %d): %s\n", fid->Cell,
218 fid->fid.Volume,
219 fid->fid.Vnode,
220 fid->fid.Unique, name);
221 return 0;
224 struct ls_context {
225 VenusFid *dir_fid;
226 CredCacheEntry *ce;
229 static int
230 print_dir_long (VenusFid *fid, const char *name, void *v)
232 int ret;
233 AccessEntry *ae;
234 struct ls_context *context = (struct ls_context *)v;
235 char type;
236 CredCacheEntry *ce = context->ce;
237 FCacheEntry *entry;
238 VenusFid *dir_fid = context->dir_fid;
239 char timestr[20];
240 struct tm *t;
241 time_t ti;
243 if (VenusFid_cmp(fid, dir_fid) == 0)
244 return 0;
246 ret = followmountpoint (fid, dir_fid, NULL, &ce);
247 if (ret) {
248 printf ("follow %s: %d\n", name, ret);
249 return 0;
252 /* Have we follow a mountpoint to ourself ? */
253 if (VenusFid_cmp(fid, dir_fid) == 0)
254 return 0;
256 ret = fcache_get(&entry, *fid, context->ce);
257 if (ret) {
258 printf("%s: %d\n", name, ret);
259 return 0;
262 ret = cm_getattr (entry, context->ce, &ae);
263 if (ret) {
264 fcache_release(entry);
265 printf ("%s: %d\n", name, ret);
266 return 0;
269 switch (entry->status.FileType) {
270 case TYPE_FILE :
271 type = '-';
272 break;
273 case TYPE_DIR :
274 type = 'd';
275 break;
276 case TYPE_LINK :
277 type = 'l';
278 break;
279 default :
280 abort ();
283 printf("(%4d, %8d, %8d, %8d): ",
284 fid->Cell,
285 fid->fid.Volume,
286 fid->fid.Vnode,
287 fid->fid.Unique);
289 ti = entry->status.ClientModTime;
290 t = localtime (&ti);
291 strftime (timestr, sizeof(timestr), "%Y-%m-%d", t);
292 printf ("%c%c%c%c%c%c%c%c%c%c %2d %6d %6d %8lu %s ",
293 type,
294 entry->status.UnixModeBits & 0x100 ? 'r' : '-',
295 entry->status.UnixModeBits & 0x080 ? 'w' : '-',
296 entry->status.UnixModeBits & 0x040 ? 'x' : '-',
297 entry->status.UnixModeBits & 0x020 ? 'r' : '-',
298 entry->status.UnixModeBits & 0x010 ? 'w' : '-',
299 entry->status.UnixModeBits & 0x008 ? 'x' : '-',
300 entry->status.UnixModeBits & 0x004 ? 'r' : '-',
301 entry->status.UnixModeBits & 0x002 ? 'w' : '-',
302 entry->status.UnixModeBits & 0x001 ? 'x' : '-',
303 entry->status.LinkCount,
304 entry->status.Owner,
305 entry->status.Group,
306 (unsigned long)fcache_get_status_length(&entry->status),
307 timestr);
309 printf ("v %d ", entry->status.DataVersion);
311 printf ("%s\n", name);
312 fcache_release(entry);
313 return 0;
316 static int
317 arla_ls (int argc, char **argv)
319 struct getargs args[] = {
320 {NULL, 'l', arg_flag, NULL},
322 int l_flag = 0;
323 int error;
324 int optind = 0;
325 struct ls_context context;
326 FCacheEntry *entry;
328 args[0].value = &l_flag;
330 if (getarg (args, sizeof(args)/sizeof(*args), argc, argv, &optind)) {
331 arg_printusage (args, sizeof(args)/sizeof(*args), "ls", NULL);
332 return 0;
334 context.dir_fid = &cwd;
335 context.ce = ce;
336 error = fcache_get(&entry, cwd, ce);
337 if (error) {
338 printf ("fcache_get failed: %s\n", koerr_gettext(error));
339 return 0;
342 error = adir_readdir (&entry, l_flag ? print_dir_long : print_dir,
343 &context, &ce);
344 fcache_release(entry);
345 if (error) {
346 printf ("adir_readdir failed: %s\n", koerr_gettext(error));
347 return 0;
349 cwd = entry->fid;
350 return 0;
353 static int
354 arla_sysname (int argc, char **argv)
356 switch (argc) {
357 case 1:
358 printf("sysname: %s\n", fcache_getdefsysname());
359 break;
360 case 2:
361 fcache_setdefsysname(argv[1]);
362 printf("setting sysname to: %s\n", fcache_getdefsysname());
363 break;
364 default:
365 printf("syntax: sysname <sysname>\n");
366 break;
368 return 0;
371 static int
372 arla_mkdir (int argc, char **argv)
374 VenusFid fid;
375 int ret;
376 FCacheEntry *e;
377 char *argcopy;
378 char *dirname;
379 char *basename;
380 AFSStoreStatus store_attr;
381 VenusFid res;
382 AFSFetchStatus fetch_attr;
384 if (argc != 2) {
385 printf ("usage: %s file\n", argv[0]);
386 return 0;
389 argcopy = strdup(argv[1]);
390 if (argcopy == NULL)
391 err(1, "strdup");
392 basename = strrchr(argcopy, '/');
393 if (basename == NULL) {
394 basename = argcopy;
395 dirname = ".";
396 } else {
397 basename[0] = '\0';
398 basename++;
399 dirname = argcopy;
402 if (cm_walk (cwd, dirname, &fid) == 0) {
404 ret = fcache_get(&e, fid, ce);
405 if (ret) {
406 printf ("fcache_get failed: %d\n", ret);
407 free(argcopy);
408 return 0;
411 store_attr.Mask = 0;
412 store_attr.ClientModTime = 0;
413 store_attr.Owner = 0;
414 store_attr.Group = 0;
415 store_attr.UnixModeBits = 0;
416 store_attr.SegSize = 0;
417 ret = cm_mkdir(&e, basename, &store_attr, &res, &fetch_attr, &ce);
418 if (ret)
419 arla_warn (ADEBWARN, ret,
420 "%s: cannot create directory `%s'",
421 argv[0], argv[1]);
423 fcache_release(e);
425 free(argcopy);
426 return 0;
429 static int
430 arla_rmdir (int argc, char **argv)
432 VenusFid fid;
433 int ret;
434 FCacheEntry *e;
435 char *argcopy;
436 char *dirname;
437 char *basename;
439 if (argc != 2) {
440 printf ("usage: %s file\n", argv[0]);
441 return 0;
444 argcopy = strdup(argv[1]);
445 if (argcopy == NULL)
446 err(1, "strdup");
447 basename = strrchr(argcopy, '/');
448 if (basename == NULL) {
449 basename = argcopy;
450 dirname = ".";
451 } else {
452 basename[0] = '\0';
453 basename++;
454 dirname = argcopy;
457 if (cm_walk (cwd, dirname, &fid) == 0) {
459 ret = fcache_get(&e, fid, ce);
460 if (ret) {
461 printf ("fcache_get failed: %d\n", ret);
462 free(dirname);
463 return 0;
466 ret = cm_rmdir(&e, basename, &ce);
467 if (ret)
468 arla_warn (ADEBWARN, ret,
469 "%s: cannot remove directory `%s'",
470 argv[0], argv[1]);
471 fcache_release(e);
473 free(argcopy);
474 return 0;
477 static int
478 arla_rm (int argc, char **argv)
480 VenusFid fid;
481 int ret;
482 FCacheEntry *e;
483 char *dirname;
484 char *basename;
486 if (argc != 2) {
487 printf ("usage: %s file\n", argv[0]);
488 return 0;
490 dirname = copy_dirname(argv[1]);
491 if (dirname == NULL)
492 err(1, "copy_dirname");
493 basename = copy_basename(argv[1]);
494 if (basename == NULL)
495 err(1, "copy_basename");
497 if(cm_walk (cwd, dirname, &fid) == 0) {
499 ret = fcache_get(&e, fid, ce);
500 if (ret) {
501 printf ("fcache_get failed: %d\n", ret);
502 free(dirname);
503 free(basename);
504 return 0;
507 ret = cm_remove(&e, basename, &ce);
508 if (ret)
509 arla_warn (ADEBWARN, ret,
510 "%s: cannot remove file `%s'",
511 argv[0], argv[1]);
513 fcache_release(e);
515 free(dirname);
516 free(basename);
517 return 0;
520 static int
521 arla_put (int argc, char **argv)
523 VenusFid dirfid;
524 VenusFid fid;
525 int ret;
526 FCacheEntry *e;
527 char *localname;
528 char *localbasename;
529 char *afsname;
530 char *afsbasename;
531 char *afsdirname;
532 AFSStoreStatus store_attr;
533 AFSFetchStatus fetch_attr;
534 int afs_fd;
535 int local_fd;
536 char buf[8192];
537 int write_ret;
538 CredCacheEntry *ce;
540 if (argc != 2 && argc != 3) {
541 printf ("usage: %s localfile [afsfile]\n", argv[0]);
542 return 0;
545 localname = argv[1];
547 localbasename = copy_basename(localname);
548 if (localbasename == NULL)
549 err(1, "copy_basename");
551 if (argc == 3) {
552 afsname = argv[2];
553 } else {
554 afsname = localbasename;
557 afsdirname = copy_dirname(afsname);
558 if (afsdirname == NULL)
559 err(1, "copy_dirname");
560 afsbasename = copy_basename(afsname);
561 if (afsbasename == NULL)
562 err(1, "copy_basename");
565 printf("localbasename: *%s* afsname: *%s* afsdirname: *%s* afsbasename: *%s*\n",
566 localbasename, afsname, afsdirname, afsbasename);
568 local_fd = open (localname, O_RDONLY, 0);
570 if (local_fd < 0) {
571 printf ("open %s: %s\n", localname, strerror(errno));
572 ret = 0;
573 goto out;
576 if(cm_walk (cwd, afsdirname, &dirfid))
577 goto out;
579 ce = cred_get (dirfid.Cell, getuid(), CRED_ANY);
581 ret = fcache_get(&e, dirfid, ce);
582 if (ret) {
583 printf ("fcache_get failed: %d\n", ret);
584 ret = 1;
585 goto out;
588 memset(&store_attr, 0, sizeof(store_attr));
590 ret = cm_create(&e, afsbasename, &store_attr, &fid, &fetch_attr, &ce);
591 if (ret) {
592 if (ret != EEXIST) {
593 arla_warn (ADEBWARN, ret,
594 "%s: cannot create file `%s'",
595 argv[0], afsname);
596 fcache_release(e);
597 ret = 1;
598 goto out;
599 } else {
600 ret = cm_lookup (&e, afsbasename, &fid, &ce, 1);
601 if (ret) {
602 arla_warn (ADEBWARN, ret,
603 "%s: cannot open file `%s'",
604 argv[0], afsname);
605 fcache_release(e);
606 ret = 1;
607 goto out;
612 fcache_release(e);
614 ret = fcache_get(&e, fid, ce);
615 if (ret) {
616 printf ("fcache_get failed: %d\n", ret);
617 ret = 1;
618 goto out;
621 ret = fcache_get_data (&e, &ce, 0);
622 if (ret) {
623 fcache_release(e);
624 printf ("fcache_get_data failed: %d\n", ret);
625 ret = 1;
626 goto out;
629 afs_fd = fcache_open_file (e, O_WRONLY);
631 if (afs_fd < 0) {
632 fcache_release(e);
633 printf ("fcache_open_file failed: %d\n", errno);
634 ret = 0;
635 goto out;
638 ret = ftruncate(afs_fd, 0);
639 if (ret) {
640 fcache_release(e);
641 printf ("ftruncate failed: %d\n", errno);
644 while ((ret = read (local_fd, buf, sizeof(buf))) > 0) {
645 write_ret = write (afs_fd, buf, ret);
646 if (write_ret < 0) {
647 printf("write failed: %d\n", errno);
648 ret = 1;
649 goto out;
650 } else if (write_ret != ret) {
651 printf("short write: %d should be %d\n", write_ret, ret);
652 ret = 1;
653 goto out;
657 close(afs_fd);
658 close(local_fd);
660 memset(&store_attr, 0, sizeof(store_attr));
662 ret = cm_close (e, NNPFS_WRITE, &store_attr, ce);
663 if (ret) {
664 arla_warn (ADEBWARN, ret,
665 "%s: cannot close file `%s'",
666 argv[0], afsname);
667 fcache_release(e);
668 ret = 1;
669 goto out;
672 fcache_release(e);
674 out:
675 free(localbasename);
676 free(afsdirname);
677 free(afsbasename);
678 return 0;
681 static int
682 arla_get (int argc, char **argv)
684 return 0;
687 static int
688 arla_cat_et_wc (int argc, char **argv, int do_cat, int out_fd)
690 VenusFid fid;
691 int fd;
692 char buf[8192];
693 int ret;
694 FCacheEntry *e;
695 size_t size = 0;
697 if (argc != 2) {
698 printf ("usage: %s file\n", argv[0]);
699 return 0;
701 if(cm_walk (cwd, argv[1], &fid) == 0) {
703 ret = fcache_get(&e, fid, ce);
704 if (ret) {
705 printf ("fcache_get failed: %d\n", ret);
706 return 0;
709 ret = fcache_get_data (&e, &ce, 0);
710 if (ret) {
711 fcache_release(e);
712 printf ("fcache_get_data failed: %d\n", ret);
713 return 0;
716 fd = fcache_open_file (e, O_RDONLY);
718 if (fd < 0) {
719 fcache_release(e);
720 printf ("fcache_open_file failed: %d\n", errno);
721 return 0;
723 while ((ret = read (fd, buf, sizeof(buf))) > 0) {
724 if(do_cat)
725 write (out_fd, buf, ret);
726 else
727 size += ret;
729 if(!do_cat)
730 printf("%lu %s\n", (unsigned long)size, argv[1]);
731 close (fd);
732 fcache_release(e);
734 return 0;
737 static int
738 arla_cat (int argc, char **argv)
740 return arla_cat_et_wc(argc, argv, 1, STDOUT_FILENO);
743 static int
744 arla_cp (int argc, char **argv)
746 char *nargv[3];
747 int fd, ret;
749 if (argc != 3) {
750 printf ("usage: %s from-file to-file\n", argv[0]);
751 return 0;
754 fd = open (argv[2], O_CREAT|O_WRONLY|O_TRUNC, 0600);
755 if (fd < 0) {
756 warn ("open");
757 return 0;
760 nargv[0] = argv[0];
761 nargv[1] = argv[1];
762 nargv[2] = NULL;
764 ret = arla_cat_et_wc(argc-1, nargv, 1, fd);
765 close (fd);
766 return ret;
770 static int
771 arla_sleep(int argc, char **argv)
773 struct timeval tv;
775 if (argc != 2) {
776 printf ("usage: %s <time>\n", argv[0]);
777 return 0;
780 tv.tv_sec = atoi(argv[1]);
781 tv.tv_usec = 0;
782 IOMGR_Select(0, NULL, NULL, NULL, &tv);
784 return 0;
787 static int
788 arla_wc (int argc, char **argv)
790 return arla_cat_et_wc(argc, argv, 0, -1);
794 static int
795 help (int argc, char **argv)
797 sl_help(cmds, argc, argv);
798 return 0;
801 static int
802 arla_checkserver (int argc, char **argv)
804 uint32_t hosts[12];
805 int num = sizeof(hosts)/sizeof(hosts[0]);
807 conn_downhosts(cwd.Cell, hosts, &num, 0);
808 if (num < 0 || num > sizeof(hosts)/sizeof(hosts[0])) {
809 fprintf (stderr, "conn_downhosts returned bogus num: %d\n", num);
810 return 0;
812 if (num == 0) {
813 printf ("no servers down in %s\n", cell_num2name(cwd.Cell));
814 } else {
815 while (num) {
816 struct in_addr in;
817 in.s_addr = hosts[num];
818 printf ("down: %s\n", inet_ntoa(in));
819 num--;
823 return 0;
826 static int
827 arla_conn_status (int argc, char **argv)
829 conn_status ();
830 return 0;
833 static int
834 arla_vol_status (int argc, char **argv)
836 volcache_status ();
837 return 0;
840 static int
841 arla_cred_status (int argc, char **argv)
843 cred_status ();
844 return 0;
847 static int
848 arla_fcache_status (int argc, char **argv)
850 fcache_status ();
851 return 0;
854 static int
855 arla_cell_status (int argc, char **argv)
857 cell_entry *c;
859 if (argc != 2) {
860 printf ("usage: %s <cell-name>\n", argv[0]);
861 return 0;
863 c = cell_get_by_name(argv[1]);
864 if (c == NULL)
865 printf ("no such cell\n");
866 else
867 cell_print_cell (c, stdout);
868 return 0;
871 static int
872 arla_connect (int argc, char **argv)
874 int error = (argc > 2) ? 1 : 0;
875 int32_t mode;
876 if (argc == 2) {
877 struct nnpfs_cred cred;
879 if (strncmp("dis", argv[1], 3) == 0)
880 mode = arla_CONNMODE_DISCONN;
881 else if (strncmp("fetch", argv[1], 5) == 0)
882 mode = arla_CONNMODE_FETCH;
883 else if (strncmp("conn", argv[1], 4) == 0)
884 mode = arla_CONNMODE_CONN;
885 else if (strncmp(argv[1], "call", 4) == 0)
886 mode = arla_CONNMODE_CONN_WITHCALLBACKS;
887 else
888 mode = -1;
890 if (mode >= 0)
891 error = set_connmode(mode, &cred);
893 if (error) {
894 printf("usage: %s [connected|fetch|disconnected|callback-connected]\n",
895 argv[0]);
896 return 0;
899 get_connmode(&mode);
900 switch(mode) {
901 case arla_CONNMODE_CONN:
902 printf("Connected mode\n");
903 break;
904 case arla_CONNMODE_FETCH:
905 printf("Fetch only mode\n");
906 break;
907 case arla_CONNMODE_DISCONN:
908 printf("Disconnected mode\n");
909 break;
910 default:
911 printf("Unknown or error\n");
912 break;
914 return 0;
917 #ifdef RXDEBUG
918 static int
919 arla_rx_status(int argc, char **argv)
921 rx_PrintStats(stderr);
922 return 0;
924 #endif
927 #if 0
929 static int
930 get_cred(const char *princ, const char *inst, const char *krealm,
931 CREDENTIALS *c)
933 KTEXT_ST foo;
934 int k_errno;
936 k_errno = krb_get_cred((char*)princ, (char*)inst, (char*)krealm, c);
938 if(k_errno != KSUCCESS) {
939 k_errno = krb_mk_req(&foo, (char*)princ, (char*)inst, (char*)krealm, 0);
940 if (k_errno == KSUCCESS)
941 k_errno = krb_get_cred((char*)princ, (char*)inst, (char*)krealm, c);
943 return k_errno;
946 #endif
949 static void
950 arla_start (char *device_file, const char *cache_dir, int argc, char **argv)
952 int error;
954 #if 0
956 struct cred_rxkad cred;
957 CREDENTIALS c;
958 int ret;
959 char *realm;
960 const char *this_cell = cell_getthiscell ();
961 const char *db_server = cell_findnamedbbyname (this_cell);
963 if (db_server == NULL)
964 arla_errx (1, ADEBERROR,
965 "no db server for cell %s", this_cell);
966 realm = krb_realmofhost (db_server);
968 ret = get_cred("afs", this_cell, realm, &c);
969 if (ret)
970 ret = get_cred("afs", "", realm, &c);
972 if (ret) {
973 arla_warnx (ADEBWARN,
974 "getting ticket for %s: %s",
975 this_cell,
976 krb_get_err_text (ret));
977 return;
980 memset(&cred, 0, sizeof(cred));
982 memcpy(&cred.ct.HandShakeKey, c.session, sizeof(cred.ct.AuthHandle));
983 cred.ct.AuthHandle = c.kvno;
984 cred.ct.ViceId = getuid();
985 cred.ct.BeginTimestamp = c.issue_date + 1;
986 cred.ct.EndTimestamp = krb_life_to_time(c.issue_date, c.lifetime);
988 cred.ticket_len = c.ticket_st.length;
989 if (cred.ticket_len > sizeof(cred.ticket))
990 arla_errx (1, ADEBERROR, "ticket too large");
991 memcpy(cred.ticket, c.ticket_st.dat, cred.ticket_len);
993 cred_add (getuid(), CRED_KRB4, 2, cell_name2num(cell_getthiscell()),
994 2, &cred, sizeof(cred), getuid());
997 #endif
999 ce = cred_get (cell_name2num(cell_getthiscell()), getuid(), CRED_ANY);
1001 assert (ce != NULL);
1003 nnpfs_message_init ();
1004 kernel_opendevice ("null");
1006 arla_warnx (ADEBINIT, "Getting root...");
1007 error = getroot (&rootcwd, ce);
1008 if (error)
1009 arla_err (1, ADEBERROR, error, "getroot");
1010 cwd = rootcwd;
1011 arla_warnx(ADEBINIT, "arla loop started");
1012 error = 0;
1013 if (argc > 0) {
1014 error = sl_command(cmds, argc, argv);
1015 if (error == -1)
1016 errx (1, "%s: Unknown command\n", argv[0]);
1017 } else {
1018 sl_loop(cmds, "arla> ");
1020 store_state();
1021 fcache_giveup_all_callbacks();
1022 if (error)
1023 exit(1);
1026 char *
1027 get_default_cache_dir (void)
1029 static char cache_path[MAXPATHLEN];
1030 char *home;
1032 home = getenv("HOME");
1033 if (home == NULL)
1034 home = "/var/tmp";
1036 snprintf (cache_path, sizeof(cache_path), "%s/.arla-cache",
1037 home);
1038 return cache_path;
1041 static struct getargs args[] = {
1042 {"conffile", 'c', arg_string, &conf_file,
1043 "path to configuration file", "file"},
1044 {"check-consistency", 'C', arg_flag, &cm_consistency,
1045 "if we want extra paranoid consistency checks", NULL },
1046 {"log", 'l', arg_string, &log_file,
1047 "where to write log (stderr (default), syslog, or path to file)", NULL},
1048 {"debug", 0, arg_string, &debug_levels,
1049 "what to write in the log", NULL},
1050 {"connected-mode", 0, arg_string, &connected_mode_string,
1051 "initial connected mode [conncted|fetch-only|disconnected]", NULL},
1052 {"dynroot", 'D', arg_flag, &dynroot_enable,
1053 "if dynroot is enabled", NULL},
1054 #ifdef KERBEROS
1055 {"rxkad-level", 'r', arg_string, &rxkad_level_string,
1056 "the rxkad level to use (clear, auth or crypt)", NULL},
1057 #endif
1058 {"sysname", 's', arg_string, &argv_sysname,
1059 "set the sysname of this system", NULL},
1060 {"root-volume",0, arg_string, &root_volume},
1061 {"port", 0, arg_integer, &client_port,
1062 "port number to use", "number"},
1063 {"recover", 'z', arg_negative_flag, &recover,
1064 "don't recover state", NULL},
1065 {"cache-dir", 0, arg_string, &cache_dir,
1066 "cache directory", "directory"},
1067 {"workers", 0, arg_integer, &num_workers,
1068 "number of worker threads", NULL},
1069 {"fake-mp", 0, arg_flag, &fake_mp,
1070 "enable fake mountpoints", NULL},
1071 {"version", 0, arg_flag, &version_flag,
1072 NULL, NULL},
1073 {"help", 0, arg_flag, &help_flag,
1074 NULL, NULL}
1077 static void
1078 usage (int ret)
1080 arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "[command]");
1081 exit (ret);
1085 main (int argc, char **argv)
1087 int optind = 0;
1088 int ret;
1090 setprogname (argv[0]);
1091 tzset();
1092 srand(time(NULL));
1094 if (getarg (args, sizeof(args)/sizeof(*args), argc, argv, &optind))
1095 usage (1);
1097 argc -= optind;
1098 argv += optind;
1100 if (help_flag)
1101 usage (0);
1103 if (version_flag) {
1104 print_version (NULL);
1105 exit (0);
1108 default_log_file = "/dev/stderr";
1110 ret = arla_init();
1111 if (ret)
1112 return ret;
1115 struct timeval tv = { 0, 10000} ;
1116 IOMGR_Select(0, NULL, NULL, NULL, &tv);
1119 arla_start (NULL, cache_dir, argc, argv);
1121 return 0;