lock_mtab();
if ((mtab = setmntent(MOUNTED, "a+")) == NULL) {
+ unlock_mtab();
fprintf(stderr, "Can't open " MOUNTED);
return 1;
}
}
}
-static void mount_error(char *node)
+static void mount_error(char *mntpnt, char *node)
{
switch(errno) {
case ENOTDIR:
- fprintf(stderr, "%s: mount point %s is not a directory\n", progname, node);
+ fprintf(stderr, "%s: mount point %s is not a directory\n",
+ progname, mntpnt);
break;
case EBUSY:
- fprintf(stderr, "%s: %s is already mounted or busy\n", progname, node);
+ fprintf(stderr, "%s: %s is already mounted or busy\n",
+ progname, mntpnt);
break;
case ENOENT:
- fprintf(stderr, "%s: mount point %s does not exist\n", progname, node);
+ if (node) {
+ fprintf(stderr, "%s: %s failed, reason given by server: %s\n",
+ progname, node, strerror(errno));
+ } else
+ fprintf(stderr, "%s: mount point %s does not exist\n",
+ progname, mntpnt);
break;
default:
fprintf(stderr, "%s: %s\n", progname, strerror(errno));
}
}
+static int chk_mountpoint(char *mount_point)
+{
+ struct stat sb;
+
+ if (stat(mount_point, &sb) < 0){
+ mount_error(mount_point, NULL);
+ return 1;
+ }
+ if (S_ISDIR(sb.st_mode) == 0){
+ errno = ENOTDIR;
+ mount_error(mount_point, NULL);
+ return 1;
+ }
+ if (access(mount_point, X_OK) < 0) {
+ mount_error(mount_point, NULL);
+ return 1;
+ }
+
+ return 0;
+}
+
+extern u_short getport(
+ struct sockaddr_in *saddr,
+ u_long prog,
+ u_long vers,
+ u_int prot);
+
+static int probe_statd()
+{
+ struct sockaddr_in addr;
+ u_short port;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ port = getport(&addr, 100024, 1, IPPROTO_UDP);
+
+ if (port == 0)
+ return 0;
+ addr.sin_port = htons(port);
+
+ if (clnt_ping(&addr, 100024, 1, IPPROTO_UDP, NULL) <= 0)
+ return 0;
+
+ return 1;
+}
-static void start_statd()
+static int start_statd()
{
/* If /var/run/rpc.statd.pid exists and is non-empty,
* assume statd already running.
* else run that file (typically a shell script)
*/
struct stat stb;
- if (stat("/var/run/rpc.statd.pid", &stb) == 0 &&
- stb.st_size > 0)
- return;
+
+ if (probe_statd())
+ return 1;
#ifdef START_STATD
if (stat(START_STATD, &stb) ==0 &&
S_ISREG(stb.st_mode) &&
- (stb.st_mode & S_IXUSR))
+ (stb.st_mode & S_IXUSR)) {
system(START_STATD);
+ if (probe_statd())
+ return 1;
+ }
#endif
+ return 0;
}
int main(int argc, char *argv[])
{
int c, flags = 0, nfs_mount_vers = 0, mnt_err = 1, fake = 0;
char *spec, *mount_point, *extra_opts = NULL;
- char *mount_opts = NULL, *p;
+ char *mount_opts = NULL;
uid_t uid = getuid();
- progname = argv[0];
- if (!progname)
- exit(2);
-
- if ((p = strrchr(progname, '/')) != NULL)
- progname = p+1;
+ progname = basename(argv[0]);
if(!strncmp(progname, "umount", strlen("umount"))) {
if(argc < 2) {
umount_usage();
exit(1);
}
- exit(nfsumount(argc, argv) ? 0 : 1);
+ exit(nfsumount(argc, argv));
}
if(argv[1] && argv[1][0] == '-') {
}
}
+ if (chk_mountpoint(mount_point))
+ exit(EX_FAIL);
+
if (nfs_mount_vers == 4)
mnt_err = nfs4mount(spec, mount_point, &flags, &extra_opts, &mount_opts, 0);
else {
mnt_err = nfsmount(spec, mount_point, &flags,
&extra_opts, &mount_opts,
0, &need_statd);
- if (!mnt_err && !fake && need_statd)
- start_statd();
+ if (!mnt_err && !fake && need_statd) {
+ if (!start_statd()) {
+ fprintf(stderr,
+ "%s: rpc.statd is not running but is "
+ "required for remote locking\n"
+ " Either use \"-o nolocks\" to keep "
+ "locks local, or start statd.\n",
+ progname);
+ exit(1);
+ }
+ }
}
if (mnt_err)
mount_opts);
if (mnt_err) {
- mount_error(mount_point);
+ mount_error(mount_point, spec);
exit(EX_FAIL);
}
}