this adds the following 4 functions. see libnfs.h for details.
struct nfs_url *nfs_parse_url_full(struct nfs_context *nfs, char *url);
struct nfs_url *nfs_parse_url_dir(struct nfs_context *nfs, char *url);
struct nfs_url *nfs_parse_url_incomplete(struct nfs_context *nfs, char *url);
void nfs_destroy_url(struct nfs_url *url);
Signed-off-by: Peter Lieven <pl@kamp.de>
int main(int argc, char *argv[])
{
struct nfs_context *nfs = NULL;
- int i, ret, res;
+ int i, ret = 1, res;
uint64_t offset;
struct client client;
struct nfsfh *nfsfh;
struct statvfs stvfs;
+ struct nfs_url *url;
exports export, tmp;
- const char *url = NULL;
char *server = NULL, *path = NULL, *strp;
#ifdef WIN32
aros_init_socket();
#endif
- url = argv[argc - 1];
-
- if (url == NULL) {
+ if (argc < 2) {
fprintf(stderr, "No URL specified.\n");
- print_usage();
- exit(10);
+ goto finished;
}
for (i=1; i < argc -1; i++) {
} else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--summary")) {
summary++;
} else {
- print_usage();
- exit(10);
+ goto finished;
}
}
- if (strncmp(url, "nfs://", 6)) {
- fprintf(stderr, "Invalid URL specified.\n");
- print_usage();
- exit(10);
- }
-
- server = strdup(url + 6);
- if (server == NULL) {
- fprintf(stderr, "Failed to strdup server string\n");
- exit(10);
- }
- if (server[0] == '/' || server[0] == '\0') {
- fprintf(stderr, "Invalid server string.\n");
- free(server);
- exit(10);
- }
- strp = strchr(server, '/');
- if (strp == NULL) {
- fprintf(stderr, "Invalid URL specified.\n");
- print_usage();
- free(server);
- exit(10);
- }
- path = strdup(strp);
- if (path == NULL) {
- fprintf(stderr, "Failed to strdup server string\n");
- free(server);
- exit(10);
- }
- if (path[0] != '/') {
- fprintf(stderr, "Invalid path.\n");
- free(server);
- free(path);
- exit(10);
- }
- *strp = 0;
-
- client.server = server;
- client.export = path;
- client.is_finished = 0;
-
nfs = nfs_init_context();
if (nfs == NULL) {
printf("failed to init context\n");
goto finished;
}
- ret = nfs_mount(nfs, client.server, client.export);
- if (ret != 0) {
- printf("Failed to mount nfs share : %s\n", nfs_get_error(nfs));
+ url = nfs_parse_url_dir(nfs, argv[argc - 1]);
+ if (url == NULL) {
+ fprintf(stderr, "%s\n", nfs_get_error(nfs));
+ goto finished;
+ }
+
+ client.server = url->server;
+ client.export = url->path;
+ client.is_finished = 0;
+
+ if (nfs_mount(nfs, client.server, client.export) != 0) {
+ fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs));
goto finished;
}
process_dir(nfs, "", 16);
if (summary) {
- ret = nfs_statvfs(nfs, "/", &stvfs);
- if (ret != 0) {
+ if (nfs_statvfs(nfs, "/", &stvfs) != 0) {
goto finished;
}
printf("\n%12" PRId64 " of %12" PRId64 " bytes free.\n",
stvfs.f_frsize * stvfs.f_bfree, stvfs.f_frsize * stvfs.f_blocks);
}
+
+ ret = 0;
+
finished:
+ if (ret) {
+ print_usage();
+ }
free(server);
free(path);
+ nfs_destroy_url(url);
if (nfs != NULL) {
nfs_destroy_context(nfs);
}
- return 0;
+ return ret;
}
struct nfs_context;
struct rpc_context;
+struct nfs_url {
+ char *server;
+ char *path;
+ char *file;
+};
+
#if defined(WIN32)
#define EXTERN __declspec( dllexport )
#else
EXTERN void nfs_destroy_context(struct nfs_context *nfs);
+/*
+ * Parse a complete NFS URL including, server, path and
+ * filename. Fail if any component is missing.
+ */
+EXTERN struct nfs_url *nfs_parse_url_full(struct nfs_context *nfs, const char *url);
+
+/*
+ * Parse an NFS URL, but do not split path and file. File
+ * in the resulting struct remains NULL.
+ */
+EXTERN struct nfs_url *nfs_parse_url_dir(struct nfs_context *nfs, const char *url);
+
+/*
+ * Parse an NFS URL, but do not fail if file, path or even server is missing.
+ * Check elements of the resulting struct for NULL.
+ */
+EXTERN struct nfs_url *nfs_parse_url_incomplete(struct nfs_context *nfs, const char *url);
+
+
+/*
+ * Free the URL struct returned by the nfs_parse_url_* functions.
+ */
+EXTERN void nfs_destroy_url(struct nfs_url *url);
+
+
struct nfsfh;
/*
return rpc_get_error(nfs->rpc);
};
+static struct nfs_url *nfs_parse_url(struct nfs_context *nfs, char *url, int dir, int incomplete)
+{
+ struct nfs_url *urls;
+ char *strp, *flagsp, *strp2;
+
+ if (strncmp(url, "nfs://", 6)) {
+ rpc_set_error(nfs->rpc, "Invalid URL specified");
+ return NULL;
+ }
+
+ urls = malloc(sizeof(struct nfs_url));
+ if (urls == NULL) {
+ rpc_set_error(nfs->rpc, "Out of memory");
+ return NULL;
+ }
+
+ urls->server = strdup(url + 6);
+ if (urls->server == NULL) {
+ nfs_destroy_url(urls);
+ rpc_set_error(nfs->rpc, "Out of memory");
+ return NULL;
+ }
+
+ if (urls->server[0] == '/' || urls->server[0] == '\0' ||
+ urls->server[0] == '?') {
+ if (incomplete) {
+ flagsp = strchr(urls->server, '?');
+ goto flags;
+ }
+ nfs_destroy_url(urls);
+ rpc_set_error(nfs->rpc, "Invalid server string");
+ return NULL;
+ }
+
+ strp = strchr(urls->server, '/');
+ if (strp == NULL) {
+ if (incomplete) {
+ flagsp = strchr(urls->server, '?');
+ goto flags;
+ }
+ nfs_destroy_url(urls);
+ rpc_set_error(nfs->rpc, "Incomplete or invalid URL specified.");
+ return NULL;
+ }
+
+ urls->path = strdup(strp);
+ if (urls->path == NULL) {
+ nfs_destroy_url(urls);
+ rpc_set_error(nfs->rpc, "Out of memory");
+ return NULL;
+ }
+ *strp = 0;
+
+ if (dir) {
+ flagsp = strchr(urls->path, '?');
+ goto flags;
+ }
+
+ strp = strrchr(urls->path, '/');
+ if (strp == NULL) {
+ if (incomplete) {
+ flagsp = strchr(urls->path, '?');
+ goto flags;
+ }
+ nfs_destroy_url(urls);
+ rpc_set_error(nfs->rpc, "Incomplete or invalid URL specified.");
+ return NULL;
+ }
+ urls->file = strdup(strp);
+ if (urls->path == NULL) {
+ nfs_destroy_url(urls);
+ rpc_set_error(nfs->rpc, "Out of memory");
+ return NULL;
+ }
+ *strp = 0;
+ flagsp = strchr(urls->file, '?');
+
+flags:
+ if (flagsp) {
+ *flagsp = 0;
+ }
+
+ if (urls->file && !strlen(urls->file)) {
+ free(urls->file);
+ urls->file = NULL;
+ if (!incomplete) {
+ nfs_destroy_url(urls);
+ rpc_set_error(nfs->rpc, "Incomplete or invalid URL specified.");
+ return NULL;
+ }
+ }
+
+ if (urls->server && strlen(urls->server) <= 1) {
+ free(urls->server);
+ urls->server = NULL;
+ }
+
+ while (flagsp != NULL && *(flagsp+1) != 0) {
+ strp = flagsp + 1;
+ flagsp = strchr(strp, '&');
+ if (flagsp) {
+ *flagsp = 0;
+ }
+ strp2 = strchr(strp, '=');
+ if (strp2) {
+ *strp2 = 0;
+ strp2++;
+ }
+ }
+
+ return urls;
+}
+
+struct nfs_url *nfs_parse_url_full(struct nfs_context *nfs, const char *url)
+{
+ return nfs_parse_url(nfs, url, 0, 0);
+}
+
+struct nfs_url *nfs_parse_url_dir(struct nfs_context *nfs, const char *url)
+{
+ return nfs_parse_url(nfs, url, 1, 0);
+}
+
+struct nfs_url *nfs_parse_url_incomplete(struct nfs_context *nfs, const char *url)
+{
+ return nfs_parse_url(nfs, url, 0, 1);
+}
+
+
+void nfs_destroy_url(struct nfs_url *url)
+{
+ if (url) {
+ free(url->server);
+ free(url->path);
+ free(url->file);
+ }
+ free(url);
+}
+
struct nfs_context *nfs_init_context(void)
{
struct nfs_context *nfs;