Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <errno.h>
     32 #include <sys/types.h>
     33 #include <ctype.h>
     34 #include <string.h>
     35 #include <strings.h>
     36 #include <thread.h>
     37 #include <synch.h>
     38 #include "libfsmgt.h"
     39 
     40 /*
     41  * Private datastructures.
     42  */
     43 typedef struct dfstab_entry {
     44 	struct dfstab_entry *next;
     45 	char    *path;
     46 	char    *resource;
     47 	char    *fstype;
     48 	char    *options;
     49 	char    *description;
     50 } dfstab_entry_t;
     51 
     52 static const char *whitespace = " \t";
     53 static mutex_t dfstab_lock = DEFAULTMUTEX;
     54 
     55 /*
     56  * Private functions
     57  */
     58 static dfstab_entry_t *get_dfstab_ents(int *);
     59 static void free_dfstab_list(dfstab_entry_t *);
     60 static dfstab_entry_t *dfstab_line_to_dfstab_entry(char *, int *);
     61 static char *create_share_cmd(dfstab_entry_t *, char *, int *);
     62 static dfstab_entry_t *change_dfstab_ent(dfstab_entry_t *,
     63 	dfstab_entry_t *, int *);
     64 static void add_entry_to_dfstab(dfstab_entry_t *, int *);
     65 
     66 
     67 static dfstab_entry_t *
     68 get_dfstab_ents(int *err)
     69 {
     70 	dfstab_entry_t *dfstablist, *headptr, *tailptr = NULL;
     71 	FILE *dfp;		/* fp for dfs list */
     72 	static char cmd[BUFSIZE];
     73 	*err = 0;
     74 
     75 	if ((dfp = fopen(DFSTAB, "r")) != NULL) {
     76 		char *share_cmd;
     77 		(void) mutex_lock(&dfstab_lock);
     78 		while ((share_cmd =
     79 		    fileutil_getline(dfp, cmd, BUFSIZE)) != NULL) {
     80 			if ((dfstablist =
     81 			    dfstab_line_to_dfstab_entry(share_cmd, err)) !=
     82 			    NULL) {
     83 				if (tailptr == NULL) {
     84 					headptr = dfstablist;
     85 					tailptr = dfstablist;
     86 				} else {
     87 					tailptr->next = dfstablist;
     88 					tailptr = dfstablist;
     89 				}
     90 				dfstablist = dfstablist->next;
     91 			} else {
     92 				free(share_cmd);
     93 				break;
     94 			}
     95 			free(share_cmd);
     96 		}
     97 		if (tailptr == NULL) {
     98 			headptr = tailptr;
     99 		}
    100 		(void) mutex_unlock(&dfstab_lock);
    101 		fclose(dfp);
    102 	} else {
    103 		*err = errno;
    104 		(void) fprintf(stderr, "%s: cannot open %s\n", cmd, DFSTAB);
    105 		headptr = NULL;
    106 	}
    107 	return (headptr);
    108 } /* get_dfstab_ents */
    109 
    110 static void
    111 add_entry_to_dfstab(dfstab_entry_t *list, int *err)
    112 {
    113 	FILE *dfp;		/* fp for dfs list */
    114 
    115 	if ((dfp = fopen(DFSTAB, "a")) != NULL) {
    116 		char *share_cmd;
    117 		if ((share_cmd = create_share_cmd(list, NULL, err)) != NULL) {
    118 			(void) mutex_lock(&dfstab_lock);
    119 			fprintf(dfp, "%s", share_cmd);
    120 			fclose(dfp);
    121 			(void) mutex_unlock(&dfstab_lock);
    122 			free(share_cmd);
    123 		} else {
    124 			*err = errno;
    125 		}
    126 	} else {
    127 		*err = errno;
    128 	}
    129 
    130 } /* add_entry_to_dfstab */
    131 
    132 static void
    133 free_dfstab_list(dfstab_entry_t *headp)
    134 {
    135 	dfstab_entry_t *tmp = headp;
    136 
    137 	while (headp != NULL) {
    138 		tmp = headp->next;
    139 		if (headp->path != NULL) {
    140 			free(headp->path);
    141 		}
    142 		if (headp->resource != NULL) {
    143 			free(headp->resource);
    144 		}
    145 		if (headp->fstype != NULL) {
    146 			free(headp->fstype);
    147 		}
    148 		if (headp->options != NULL) {
    149 			free(headp->options);
    150 		}
    151 		if (headp->description != NULL) {
    152 			free(headp->description);
    153 		}
    154 		headp->next = NULL;
    155 		free(headp);
    156 		headp = tmp;
    157 	}
    158 } /* free_dfstab_list */
    159 
    160 static char *
    161 create_share_cmd(dfstab_entry_t *new_entry, char *temp_line, int *err)
    162 {
    163 	char tempstr[BUFSIZE];
    164 	char *cmd, *ret_val;
    165 
    166 	cmd = (char *)calloc((size_t)1, BUFSIZE);
    167 	if (cmd == NULL) {
    168 		*err = errno;
    169 		return (NULL);
    170 	}
    171 	sprintf(cmd, "share ");
    172 	if (new_entry->fstype) {
    173 		sprintf(tempstr, "-F %s ", new_entry->fstype);
    174 		strlcat(cmd, tempstr, BUFSIZE);
    175 	}
    176 	if (new_entry->options) {
    177 		sprintf(tempstr, "-o %s ", new_entry->options);
    178 		strlcat(cmd, tempstr, BUFSIZE);
    179 	}
    180 	if (new_entry->description) {
    181 		sprintf(tempstr, "-d %s ",
    182 		    new_entry->description);
    183 		strlcat(cmd, tempstr, BUFSIZE);
    184 	}
    185 	sprintf(tempstr, "%s\n", new_entry->path);
    186 	strlcat(cmd, tempstr, BUFSIZE);
    187 	if (temp_line != NULL && strchr(temp_line, '#')) {
    188 		sprintf(tempstr, " %s", strchr(temp_line, '#'));
    189 		strlcat(cmd, tempstr, BUFSIZE);
    190 	}
    191 	ret_val = strdup(cmd);
    192 	free(cmd);
    193 	return (ret_val);
    194 } /* create_share_cmd */
    195 
    196 /*
    197  * dfstab_line_to_dfstab_entry - parses a line from dfstab and fills in
    198  * the fields of a dfstab_entry_t structure
    199  * Parameters:
    200  * char *cmd - the share command or dfstab line to be parsed
    201  * int *err - a pointer for returning any error codes encountered
    202  */
    203 static dfstab_entry_t *
    204 dfstab_line_to_dfstab_entry(char *cmd, int *err)
    205 {
    206 
    207 	dfstab_entry_t *dfstablist;
    208 	extern char *optarg;
    209 	extern int optind;
    210 	int c, argcount = 0;
    211 	char *temp_str;
    212 	char *arglist[LINESZ];
    213 
    214 	c = 0;
    215 	optind = 1;
    216 
    217 	temp_str = strdup(cmd);
    218 	if (temp_str == NULL) {
    219 		*err = ENOMEM;
    220 		return (NULL);
    221 	}
    222 
    223 	for (arglist[argcount] = strtok(temp_str, whitespace);
    224 	    arglist[argcount] != NULL; /* CSTYLED */) {
    225 		arglist[++argcount] = strtok(NULL, whitespace);
    226 	}
    227 	argcount--;
    228 	dfstablist =
    229 	    (dfstab_entry_t *)calloc((size_t)1,
    230 	    sizeof (dfstab_entry_t));
    231 	if (dfstablist == NULL) {
    232 		*err = ENOMEM;
    233 		free(temp_str);
    234 		return (NULL);
    235 	}
    236 	while ((c = getopt(argcount, arglist, "F:d:o:")) != -1) {
    237 		switch (c) {
    238 		case 'F':
    239 					/* file system type */
    240 					/* at most one -F */
    241 			*err |= (dfstablist->fstype != NULL);
    242 			dfstablist->fstype = strdup(optarg);
    243 			if (dfstablist->fstype == NULL) {
    244 				*err = ENOMEM;
    245 				free_dfstab_list(dfstablist);
    246 				free(temp_str);
    247 				return (NULL);
    248 			}
    249 			break;
    250 		case 'd':		/* description */
    251 					/* at most one -d */
    252 			*err |= (dfstablist->description != NULL);
    253 			dfstablist->description = strdup(optarg);
    254 			if (dfstablist->description == NULL) {
    255 				*err = ENOMEM;
    256 				free_dfstab_list(dfstablist);
    257 				free(temp_str);
    258 				return (NULL);
    259 			}
    260 			break;
    261 		case 'o':		/* fs specific options */
    262 					/* at most one - o */
    263 			*err |= (dfstablist->options != NULL);
    264 			dfstablist->options = strdup(optarg);
    265 			if (dfstablist->options == NULL) {
    266 				*err = ENOMEM;
    267 				free_dfstab_list(dfstablist);
    268 				free(temp_str);
    269 				return (NULL);
    270 			}
    271 			break;
    272 		case '?':
    273 			*err = 1;
    274 			break;
    275 		}
    276 	}
    277 	if (dfstablist->fstype == NULL) {
    278 		FILE *fp;
    279 
    280 		if ((fp = fopen(DFSTYPES, "r")) == NULL) {
    281 			(void) fprintf(stderr, "%s: cannot open %s\n",
    282 			    cmd, DFSTYPES);
    283 			free_dfstab_list(dfstablist);
    284 			free(temp_str);
    285 			return (NULL);
    286 		}
    287 		(void) mutex_lock(&dfstab_lock);
    288 		dfstablist->fstype = strdup(fileutil_getfs(fp));
    289 		(void) mutex_unlock(&dfstab_lock);
    290 		fclose(fp);
    291 	}
    292 	dfstablist->path = strdup(arglist[argcount]);
    293 	if (dfstablist->path == NULL) {
    294 		*err = ENOMEM;
    295 		free_dfstab_list(dfstablist);
    296 		free(temp_str);
    297 		return (NULL);
    298 	}
    299 	free(temp_str);
    300 	return (dfstablist);
    301 } /* dfstab_line_to_dfstab_entry */
    302 
    303 static dfstab_entry_t *
    304 change_dfstab_ent(
    305 	dfstab_entry_t *old_entry,
    306 	dfstab_entry_t *new_entry,
    307 	int *err)
    308 {
    309 
    310 	FILE *fp;
    311 	dfstab_entry_t *temp_list, *ret_val;
    312 	char cmd[BUFSIZE];
    313 	char **temp_dfstab = NULL;
    314 	int line_found = 0;
    315 
    316 	if ((fp = fopen(DFSTAB, "r")) != NULL) {
    317 		char *share_cmd;
    318 		int count = 0;
    319 		(void) mutex_lock(&dfstab_lock);
    320 		while (fgets(cmd, BUFSIZE, fp) != NULL) {
    321 			if ((share_cmd =
    322 			    fileutil_get_cmd_from_string(cmd)) == NULL) {
    323 				if (!fileutil_add_string_to_array(
    324 				    &temp_dfstab, cmd, &count, err)) {
    325 					ret_val = NULL;
    326 					line_found = 0;
    327 					break;
    328 				}
    329 				continue;
    330 			}
    331 			if ((temp_list =
    332 			    dfstab_line_to_dfstab_entry(share_cmd, err)) ==
    333 			    NULL) {
    334 				free(share_cmd);
    335 				ret_val = NULL;
    336 				break;
    337 			}
    338 			if (strcmp(old_entry->path,
    339 			    temp_list->path) == 0) {
    340 				char *new_cmd = NULL;
    341 				line_found = 1;
    342 				if (new_entry != NULL && (new_cmd =
    343 				    create_share_cmd(new_entry, cmd,
    344 				    err)) != NULL) {
    345 					if (!fileutil_add_string_to_array(
    346 					    &temp_dfstab, new_cmd, &count,
    347 					    err)) {
    348 						ret_val = NULL;
    349 						line_found = 0;
    350 						free(share_cmd);
    351 						free(new_cmd);
    352 						break;
    353 					}
    354 					free(new_cmd);
    355 				}
    356 			} else {
    357 				if (!fileutil_add_string_to_array(
    358 				    &temp_dfstab, cmd, &count, err)) {
    359 					free(share_cmd);
    360 					ret_val = NULL;
    361 					line_found = 0;
    362 					break;
    363 				}
    364 			}
    365 			free_dfstab_list(temp_list);
    366 			free(share_cmd);
    367 		}
    368 		fclose(fp);
    369 
    370 		if (line_found && temp_dfstab != NULL) {
    371 			if ((fp = fopen(DFSTAB, "w")) != NULL) {
    372 				int i;
    373 				for (i = 0; i < count; i++) {
    374 					fprintf(fp, "%s", temp_dfstab[i]);
    375 				}
    376 				fclose(fp);
    377 				(void) mutex_unlock(&dfstab_lock);
    378 				ret_val = get_dfstab_ents(err);
    379 				fileutil_free_string_array(temp_dfstab, count);
    380 			} else {
    381 				*err = errno;
    382 				(void) mutex_unlock(&dfstab_lock);
    383 				fileutil_free_string_array(temp_dfstab, count);
    384 				ret_val = NULL;
    385 			}
    386 		} else {
    387 			(void) mutex_unlock(&dfstab_lock);
    388 			if (temp_dfstab != NULL) {
    389 				fileutil_free_string_array(temp_dfstab, count);
    390 			}
    391 			ret_val = NULL;
    392 		}
    393 	} else {
    394 		*err = errno;
    395 		ret_val = NULL;
    396 	}
    397 	return (ret_val);
    398 } /* change_dfstab_ent */
    399 
    400 /*
    401  * Public accessor functions.
    402  */
    403 
    404 /*
    405  * fs_add_DFStab_ent - adds an entry to dfstab and to the list of dfstab
    406  * entries. Returns a pointer to the head of the dfstab entry list.
    407  * Parameters:
    408  * char *cmd - the same command to be added to dstab
    409  * int *err - an error pointer for retruning any errors
    410  */
    411 fs_dfstab_entry_t
    412 fs_add_DFStab_ent(char *cmd, int *err)
    413 {
    414 	dfstab_entry_t *dfstab_ent;
    415 
    416 	dfstab_ent = dfstab_line_to_dfstab_entry(cmd, err);
    417 	if (dfstab_ent == NULL) {
    418 		*err = errno;
    419 		return (NULL);
    420 	}
    421 	add_entry_to_dfstab(dfstab_ent, err);
    422 	if (*err != 0) {
    423 		free_dfstab_list(dfstab_ent);
    424 		return (NULL);
    425 	}
    426 	free_dfstab_list(dfstab_ent);
    427 	return (get_dfstab_ents(err));
    428 }
    429 
    430 /*
    431  * set_DFStab_ent - adds an entry to dfstab and to the list of dfstab entries.
    432  * returns a pointer to the head of the dfstab entry list.
    433  */
    434 fs_dfstab_entry_t
    435 fs_set_DFStab_ent(
    436 	char *path,
    437 	char *fstype,
    438 	char *options,
    439 	char *description,
    440 	int *err)
    441 {
    442 
    443 	dfstab_entry_t *new_entry;
    444 	new_entry = (dfstab_entry_t *)calloc((size_t)1,
    445 	    sizeof (dfstab_entry_t));
    446 	if (new_entry == NULL) {
    447 		*err = ENOMEM;
    448 		return (NULL);
    449 	}
    450 	if (path != NULL) {
    451 		new_entry->path = strdup(path);
    452 	} else {
    453 		*err = EINVAL;
    454 		free_dfstab_list(new_entry);
    455 		return (NULL);
    456 	}
    457 	if (fstype != NULL) {
    458 		new_entry->fstype = strdup(fstype);
    459 	} else {
    460 		FILE *fp;
    461 
    462 		if ((fp = fopen(DFSTYPES, "r")) == NULL) {
    463 			/* change this to error handler */
    464 			(void) fprintf(stderr, "cannot open %s\n",
    465 			    DFSTYPES);
    466 			free_dfstab_list(new_entry);
    467 			return (NULL);
    468 		}
    469 		(void) mutex_lock(&dfstab_lock);
    470 		new_entry->fstype = strdup(fileutil_getfs(fp));
    471 		(void) mutex_unlock(&dfstab_lock);
    472 		fclose(fp);
    473 	}
    474 	if (options != NULL) {
    475 		new_entry->options = strdup(options);
    476 	}
    477 	if (description != NULL) {
    478 		new_entry->description = strdup(description);
    479 	}
    480 	add_entry_to_dfstab(new_entry, err);
    481 	if (*err != 0) {
    482 		free_dfstab_list(new_entry);
    483 		return (NULL);
    484 	}
    485 	free_dfstab_list(new_entry);
    486 	return (get_dfstab_ents(err));
    487 } /* set_DFStab_ent */
    488 
    489 /*
    490  * Accessor function for path element of dfstab entry.
    491  */
    492 char *
    493 fs_get_DFStab_ent_Path(void *entry)
    494 {
    495 	dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
    496 	if (entryptr == NULL) {
    497 		return (NULL);
    498 	}
    499 	return (entryptr->path);
    500 } /* get_DFStab_ent_Path */
    501 
    502 /*
    503  * Accessor function for fstype element of dfstab entry.
    504  */
    505 char *
    506 fs_get_DFStab_ent_Fstype(void *entry)
    507 {
    508 	dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
    509 	if (entryptr == NULL) {
    510 		return (NULL);
    511 	}
    512 	return (entryptr->fstype);
    513 }
    514 
    515 /*
    516  * Accessor function for options element of dfstab entry.
    517  */
    518 char *
    519 fs_get_DFStab_ent_Options(void *entry)
    520 {
    521 	dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
    522 	if (entryptr == NULL) {
    523 		return (NULL);
    524 	}
    525 	return (entryptr->options);
    526 }
    527 
    528 /*
    529  * Accessor function for description element of dfstab entry.
    530  */
    531 char *
    532 fs_get_DFStab_ent_Desc(void *entry)
    533 {
    534 	dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
    535 	if (entryptr == NULL) {
    536 		return (NULL);
    537 	}
    538 	return (entryptr->description);
    539 }
    540 
    541 /*
    542  * Accessor function for resource element of dfstab entry.
    543  */
    544 char *
    545 fs_get_DFStab_ent_Res(void *entry)
    546 {
    547 	dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
    548 	if (entryptr == NULL) {
    549 		return (NULL);
    550 	}
    551 	return (entryptr->resource);
    552 }
    553 
    554 
    555 /*
    556  * Calls get_dfstab_ents to create the list of dfstab
    557  * entries and returns that list.
    558  */
    559 fs_dfstab_entry_t
    560 fs_get_DFStab_ents(int *err)
    561 {
    562 	dfstab_entry_t *list;
    563 	list = get_dfstab_ents(err);
    564 	return (list);
    565 }
    566 
    567 /*
    568  * Retrives and returns the next entry in the list.
    569  */
    570 fs_dfstab_entry_t
    571 fs_get_DFStab_ent_Next(void *list)
    572 {
    573 	dfstab_entry_t *listptr = (dfstab_entry_t *)list;
    574 	if (listptr == NULL) {
    575 		return (NULL);
    576 	}
    577 	return (listptr->next);
    578 }
    579 
    580 /*
    581  * Retrives and returns a share command based on the dfstab entry passed in.
    582  */
    583 char *
    584 fs_get_Dfstab_share_cmd(fs_dfstab_entry_t dfstab_ent, int *err)
    585 {
    586 	char *share_cmd;
    587 	if (dfstab_ent == NULL) {
    588 		return (NULL);
    589 	}
    590 	share_cmd = create_share_cmd((dfstab_entry_t *)dfstab_ent, NULL, err);
    591 	return (share_cmd);
    592 } /* fs_get_Dfstab_share_cmd */
    593 
    594 /*
    595  * edit_DFStab_ent - changes an entry in dfstab.
    596  */
    597 fs_dfstab_entry_t
    598 fs_edit_DFStab_ent(char *old_cmd, char *new_cmd, int *err)
    599 {
    600 	dfstab_entry_t *old_dfstabent, *new_dfstabent, *ret_val;
    601 
    602 	if ((old_dfstabent =
    603 	    dfstab_line_to_dfstab_entry(old_cmd, err)) == NULL) {
    604 		return (NULL);
    605 	}
    606 	if ((new_dfstabent =
    607 	    dfstab_line_to_dfstab_entry(new_cmd, err)) == NULL) {
    608 		return (NULL);
    609 	}
    610 	if ((ret_val =
    611 	    change_dfstab_ent(old_dfstabent, new_dfstabent, err)) == NULL) {
    612 		return (NULL);
    613 	}
    614 	free_dfstab_list(old_dfstabent);
    615 	free_dfstab_list(new_dfstabent);
    616 	return (ret_val);
    617 }
    618 
    619 /*
    620  * del_DFStab_ent - deletes an entry in dfstab.
    621  */
    622 fs_dfstab_entry_t
    623 fs_del_DFStab_ent(char *del_cmd, int *err)
    624 {
    625 	dfstab_entry_t *del_dfstabent, *ret_val;
    626 
    627 	if ((del_dfstabent =
    628 	    dfstab_line_to_dfstab_entry(del_cmd, err)) == NULL) {
    629 		return (NULL);
    630 	}
    631 	if ((ret_val =
    632 	    change_dfstab_ent(del_dfstabent, NULL, err)) == NULL) {
    633 		return (NULL);
    634 	}
    635 	free_dfstab_list(del_dfstabent);
    636 	return (ret_val);
    637 }
    638 
    639 /*
    640  * del_All_DFStab_ents_with_Path - deletes all duplicate entries with
    641  * the specified path.
    642  */
    643 fs_dfstab_entry_t
    644 fs_del_All_DFStab_ents_with_Path(char *path, int *err)
    645 {
    646 	dfstab_entry_t del_dfstabent, *ret_val;
    647 
    648 	if (path != NULL) {
    649 		if ((del_dfstabent.path = strdup(path)) != NULL) {
    650 			if ((ret_val = change_dfstab_ent(&del_dfstabent,
    651 			    NULL, err)) == NULL) {
    652 				ret_val = NULL;
    653 			}
    654 			free(del_dfstabent.path);
    655 		} else {
    656 			*err = ENOMEM;
    657 			ret_val = NULL;
    658 		}
    659 	} else {
    660 		*err = EINVAL;
    661 		ret_val = NULL;
    662 	}
    663 	return (ret_val);
    664 }
    665 
    666 
    667 int
    668 fs_check_for_duplicate_DFStab_paths(char *path, int *err)
    669 {
    670 	dfstab_entry_t *dfstablist;
    671 	int count = 0;
    672 
    673 	*err = 0;
    674 	if (path == NULL) {
    675 		count = -1;
    676 	}
    677 	dfstablist = get_dfstab_ents(err);
    678 	if (dfstablist != NULL) {
    679 		while (dfstablist != NULL) {
    680 			if (strcmp(dfstablist->path, path) == 0) {
    681 				count++;
    682 			}
    683 			dfstablist = dfstablist->next;
    684 		}
    685 
    686 		free_dfstab_list(dfstablist);
    687 	} else {
    688 		if (err != 0)
    689 			count = *err;
    690 		else
    691 			count = 0;
    692 	}
    693 	return (count);
    694 }
    695 
    696 void
    697 fs_free_DFStab_ents(void *list)
    698 {
    699 	dfstab_entry_t *headp = (dfstab_entry_t *)list;
    700 	free_dfstab_list(headp);
    701 }
    702 
    703 /*
    704  * used for debugging only
    705  */
    706 void
    707 fs_print_dfstab_entries(void *list)
    708 {
    709 	while (list != NULL) {
    710 
    711 		if (fs_get_DFStab_ent_Fstype(list) != NULL)
    712 			printf("fstype: %s", fs_get_DFStab_ent_Fstype(list));
    713 		if (fs_get_DFStab_ent_Desc(list) != NULL)
    714 			printf(" description: %s",
    715 			    fs_get_DFStab_ent_Desc(list));
    716 		if (fs_get_DFStab_ent_Options(list) != NULL)
    717 			printf(" options: %s",
    718 			    fs_get_DFStab_ent_Options(list));
    719 		if (fs_get_DFStab_ent_Path(list) != NULL)
    720 			printf(" shared path is: %s\n",
    721 			    fs_get_DFStab_ent_Path(list));
    722 		list = (void *)fs_get_DFStab_ent_Next(list);
    723 	}
    724 
    725 }
    726