+ for (;;) {
+ if (sleep(secs))
+ break;
+ secs <<= 1;
+ if (secs > 120)
+ secs = 120;
+
+ if (try_mount(spec, node, type, flags, options,
+ fake, extra_opts))
+ return EX_SUCCESS;
+
+ if (is_permanent_error(errno))
+ break;
+
+ if (time(NULL) > timeout)
+ break;
+
+ sys_mount_errors(hostname, errno, 1, 1);
+ };
+
+ sys_mount_errors(hostname, errno, 1, 0);
+ return EX_FAIL;
+}
+
+/*
+ * Handle "background" NFS mount
+ *
+ * Returns a valid mount command exit code.
+ */
+static int nfsmount_bg(const char *spec, const char *node,
+ const char *type, char *hostname, int flags,
+ struct mount_options *options,
+ int fake, int child, char **extra_opts)
+{
+ if (!child)
+ return nfsmount_parent(spec, node, type, hostname, flags,
+ options, fake, extra_opts);
+ else
+ return nfsmount_child(spec, node, type, hostname, flags,
+ options, fake, extra_opts);
+}
+
+/**
+ * nfsmount_string - Mount an NFS file system using C string options
+ * @spec: C string specifying remote share to mount ("hostname:path")
+ * @node: C string pathname of local mounted-on directory
+ * @type: C string that represents file system type ("nfs" or "nfs4")
+ * @flags: MS_ style mount flags
+ * @extra_opts: pointer to C string containing fs-specific mount options
+ * (input and output argument)
+ * @fake: flag indicating whether to carry out the whole operation
+ * @child: one if this is a mount daemon (bg)
+ */
+int nfsmount_string(const char *spec, const char *node, const char *type,
+ int flags, char **extra_opts, int fake, int child)
+{
+ struct mount_options *options = NULL;
+ struct sockaddr_in saddr;
+ char *hostname;
+ int retval = EX_FAIL;
+
+ if (!parse_devname(spec, &hostname))
+ return retval;
+ if (!fill_ipv4_sockaddr(hostname, &saddr))
+ goto fail;
+
+ options = po_split(*extra_opts);
+ if (!options) {
+ nfs_error(_("%s: internal option parsing error"), progname);
+ goto fail;