* and listen for requests (using my_svc_run)
*
*/
-#include "config.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <sys/types.h>
#include <sys/select.h>
* Record is terminated with newline.
*
*/
-void cache_export_ent(char *domain, struct exportent *exp);
+int cache_export_ent(char *domain, struct exportent *exp);
char *lbuf = NULL;
qword_print(f, *client?client:"DEFAULT");
qword_eol(f);
- if (client && strcmp(ipaddr, client))
- mountlist_add(ipaddr, *client?client:"DEFAULT");
-
if (client) free(client);
}
goto out;
if (qword_get_int(&cp, &fsidtype) != 0)
goto out;
- if (fsidtype < 0 || fsidtype > 1)
+ if (fsidtype < 0 || fsidtype > 3)
goto out; /* unknown type */
if ((fsidlen = qword_get(&cp, fsid, 32)) <= 0)
goto out;
goto out;
memcpy(&fsidnum, fsid, 4);
break;
+
+ case 2: /* 12 bytes: 4 major, 4 minor, 4 inode
+ * This format is never actually used but was
+ * an historical accident
+ */
+ if (fsidlen != 12)
+ goto out;
+ memcpy(&dev, fsid, 4); major = ntohl(dev);
+ memcpy(&dev, fsid+4, 4); minor = ntohl(dev);
+ memcpy(&inode, fsid+8, 4);
+ break;
+
+ case 3: /* 8 bytes: 4 byte packed device number, 4 inode */
+ /* This is *host* endian, not net-byte-order, because
+ * no-one outside this host has any business interpreting it
+ */
+ if (fsidlen != 8)
+ goto out;
+ memcpy(&dev, fsid, 4);
+ memcpy(&inode, fsid+4, 4);
+ major = (dev & 0xfff00) >> 8;
+ minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
+ break;
+
}
auth_reload();
((exp->m_export.e_flags & NFSEXP_FSID) == 0 ||
exp->m_export.e_fsid != fsidnum))
continue;
- if (fsidtype == 0) {
+ if (fsidtype != 1) {
if (stb.st_ino != inode)
continue;
if (major != major(stb.st_dev) ||
qword_printint(f, found->m_export.e_anonuid);
qword_printint(f, found->m_export.e_anongid);
qword_printint(f, found->m_export.e_fsid);
- mountlist_add(dom, path);
}
qword_eol(f);
out:
* % echo $domain $path $[now+30*60] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel
*/
-void cache_export_ent(char *domain, struct exportent *exp)
+int cache_export_ent(char *domain, struct exportent *exp)
{
-
+ int err;
FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
if (!f)
- return;
+ return -1;
qword_print(f, domain);
qword_print(f, exp->e_path);
qword_printint(f, exp->e_anonuid);
qword_printint(f, exp->e_anongid);
qword_printint(f, exp->e_fsid);
- qword_eol(f);
+ err = qword_eol(f);
fclose(f);
-
- mountlist_add(domain, exp->e_path);
+ return err;
}
-void cache_export(nfs_export *exp)
+int cache_export(nfs_export *exp)
{
+ int err;
FILE *f;
f = fopen("/proc/net/rpc/auth.unix.ip/channel", "w");
if (!f)
- return;
+ return -1;
qword_print(f, "nfsd");
qword_print(f, inet_ntoa(exp->m_client->m_addrlist[0]));
qword_printint(f, time(0)+30*60);
qword_print(f, exp->m_client->m_hostname);
- qword_eol(f);
+ err = qword_eol(f);
fclose(f);
- if (strcmp(inet_ntoa(exp->m_client->m_addrlist[0]), exp->m_client->m_hostname))
- mountlist_add(inet_ntoa(exp->m_client->m_addrlist[0]), exp->m_client->m_hostname);
-
- cache_export_ent(exp->m_client->m_hostname, &exp->m_export);
+ err = cache_export_ent(exp->m_client->m_hostname, &exp->m_export)
+ || err;
+ return err;
}
/* Get a filehandle.
qword_print(f, exp->m_client->m_hostname);
qword_print(f, p);
qword_printint(f, len);
- qword_eol(f);
+ failed = qword_eol(f);
- failed = (fgets(buf, sizeof(buf), f) == NULL);
+ if (!failed)
+ failed = (fgets(buf, sizeof(buf), f) == NULL);
fclose(f);
if (failed)
return NULL;
memset(fh.fh_handle, 0, sizeof(fh.fh_handle));
- fh.fh_size = qword_get(&bp, fh.fh_handle, NFS3_FHSIZE);
+ fh.fh_size = qword_get(&bp, (char *)fh.fh_handle, NFS3_FHSIZE);
return &fh;
}