| diff -up nfs-utils-1.3.0/utils/mountd/cache.c.orig nfs-utils-1.3.0/utils/mountd/cache.c |
| --- nfs-utils-1.3.0/utils/mountd/cache.c.orig 2017-01-06 09:31:53.155412013 -0500 |
| +++ nfs-utils-1.3.0/utils/mountd/cache.c 2017-01-06 09:50:52.438190388 -0500 |
| @@ -61,15 +61,13 @@ enum nfsd_fsid { |
| * Record is terminated with newline. |
| * |
| */ |
| -static int cache_export_ent(char *domain, struct exportent *exp, char *p); |
| +static int cache_export_ent(char *buf, int buflen, char *domain, struct exportent *exp, char *path); |
| |
| #define INITIAL_MANAGED_GROUPS 100 |
| |
| -char *lbuf = NULL; |
| -int lbuflen = 0; |
| extern int use_ipaddr; |
| |
| -static void auth_unix_ip(FILE *f) |
| +static void auth_unix_ip(int f) |
| { |
| /* requests are |
| * class IP-ADDR |
| @@ -78,23 +76,26 @@ static void auth_unix_ip(FILE *f) |
| * |
| * "nfsd" IP-ADDR expiry domainname |
| */ |
| - char *cp; |
| char class[20]; |
| char ipaddr[INET6_ADDRSTRLEN + 1]; |
| char *client = NULL; |
| struct addrinfo *tmp = NULL; |
| - if (readline(fileno(f), &lbuf, &lbuflen) != 1) |
| - return; |
| + char buf[RPC_CHAN_BUF_SIZE], *bp; |
| + int blen; |
| + |
| + blen = read(f, buf, sizeof(buf)); |
| + if (blen <= 0 || buf[blen-1] != '\n') return; |
| + buf[blen-1] = 0; |
| |
| - xlog(D_CALL, "auth_unix_ip: inbuf '%s'", lbuf); |
| + xlog(D_CALL, "auth_unix_ip: inbuf '%s'", buf); |
| |
| - cp = lbuf; |
| + bp = buf; |
| |
| - if (qword_get(&cp, class, 20) <= 0 || |
| + if (qword_get(&bp, class, 20) <= 0 || |
| strcmp(class, "nfsd") != 0) |
| return; |
| |
| - if (qword_get(&cp, ipaddr, sizeof(ipaddr) - 1) <= 0) |
| + if (qword_get(&bp, ipaddr, sizeof(ipaddr) - 1) <= 0) |
| return; |
| |
| tmp = host_pton(ipaddr); |
| @@ -113,16 +114,20 @@ static void auth_unix_ip(FILE *f) |
| freeaddrinfo(ai); |
| } |
| } |
| - qword_print(f, "nfsd"); |
| - qword_print(f, ipaddr); |
| - qword_printtimefrom(f, DEFAULT_TTL); |
| + bp = buf; blen = sizeof(buf); |
| + qword_add(&bp, &blen, "nfsd"); |
| + qword_add(&bp, &blen, ipaddr); |
| + qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL); |
| if (use_ipaddr) { |
| memmove(ipaddr + 1, ipaddr, strlen(ipaddr) + 1); |
| ipaddr[0] = '$'; |
| - qword_print(f, ipaddr); |
| + qword_add(&bp, &blen, ipaddr); |
| } else if (client) |
| - qword_print(f, *client?client:"DEFAULT"); |
| - qword_eol(f); |
| + qword_add(&bp, &blen, *client?client:"DEFAULT"); |
| + qword_addeol(&bp, &blen); |
| + if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) |
| + xlog(L_ERROR, "auth_unix_ip: error writing reply"); |
| + |
| xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT"); |
| |
| free(client); |
| @@ -130,7 +135,7 @@ static void auth_unix_ip(FILE *f) |
| |
| } |
| |
| -static void auth_unix_gid(FILE *f) |
| +static void auth_unix_gid(int f) |
| { |
| /* Request are |
| * uid |
| @@ -144,7 +149,8 @@ static void auth_unix_gid(FILE *f) |
| gid_t *more_groups; |
| int ngroups; |
| int rv, i; |
| - char *cp; |
| + char buf[RPC_CHAN_BUF_SIZE], *bp; |
| + int blen; |
| |
| if (groups_len == 0) { |
| groups = malloc(sizeof(gid_t) * INITIAL_MANAGED_GROUPS); |
| @@ -156,11 +162,12 @@ static void auth_unix_gid(FILE *f) |
| |
| ngroups = groups_len; |
| |
| - if (readline(fileno(f), &lbuf, &lbuflen) != 1) |
| - return; |
| + blen = read(f, buf, sizeof(buf)); |
| + if (blen <= 0 || buf[blen-1] != '\n') return; |
| + buf[blen-1] = 0; |
| |
| - cp = lbuf; |
| - if (qword_get_uint(&cp, &uid) != 0) |
| + bp = buf; |
| + if (qword_get_uint(&bp, &uid) != 0) |
| return; |
| |
| pw = getpwuid(uid); |
| @@ -180,15 +187,19 @@ static void auth_unix_gid(FILE *f) |
| } |
| } |
| } |
| - qword_printuint(f, uid); |
| - qword_printtimefrom(f, DEFAULT_TTL); |
| + |
| + bp = buf; blen = sizeof(buf); |
| + qword_adduint(&bp, &blen, uid); |
| + qword_adduint(&bp, &blen, time(0) + DEFAULT_TTL); |
| if (rv >= 0) { |
| - qword_printuint(f, ngroups); |
| + qword_adduint(&bp, &blen, ngroups); |
| for (i=0; i<ngroups; i++) |
| - qword_printuint(f, groups[i]); |
| + qword_adduint(&bp, &blen, groups[i]); |
| } else |
| - qword_printuint(f, 0); |
| - qword_eol(f); |
| + qword_adduint(&bp, &blen, 0); |
| + qword_addeol(&bp, &blen); |
| + if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) |
| + xlog(L_ERROR, "auth_unix_gid: error writing reply"); |
| } |
| |
| #if USE_BLKID |
| @@ -578,14 +589,13 @@ static struct addrinfo *lookup_client_ad |
| return ret; |
| } |
| |
| -static void nfsd_fh(FILE *f) |
| +static void nfsd_fh(int f) |
| { |
| /* request are: |
| * domain fsidtype fsid |
| * interpret fsid, find export point and options, and write: |
| * domain fsidtype fsid expiry path |
| */ |
| - char *cp; |
| char *dom; |
| int fsidtype; |
| int fsidlen; |
| @@ -597,24 +607,27 @@ static void nfsd_fh(FILE *f) |
| nfs_export *exp; |
| int i; |
| int dev_missing = 0; |
| + char buf[RPC_CHAN_BUF_SIZE], *bp; |
| + int blen; |
| |
| - if (readline(fileno(f), &lbuf, &lbuflen) != 1) |
| - return; |
| + blen = read(f, buf, sizeof(buf)); |
| + if (blen <= 0 || buf[blen-1] != '\n') return; |
| + buf[blen-1] = 0; |
| |
| - xlog(D_CALL, "nfsd_fh: inbuf '%s'", lbuf); |
| + xlog(D_CALL, "nfsd_fh: inbuf '%s'", buf); |
| |
| - cp = lbuf; |
| + bp = buf; |
| |
| - dom = malloc(strlen(cp)); |
| + dom = malloc(blen); |
| if (dom == NULL) |
| return; |
| - if (qword_get(&cp, dom, strlen(cp)) <= 0) |
| + if (qword_get(&bp, dom, blen) <= 0) |
| goto out; |
| - if (qword_get_int(&cp, &fsidtype) != 0) |
| + if (qword_get_int(&bp, &fsidtype) != 0) |
| goto out; |
| if (fsidtype < 0 || fsidtype > 7) |
| goto out; /* unknown type */ |
| - if ((fsidlen = qword_get(&cp, fsid, 32)) <= 0) |
| + if ((fsidlen = qword_get(&bp, fsid, 32)) <= 0) |
| goto out; |
| if (parse_fsid(fsidtype, fsidlen, fsid, &parsed)) |
| goto out; |
| @@ -715,12 +728,13 @@ static void nfsd_fh(FILE *f) |
| } |
| |
| if (found) |
| - if (cache_export_ent(dom, found, found_path) < 0) |
| + if (cache_export_ent(buf, sizeof(buf), dom, found, found_path) < 0) |
| found = 0; |
| |
| - qword_print(f, dom); |
| - qword_printint(f, fsidtype); |
| - qword_printhex(f, fsid, fsidlen); |
| + bp = buf; blen = sizeof(buf); |
| + qword_add(&bp, &blen, dom); |
| + qword_addint(&bp, &blen, fsidtype); |
| + qword_addhex(&bp, &blen, fsid, fsidlen); |
| /* The fsid -> path lookup can be quite expensive as it |
| * potentially stats and reads lots of devices, and some of those |
| * might have spun-down. The Answer is not likely to |
| @@ -729,20 +743,21 @@ static void nfsd_fh(FILE *f) |
| * timeout. Maybe this should be configurable on the command |
| * line. |
| */ |
| - qword_printint(f, 0x7fffffff); |
| + qword_addint(&bp, &blen, 0x7fffffff); |
| if (found) |
| - qword_print(f, found_path); |
| - qword_eol(f); |
| - out: |
| + qword_add(&bp, &blen, found_path); |
| + qword_addeol(&bp, &blen); |
| + if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) |
| + xlog(L_ERROR, "nfsd_fh: error writing reply"); |
| +out: |
| if (found_path) |
| free(found_path); |
| freeaddrinfo(ai); |
| free(dom); |
| xlog(D_CALL, "nfsd_fh: found %p path %s", found, found ? found->e_path : NULL); |
| - return; |
| } |
| |
| -static void write_fsloc(FILE *f, struct exportent *ep) |
| +static void write_fsloc(char **bp, int *blen, struct exportent *ep) |
| { |
| struct servers *servers; |
| |
| @@ -752,20 +767,20 @@ static void write_fsloc(FILE *f, struct |
| servers = replicas_lookup(ep->e_fslocmethod, ep->e_fslocdata); |
| if (!servers) |
| return; |
| - qword_print(f, "fsloc"); |
| - qword_printint(f, servers->h_num); |
| + qword_add(bp, blen, "fsloc"); |
| + qword_addint(bp, blen, servers->h_num); |
| if (servers->h_num >= 0) { |
| int i; |
| for (i=0; i<servers->h_num; i++) { |
| - qword_print(f, servers->h_mp[i]->h_host); |
| - qword_print(f, servers->h_mp[i]->h_path); |
| + qword_add(bp, blen, servers->h_mp[i]->h_host); |
| + qword_add(bp, blen, servers->h_mp[i]->h_path); |
| } |
| } |
| - qword_printint(f, servers->h_referral); |
| + qword_addint(bp, blen, servers->h_referral); |
| release_replicas(servers); |
| } |
| |
| -static void write_secinfo(FILE *f, struct exportent *ep, int flag_mask) |
| +static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask) |
| { |
| struct sec_entry *p; |
| |
| @@ -776,45 +791,52 @@ static void write_secinfo(FILE *f, struc |
| return; |
| } |
| fix_pseudoflavor_flags(ep); |
| - qword_print(f, "secinfo"); |
| - qword_printint(f, p - ep->e_secinfo); |
| + qword_add(bp, blen, "secinfo"); |
| + qword_addint(bp, blen, p - ep->e_secinfo); |
| for (p = ep->e_secinfo; p->flav; p++) { |
| - qword_printint(f, p->flav->fnum); |
| - qword_printint(f, p->flags & flag_mask); |
| + qword_addint(bp, blen, p->flav->fnum); |
| + qword_addint(bp, blen, p->flags & flag_mask); |
| } |
| |
| } |
| |
| -static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *exp) |
| +static int dump_to_cache(int f, char *buf, int buflen, char *domain, char *path, struct exportent *exp) |
| { |
| - qword_print(f, domain); |
| - qword_print(f, path); |
| + char *bp = buf; |
| + int blen = buflen; |
| + time_t now = time(0); |
| + |
| + qword_add(&bp, &blen, domain); |
| + qword_add(&bp, &blen, path); |
| if (exp) { |
| int different_fs = strcmp(path, exp->e_path) != 0; |
| int flag_mask = different_fs ? ~NFSEXP_FSID : ~0; |
| |
| - qword_printtimefrom(f, exp->e_ttl); |
| - qword_printint(f, exp->e_flags & flag_mask); |
| - qword_printint(f, exp->e_anonuid); |
| - qword_printint(f, exp->e_anongid); |
| - qword_printint(f, exp->e_fsid); |
| - write_fsloc(f, exp); |
| - write_secinfo(f, exp, flag_mask); |
| - if (exp->e_uuid == NULL || different_fs) { |
| - char u[16]; |
| - if (uuid_by_path(path, 0, 16, u)) { |
| - qword_print(f, "uuid"); |
| - qword_printhex(f, u, 16); |
| - } |
| - } else { |
| - char u[16]; |
| - get_uuid(exp->e_uuid, 16, u); |
| - qword_print(f, "uuid"); |
| - qword_printhex(f, u, 16); |
| - } |
| + qword_adduint(&bp, &blen, now + exp->e_ttl); |
| + qword_addint(&bp, &blen, exp->e_flags & flag_mask); |
| + qword_addint(&bp, &blen, exp->e_anonuid); |
| + qword_addint(&bp, &blen, exp->e_anongid); |
| + qword_addint(&bp, &blen, exp->e_fsid); |
| + write_fsloc(&bp, &blen, exp); |
| + write_secinfo(&bp, &blen, exp, flag_mask); |
| + if (exp->e_uuid == NULL || different_fs) { |
| + char u[16]; |
| + if (uuid_by_path(path, 0, 16, u)) { |
| + qword_add(&bp, &blen, "uuid"); |
| + qword_addhex(&bp, &blen, u, 16); |
| + } |
| + } else { |
| + char u[16]; |
| + get_uuid(exp->e_uuid, 16, u); |
| + qword_add(&bp, &blen, "uuid"); |
| + qword_addhex(&bp, &blen, u, 16); |
| + } |
| } else |
| - qword_printtimefrom(f, DEFAULT_TTL); |
| - return qword_eol(f); |
| + qword_adduint(&bp, &blen, now + DEFAULT_TTL); |
| + qword_addeol(&bp, &blen); |
| + if (blen <= 0) return -1; |
| + if (write(f, buf, bp - buf) != bp - buf) return -1; |
| + return 0; |
| } |
| |
| static nfs_export * |
| @@ -1164,27 +1186,27 @@ static struct exportent *lookup_junction |
| return exp; |
| } |
| |
| -static void lookup_nonexport(FILE *f, char *dom, char *path, |
| +static void lookup_nonexport(int f, char *buf, int buflen, char *dom, char *path, |
| struct addrinfo *ai) |
| { |
| struct exportent *eep; |
| |
| eep = lookup_junction(dom, path, ai); |
| - dump_to_cache(f, dom, path, eep); |
| + dump_to_cache(f, buf, buflen, dom, path, eep); |
| if (eep == NULL) |
| return; |
| exportent_release(eep); |
| free(eep); |
| } |
| #else /* !HAVE_NFS_PLUGIN_H */ |
| -static void lookup_nonexport(FILE *f, char *dom, char *path, |
| +static void lookup_nonexport(int f, char *buf, int buflen, char *dom, char *path, |
| struct addrinfo *UNUSED(ai)) |
| { |
| - dump_to_cache(f, dom, path, NULL); |
| + dump_to_cache(f, buf, buflen, dom, path, NULL); |
| } |
| #endif /* !HAVE_NFS_PLUGIN_H */ |
| |
| -static void nfsd_export(FILE *f) |
| +static void nfsd_export(int f) |
| { |
| /* requests are: |
| * domain path |
| @@ -1192,26 +1214,28 @@ static void nfsd_export(FILE *f) |
| * domain path expiry flags anonuid anongid fsid |
| */ |
| |
| - char *cp; |
| char *dom, *path; |
| nfs_export *found = NULL; |
| struct addrinfo *ai = NULL; |
| + char buf[RPC_CHAN_BUF_SIZE], *bp; |
| + int blen; |
| |
| - if (readline(fileno(f), &lbuf, &lbuflen) != 1) |
| - return; |
| - |
| - xlog(D_CALL, "nfsd_export: inbuf '%s'", lbuf); |
| - |
| - cp = lbuf; |
| - dom = malloc(strlen(cp)); |
| - path = malloc(strlen(cp)); |
| + blen = read(f, buf, sizeof(buf)); |
| + if (blen <= 0 || buf[blen-1] != '\n') return; |
| + buf[blen-1] = 0; |
| + |
| + xlog(D_CALL, "nfsd_export: inbuf '%s'", buf); |
| + |
| + bp = buf; |
| + dom = malloc(blen); |
| + path = malloc(blen); |
| |
| if (!dom || !path) |
| goto out; |
| |
| - if (qword_get(&cp, dom, strlen(lbuf)) <= 0) |
| + if (qword_get(&bp, dom, blen) <= 0) |
| goto out; |
| - if (qword_get(&cp, path, strlen(lbuf)) <= 0) |
| + if (qword_get(&bp, path, blen) <= 0) |
| goto out; |
| |
| auth_reload(); |
| @@ -1225,14 +1249,14 @@ static void nfsd_export(FILE *f) |
| found = lookup_export(dom, path, ai); |
| |
| if (found) { |
| - if (dump_to_cache(f, dom, path, &found->m_export) < 0) { |
| + if (dump_to_cache(f, buf, sizeof(buf), dom, path, &found->m_export) < 0) { |
| xlog(L_WARNING, |
| "Cannot export %s, possibly unsupported filesystem" |
| " or fsid= required", path); |
| - dump_to_cache(f, dom, path, NULL); |
| + dump_to_cache(f, buf, sizeof(buf), dom, path, NULL); |
| } |
| } else |
| - lookup_nonexport(f, dom, path, ai); |
| + lookup_nonexport(f, buf, sizeof(buf), dom, path, ai); |
| |
| out: |
| xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL); |
| @@ -1244,15 +1268,14 @@ static void nfsd_export(FILE *f) |
| |
| struct { |
| char *cache_name; |
| - void (*cache_handle)(FILE *f); |
| - FILE *f; |
| - char vbuf[RPC_CHAN_BUF_SIZE]; |
| + void (*cache_handle)(int f); |
| + int f; |
| } cachelist[] = { |
| - { "auth.unix.ip", auth_unix_ip, NULL, ""}, |
| - { "auth.unix.gid", auth_unix_gid, NULL, ""}, |
| - { "nfsd.export", nfsd_export, NULL, ""}, |
| - { "nfsd.fh", nfsd_fh, NULL, ""}, |
| - { NULL, NULL, NULL, ""} |
| + { "auth.unix.ip", auth_unix_ip, -1 }, |
| + { "auth.unix.gid", auth_unix_gid, -1 }, |
| + { "nfsd.export", nfsd_export, -1 }, |
| + { "nfsd.fh", nfsd_fh, -1 }, |
| + { NULL, NULL, -1 } |
| }; |
| |
| extern int manage_gids; |
| @@ -1269,11 +1292,7 @@ void cache_open(void) |
| if (!manage_gids && cachelist[i].cache_handle == auth_unix_gid) |
| continue; |
| sprintf(path, "/proc/net/rpc/%s/channel", cachelist[i].cache_name); |
| - cachelist[i].f = fopen(path, "r+"); |
| - if (cachelist[i].f != NULL) { |
| - setvbuf(cachelist[i].f, cachelist[i].vbuf, _IOLBF, |
| - RPC_CHAN_BUF_SIZE); |
| - } |
| + cachelist[i].f = open(path, O_RDWR); |
| } |
| } |
| |
| @@ -1285,8 +1304,8 @@ void cache_set_fds(fd_set *fdset) |
| { |
| int i; |
| for (i=0; cachelist[i].cache_name; i++) { |
| - if (cachelist[i].f) |
| - FD_SET(fileno(cachelist[i].f), fdset); |
| + if (cachelist[i].f >= 0) |
| + FD_SET(cachelist[i].f, fdset); |
| } |
| } |
| |
| @@ -1299,11 +1318,11 @@ int cache_process_req(fd_set *readfds) |
| int i; |
| int cnt = 0; |
| for (i=0; cachelist[i].cache_name; i++) { |
| - if (cachelist[i].f != NULL && |
| - FD_ISSET(fileno(cachelist[i].f), readfds)) { |
| + if (cachelist[i].f >= 0 && |
| + FD_ISSET(cachelist[i].f, readfds)) { |
| cnt++; |
| cachelist[i].cache_handle(cachelist[i].f); |
| - FD_CLR(fileno(cachelist[i].f), readfds); |
| + FD_CLR(cachelist[i].f, readfds); |
| } |
| } |
| return cnt; |
| @@ -1316,14 +1335,14 @@ int cache_process_req(fd_set *readfds) |
| * % echo $domain $path $[now+DEFAULT_TTL] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel |
| */ |
| |
| -static int cache_export_ent(char *domain, struct exportent *exp, char *path) |
| +static int cache_export_ent(char *buf, int buflen, char *domain, struct exportent *exp, char *path) |
| { |
| - int err; |
| - FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w"); |
| - if (!f) |
| - return -1; |
| + int f, err; |
| + |
| + f = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY); |
| + if (f < 0) return -1; |
| |
| - err = dump_to_cache(f, domain, exp->e_path, exp); |
| + err = dump_to_cache(f, buf, buflen, domain, exp->e_path, exp); |
| if (err) { |
| xlog(L_WARNING, |
| "Cannot export %s, possibly unsupported filesystem or" |
| @@ -1364,13 +1383,13 @@ static int cache_export_ent(char *domain |
| continue; |
| dev = stb.st_dev; |
| path[l] = 0; |
| - dump_to_cache(f, domain, path, exp); |
| + dump_to_cache(f, buf, buflen, domain, path, exp); |
| path[l] = c; |
| } |
| break; |
| } |
| |
| - fclose(f); |
| + close(f); |
| return err; |
| } |
| |
| @@ -1381,27 +1400,25 @@ static int cache_export_ent(char *domain |
| */ |
| int cache_export(nfs_export *exp, char *path) |
| { |
| - char buf[INET6_ADDRSTRLEN]; |
| - int err; |
| - FILE *f; |
| + char ip[INET6_ADDRSTRLEN]; |
| + char buf[RPC_CHAN_BUF_SIZE], *bp; |
| + int blen, f; |
| |
| - f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w"); |
| - if (!f) |
| + f = open("/proc/net/rpc/auth.unix.ip/channel", O_WRONLY); |
| + if (f < 0) |
| return -1; |
| |
| + bp = buf, blen = sizeof(buf); |
| + qword_add(&bp, &blen, "nfsd"); |
| + qword_add(&bp, &blen, host_ntop(get_addrlist(exp->m_client, 0), ip, sizeof(ip))); |
| + qword_adduint(&bp, &blen, time(0) + exp->m_export.e_ttl); |
| + qword_add(&bp, &blen, exp->m_client->m_hostname); |
| + qword_addeol(&bp, &blen); |
| + if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) blen = -1; |
| + close(f); |
| + if (blen < 0) return -1; |
| |
| - qword_print(f, "nfsd"); |
| - qword_print(f, |
| - host_ntop(get_addrlist(exp->m_client, 0), buf, sizeof(buf))); |
| - qword_printtimefrom(f, exp->m_export.e_ttl); |
| - qword_print(f, exp->m_client->m_hostname); |
| - err = qword_eol(f); |
| - |
| - fclose(f); |
| - |
| - err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export, path) |
| - || err; |
| - return err; |
| + return cache_export_ent(buf, sizeof(buf), exp->m_client->m_hostname, &exp->m_export, path); |
| } |
| |
| /** |
| @@ -1420,27 +1437,33 @@ int cache_export(nfs_export *exp, char * |
| struct nfs_fh_len * |
| cache_get_filehandle(nfs_export *exp, int len, char *p) |
| { |
| - FILE *f = fopen("/proc/fs/nfsd/filehandle", "r+"); |
| - char buf[200]; |
| - char *bp = buf; |
| - int failed; |
| static struct nfs_fh_len fh; |
| + char buf[RPC_CHAN_BUF_SIZE], *bp; |
| + int blen, f; |
| |
| - if (!f) |
| - f = fopen("/proc/fs/nfs/filehandle", "r+"); |
| - if (!f) |
| + f = open("/proc/fs/nfsd/filehandle", O_RDWR); |
| + if (f < 0) { |
| + f = open("/proc/fs/nfs/filehandle", O_RDWR); |
| + if (f < 0) return NULL; |
| + } |
| + |
| + bp = buf, blen = sizeof(buf); |
| + qword_add(&bp, &blen, exp->m_client->m_hostname); |
| + qword_add(&bp, &blen, p); |
| + qword_addint(&bp, &blen, len); |
| + qword_addeol(&bp, &blen); |
| + if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) { |
| + close(f); |
| return NULL; |
| + } |
| + bp = buf; |
| + blen = read(f, buf, sizeof(buf)); |
| + close(f); |
| |
| - qword_print(f, exp->m_client->m_hostname); |
| - qword_print(f, p); |
| - qword_printint(f, len); |
| - failed = qword_eol(f); |
| - |
| - if (!failed) |
| - failed = (fgets(buf, sizeof(buf), f) == NULL); |
| - fclose(f); |
| - if (failed) |
| + if (blen <= 0 || buf[blen-1] != '\n') |
| return NULL; |
| + buf[blen-1] = 0; |
| + |
| memset(fh.fh_handle, 0, sizeof(fh.fh_handle)); |
| fh.fh_size = qword_get(&bp, (char *)fh.fh_handle, NFS3_FHSIZE); |
| return &fh; |