]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mount/parse_opt.c
pdate addres for Free Software Foundation
[nfs-utils.git] / utils / mount / parse_opt.c
index f61d0dd6470da10448d7cc3d9df3f0762667c405..75a0daaef05f131e15fb2fb6d0499dfee9d3f082 100644 (file)
@@ -16,8 +16,8 @@
  *
  * You should have received a copy of the GNU General Public
  * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 0211-1301 USA
  *
  */
 
@@ -101,6 +101,37 @@ fail:
        return NULL;
 }
 
+static struct mount_option *option_dup(const struct mount_option *option)
+{
+       struct mount_option *new;
+
+       new = malloc(sizeof(*new));
+       if (!new)
+               return NULL;
+       
+       new->next = NULL;
+       new->prev = NULL;
+
+       new->keyword = strdup(option->keyword);
+       if (!new->keyword)
+               goto fail;
+
+       new->value = NULL;
+       if (option->value) {
+               new->value = strdup(option->value);
+               if (!new->value) {
+                       free(new->keyword);
+                       goto fail;
+               }
+       }
+
+       return new;
+
+fail:
+       free(new);
+       return NULL;
+}
+
 static void option_destroy(struct mount_option *option)
 {
        free(option->keyword);
@@ -228,6 +259,40 @@ fail:
        return NULL;
 }
 
+/**
+ * po_dup - duplicate an existing list of options
+ * @options: pointer to mount options
+ *
+ */
+struct mount_options *po_dup(struct mount_options *source)
+{
+       struct mount_options *target;
+       struct mount_option *current;
+
+       if (!source)
+               return NULL;
+
+       target = options_create();
+       if (options_empty(source) || target == NULL)
+               return target;
+
+       current = source->head;
+       while (target->count < source->count) {
+               struct mount_option *option;
+
+               option = option_dup(current);
+               if (!option) {
+                       po_destroy(target);
+                       return NULL;
+               }
+
+               options_tail_insert(target, option);
+               current = current->next;
+       }
+
+       return target;
+}
+
 /**
  * po_replace - replace mount options in one mount_options object with another
  * @target: pointer to previously instantiated object to replace
@@ -421,34 +486,39 @@ po_found_t po_get_numeric(struct mount_options *options, char *keyword, long *va
 #endif /* HAVE_STRTOL */
 
 /**
- * po_rightmost - determine the relative position of two options
+ * po_rightmost - determine the relative position of several options
  * @options: pointer to mount options
- * @key1: pointer to a C string containing an option keyword
- * @key2: pointer to a C string containing another option keyword
+ * @keys: pointer to an array of C strings containing option keywords
+ *
+ * This function can be used to determine which of several similar
+ * options will be the one to take effect.
  *
  * The kernel parses the mount option string from left to right.
  * If an option is specified more than once (for example, "intr"
  * and "nointr", the rightmost option is the last to be parsed,
  * and it therefore takes precedence over previous similar options.
  *
- * This function can be used to determine which of two similar
- * options will be the one to take effect.
+ * This can also distinguish among multiple synonymous options, such
+ * as "proto=," "udp" and "tcp."
+ *
+ * Returns the index into @keys of the option that is rightmost.
+ * If none of the options listed in @keys is present in @options, or
+ * if @options is NULL, returns -1.
  */
-po_rightmost_t po_rightmost(struct mount_options *options,
-                           char *key1, char *key2)
+int po_rightmost(struct mount_options *options, const char *keys[])
 {
        struct mount_option *option;
+       int i;
 
        if (options) {
                for (option = options->tail; option; option = option->prev) {
-                       if (key2 && strcmp(option->keyword, key2) == 0)
-                               return PO_KEY2_RIGHTMOST;
-                       if (key1 && strcmp(option->keyword, key1) == 0)
-                               return PO_KEY1_RIGHTMOST;
+                       for (i = 0; keys[i] != NULL; i++)
+                               if (strcmp(option->keyword, keys[i]) == 0)
+                                       return i;
                }
        }
 
-       return PO_NEITHER_FOUND;
+       return -1;
 }
 
 /**