readdir was rewritten in Ruby just before the end of the hackfest
[hurd/trovefs.git] / trovefs.c
1 /*
2  * Copyright (C) 1997,98,2002 Free Software Foundation Inc.
3  * Copyright (C) 2013  Steven McDonald <steven@steven-mcdonald.id.au>
4  *
5  * ftpfs translator written by Miles Bader <miles@gnu.org>
6  * Modified for trovefs by Steven McDonald <steven@steven-mcdonald.id.au>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This software is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  */
22
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <argp.h>
26 //#include <error.h>
27 #include <hurd/netfs.h>
28 #include "trovefs.h"
29
30 char *netfs_server_name = "trovefs";
31 char *netfs_server_version = TROVEFS_VERSION;
32
33 const char *argp_program_version = "trovefs " TROVEFS_VERSION;
34
35 static char args_doc[] = "BUCKET";
36 static char doc[] = "Trove filesystem translator."
37 "\vIf --hostname is not specified, it defaults to"
38 " \"" TROVEFS_DEFAULT_HOSTNAME "\".";
39
40 static struct argp_option options[] =
41 {
42         {"hostname",          'h', "HOSTNAME", 0, "S3 server hostname to connect to"},
43         {"access-key-id",     'i', "ID",       0, "Access key ID for S3 server"},
44         {"secret-access-key", 'k', "KEY",      0, "Secret access key for S3 server"},
45
46         {0}
47 };
48
49 struct arguments
50 {
51         char *args[1];
52         char *hostname;
53         char *access_key_id;
54         char *secret_access_key;
55 };
56
57 static error_t
58 parse_opt (int key, char *arg, struct argp_state *state)
59 {
60         struct arguments *arguments = state->input;
61
62         switch (key)
63         {
64                 case 'h':
65                         arguments->hostname = arg;
66                         break;
67                 case 'i':
68                         arguments->access_key_id = arg;
69                         break;
70                 case 'k':
71                         arguments->secret_access_key = arg;
72                         break;
73                 case ARGP_KEY_ARG:
74                         if (state->arg_num >= 1)
75                                 argp_usage (state);
76                         arguments->args[state->arg_num] = arg;
77                         break;
78                 case ARGP_KEY_END:
79                         if (state->arg_num < 1)
80                                 argp_usage (state);
81                         break;
82                 default:
83                         return ARGP_ERR_UNKNOWN;
84         }
85         return 0;
86 }
87
88 static struct argp argp = { options, parse_opt, args_doc, doc };
89
90 int netfs_maxsymlinks = 0;
91
92 int
93 main (int argc, char *argv[])
94 {
95         error_t err;
96         mach_port_t bootstrap, underlying_node;
97         io_statbuf_t underlying_stat;
98         struct arguments *arguments = malloc (sizeof (struct arguments));
99         arguments->hostname = TROVEFS_DEFAULT_HOSTNAME;
100
101         argp_parse (&argp, argc, argv, 0, 0, arguments);
102
103         struct trovefs *trovefs;
104
105         task_get_bootstrap_port (mach_task_self (), &bootstrap);
106
107         netfs_init ();
108
109         err = trovefs_create (
110                 arguments->hostname,
111                 arguments->args[0], // Bucket.
112                 arguments->access_key_id,
113                 arguments->secret_access_key,
114                 getpid (),
115                 &trovefs
116         );
117         if (err)
118                 return 1;
119 // FIXME: Why the fuck is 'error' broken?
120 //              error (1, err, "%s:%s", arguments->hostname, arguments->args[0]);
121
122         netfs_root_node = trovefs->root;
123
124         underlying_node = netfs_startup (bootstrap, 0);
125         err = io_stat (underlying_node, &underlying_stat);
126         if (err)
127                 return 2;
128
129         netfs_root_node->nn_stat = underlying_stat;
130         netfs_root_node->nn_stat.st_mode = S_IFDIR | (underlying_stat.st_mode & ~S_IFMT & ~S_ITRANS);
131
132         for (;;)
133                 netfs_server_loop ();
134 }