dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fs.d / autofs / autod_autofs.c
blob04b98700dfc47d2335aaf6ab4f715cbc282d63c0
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * autod_autofs.c
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #include <sys/param.h>
33 #include <sys/stat.h>
34 #include <sys/mntent.h>
35 #include <sys/mnttab.h>
36 #include <sys/mount.h>
37 #include <sys/utsname.h>
38 #include <sys/tiuser.h>
39 #include <syslog.h>
40 #include <string.h>
41 #include <errno.h>
42 #include <fslib.h>
43 #include <sys/vfs.h>
44 #include <assert.h>
45 #include "automount.h"
47 static int process_opts(char *options, int *directp, int *sawnestp);
48 void netbuf_free(struct netbuf *);
50 int
51 mount_autofs(
52 struct mapent *me,
53 char *mntpnt,
54 action_list *alp,
55 char *rootp,
56 char *subdir,
57 char *key
60 int mntflags = 0;
61 struct utsname utsname;
62 autofs_args *fnip = NULL;
63 int mount_timeout = AUTOFS_MOUNT_TIMEOUT;
64 int sawnest, len, error = 0;
65 char *buf, rel_mntpnt[MAXPATHLEN];
67 if (trace > 1)
68 trace_prt(1, " mount_autofs %s on %s\n",
69 me->map_fs->mfs_dir, mntpnt);
71 if (strcmp(mntpnt, "/-") == 0) {
72 syslog(LOG_ERR, "invalid mountpoint: /-");
73 return (ENOENT);
77 * get relative mountpoint
79 sprintf(rel_mntpnt, ".%s", mntpnt+strlen(rootp));
81 if (trace > 2)
82 trace_prt(1, "rel_mntpnt = %s\n", rel_mntpnt);
84 if (uname(&utsname) < 0) {
85 error = errno;
86 syslog(LOG_ERR, "uname %s", strerror(error));
87 return (error);
90 if ((fnip = (autofs_args *)
91 malloc(sizeof (autofs_args))) == NULL) {
92 goto free_mem;
94 (void) memset(fnip, 0, sizeof (*fnip));
96 if ((fnip->addr.buf = (char *)malloc(MAXADDRLEN)) == NULL)
97 goto free_mem;
99 (void) strcpy(fnip->addr.buf, utsname.nodename);
100 (void) strcat(fnip->addr.buf, ".autofs");
102 if ((fnip->opts = malloc(MAX_MNTOPT_STR)) == NULL)
103 goto free_mem;
104 strcpy(fnip->opts, me->map_mntopts);
106 if (process_opts(fnip->opts, &fnip->direct, &sawnest) != 0)
107 goto free_mem;
109 fnip->addr.len = strlen(fnip->addr.buf);
110 fnip->addr.maxlen = fnip->addr.len;
113 * get absolute mountpoint
115 if ((fnip->path = strdup(mntpnt)) == NULL)
116 goto free_mem;
117 if ((fnip->map = strdup(me->map_fs->mfs_dir)) == NULL)
118 goto free_mem;
119 if ((fnip->subdir = strdup(subdir)) == NULL)
120 goto free_mem;
123 * This timeout is really ignored by autofs, it uses the
124 * parent directory's timeout since it's really the one
125 * specified/inherited from the original mount by 'automount'
127 fnip->mount_to = mount_timeout; /* IGNORED */
128 fnip->rpc_to = AUTOFS_RPC_TIMEOUT;
130 if (fnip->direct) {
131 if (me->map_modified == TRUE || me->map_faked == TRUE) {
132 if ((fnip->key = strdup(key)) == NULL)
133 goto free_mem;
134 } else {
135 /* wierd case of a direct map pointer in another map */
136 if ((fnip->key = strdup(fnip->path)) == NULL)
137 goto free_mem;
139 } else {
140 fnip->key = NULL;
144 * Fill out action list.
146 alp->action.action = AUTOFS_MOUNT_RQ;
147 if ((alp->action.action_list_entry_u.mounta.spec =
148 strdup(me->map_fs->mfs_dir)) == NULL)
149 goto free_mem;
150 if ((alp->action.action_list_entry_u.mounta.dir =
151 strdup(rel_mntpnt)) == NULL)
152 goto free_mem;
154 len = strlen(fnip->opts);
156 * Get a buffer for the option string, it holds the map options plus
157 * space for "nest" if it isn't already in the option string
159 if ((buf = (char *)malloc(MAX_MNTOPT_STR)) == NULL)
160 goto free_mem;
161 strcpy(buf, fnip->opts);
162 if (!sawnest) {
163 if (len + strlen(",nest") + 1 > MAX_MNTOPT_STR)
164 goto free_mem;
165 if (len)
166 (void) strcat(buf, ",");
167 (void) strcat(buf, "nest");
169 alp->action.action_list_entry_u.mounta.optptr = buf;
170 alp->action.action_list_entry_u.mounta.optlen = strlen(buf) + 1;
171 alp->action.action_list_entry_u.mounta.flags =
172 mntflags | MS_DATA | MS_OPTIONSTR;
173 if ((alp->action.action_list_entry_u.mounta.fstype =
174 strdup(MNTTYPE_AUTOFS)) == NULL)
175 goto free_mem;
176 alp->action.action_list_entry_u.mounta.dataptr = (char *)fnip;
177 alp->action.action_list_entry_u.mounta.datalen = sizeof (*fnip);
179 return (0);
181 free_mem:
183 * We got an error, free the memory we allocated.
185 syslog(LOG_ERR, "mount_autofs: memory allocation failure");
186 free_autofs_args(fnip);
187 alp->action.action_list_entry_u.mounta.dataptr = NULL;
188 alp->action.action_list_entry_u.mounta.datalen = 0;
189 free_mounta(&alp->action.action_list_entry_u.mounta);
191 return (error ? error : ENOMEM);
195 * Set *directp to 1 if "direct" is found, and 0 otherwise
196 * (mounts are indirect by default). If both "direct" and "indirect" are
197 * found, the last one wins.
199 static int
200 process_opts(char *options, int *directp, int *sawnestp)
202 char *opt, *opts, *lasts;
203 char buf[AUTOFS_MAXOPTSLEN];
205 assert(strlen(options)+1 < AUTOFS_MAXOPTSLEN);
207 *sawnestp = 0;
208 strcpy(buf, options);
209 opts = buf;
210 options[0] = '\0';
211 *directp = 0;
213 while ((opt = strtok_r(opts, ",", &lasts)) != NULL) {
214 opts = NULL;
215 while (isspace(*opt)) {
216 opt++;
218 if (strcmp(opt, "direct") == 0) {
219 *directp = 1;
220 } else if (strcmp(opt, "indirect") == 0) {
221 *directp = 0;
222 } else if (strcmp(opt, "ignore") != 0) {
223 if (strcmp(opt, "nest") == 0) {
224 *sawnestp = 1;
226 if (options[0] != '\0') {
227 (void) strcat(options, ",");
229 (void) strcat(options, opt);
232 return (0);
236 * Free autofs_args structure
238 void
239 free_autofs_args(autofs_args *p)
241 if (p == NULL)
242 return;
243 free(p->addr.buf);
244 free(p->path);
245 free(p->opts);
246 free(p->map);
247 free(p->subdir);
248 free(p->key);
249 free(p);
253 * free mounta structure. Assumes that m->dataptr has
254 * been freed already
256 void
257 free_mounta(struct mounta *m)
259 if (m == NULL)
260 return;
261 free(m->spec);
262 free(m->dir);
263 free(m->fstype);
264 free(m->optptr);
265 assert(m->dataptr == NULL);
266 assert(m->datalen == 0);
268 * no need to free 'm' since it is part of the
269 * action_list_entry structure.