X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Flibnfs.c;h=cf9ad1321ad9a0a150aa78c5f94154c5283d617d;hb=bf817ee6942c488d0b41aede1074bf831ed8e316;hp=e99c561054b116914727e868fba83a9f513e9ec4;hpb=463d59bf8e5ff1a3ac27ab4fedf77b237394d1a6;p=deb_libnfs.git diff --git a/lib/libnfs.c b/lib/libnfs.c index e99c561..cf9ad13 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -173,6 +173,159 @@ char *nfs_get_error(struct nfs_context *nfs) return rpc_get_error(nfs->rpc); }; +static int nfs_set_context_args(struct nfs_context *nfs, char *arg, char *val) +{ + if (!strncmp(arg, "tcp-syncnt", 10)) { + rpc_set_tcp_syncnt(nfs_get_rpc_context(nfs), atoi(val)); + } else if (!strncmp(arg, "uid", 3)) { + rpc_set_uid(nfs_get_rpc_context(nfs), atoi(val)); + } else if (!strncmp(arg, "gid", 3)) { + rpc_set_gid(nfs_get_rpc_context(nfs), atoi(val)); + } + return 0; +} + +static struct nfs_url *nfs_parse_url(struct nfs_context *nfs, const 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; + } + + memset(urls, 0x00, sizeof(struct nfs_url)); + 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; + } + } + + while (flagsp != NULL && *(flagsp+1) != 0) { + strp = flagsp + 1; + flagsp = strchr(strp, '&'); + if (flagsp) { + *flagsp = 0; + } + strp2 = strchr(strp, '='); + if (strp2) { + *strp2 = 0; + strp2++; + nfs_set_context_args(nfs, strp, strp2); + } + } + + if (urls->server && strlen(urls->server) <= 1) { + free(urls->server); + urls->server = NULL; + } + + 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; @@ -457,6 +610,7 @@ static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_da { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; + struct FSINFO3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -471,7 +625,8 @@ static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_nfs_fsinfo_async(rpc, nfs_mount_9_cb, &nfs->rootfh, data) != 0) { + args.fsroot = nfs->rootfh; + if (rpc_nfs3_fsinfo_async(rpc, nfs_mount_9_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -500,7 +655,7 @@ static void nfs_mount_7_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_nfs_null_async(rpc, nfs_mount_8_cb, data) != 0) { + if (rpc_nfs3_null_async(rpc, nfs_mount_8_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -574,7 +729,7 @@ static void nfs_mount_5_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_mount_mnt_async(rpc, nfs_mount_6_cb, nfs->export, data) != 0) { + if (rpc_mount3_mnt_async(rpc, nfs_mount_6_cb, nfs->export, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -602,7 +757,7 @@ static void nfs_mount_4_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_mount_null_async(rpc, nfs_mount_5_cb, data) != 0) { + if (rpc_mount3_null_async(rpc, nfs_mount_5_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -1557,6 +1712,7 @@ static void nfs_fsync_cb(struct rpc_context *rpc, int status, void *command_data int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; + struct COMMIT3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { @@ -1568,7 +1724,10 @@ int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi data->cb = cb; data->private_data = private_data; - if (rpc_nfs_commit_async(nfs->rpc, nfs_fsync_cb, &nfsfh->fh, data) != 0) { + args.file = nfsfh->fh; + args.offset = 0; + args.count = 0; + if (rpc_nfs3_commit_async(nfs->rpc, nfs_fsync_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send COMMIT call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1635,7 +1794,7 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t l args.new_attributes.size.set_it = 1; args.new_attributes.size.set_size3_u.size = length; - if (rpc_nfs_setattr_async(nfs->rpc, nfs_ftruncate_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_ftruncate_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1734,7 +1893,7 @@ static int nfs_mkdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_da args.attributes.mode.set_it = 1; args.attributes.mode.set_mode3_u.mode = 0755; - if (rpc_nfs_mkdir_async(nfs->rpc, nfs_mkdir_cb, &args, data) != 0) { + if (rpc_nfs3_mkdir_async(nfs->rpc, nfs_mkdir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send MKDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1814,10 +1973,13 @@ static void nfs_rmdir_cb(struct rpc_context *rpc, int status, void *command_data static int nfs_rmdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { char *str = data->continue_data; - + RMDIR3args args; + str = &str[strlen(str) + 1]; - if (rpc_nfs_rmdir_async(nfs->rpc, nfs_rmdir_cb, &data->fh, str, data) != 0) { + args.object.dir = data->fh; + args.object.name = str; + if (rpc_nfs3_rmdir_async(nfs->rpc, nfs_rmdir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send RMDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2687,7 +2849,10 @@ static void nfs_statvfs_1_cb(struct rpc_context *rpc, int status, void *command_ static int nfs_statvfs_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { - if (rpc_nfs_fsstat_async(nfs->rpc, nfs_statvfs_1_cb, &data->fh, data) != 0) { + FSSTAT3args args; + + args.fsroot = data->fh; + if (rpc_nfs3_fsstat_async(nfs->rpc, nfs_statvfs_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send FSSTAT call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2817,7 +2982,7 @@ static int nfs_chmod_continue_internal(struct nfs_context *nfs, struct nfs_cb_da args.new_attributes.mode.set_it = 1; args.new_attributes.mode.set_mode3_u.mode = data->continue_int; - if (rpc_nfs_setattr_async(nfs->rpc, nfs_chmod_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_chmod_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2929,7 +3094,7 @@ static int nfs_chown_continue_internal(struct nfs_context *nfs, struct nfs_cb_da args.new_attributes.gid.set_gid3_u.gid = chown_data->gid; } - if (rpc_nfs_setattr_async(nfs->rpc, nfs_chown_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_chown_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3065,7 +3230,7 @@ static int nfs_utimes_continue_internal(struct nfs_context *nfs, struct nfs_cb_d args.new_attributes.mtime.set_it = SET_TO_SERVER_TIME; } - if (rpc_nfs_setattr_async(nfs->rpc, nfs_utimes_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_utimes_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3764,7 +3929,7 @@ static void mount_export_4_cb(struct rpc_context *rpc, int status, void *command return; } - if (rpc_mount_export_async(rpc, mount_export_5_cb, data) != 0) { + if (rpc_mount3_export_async(rpc, mount_export_5_cb, data) != 0) { data->cb(rpc, -ENOMEM, command_data, data->private_data); free_mount_cb_data(data); return;