symbolic links take on user ownership of their containing directory
[unix-history] / usr / src / sbin / mount_portal / mount_portal.c
CommitLineData
bdeaeb8f
JSP
1/*
2 * Copyright (c) 1992 The Regents of the University of California
3 * Copyright (c) 1990, 1992 Jan-Simon Pendry
4 * All rights reserved.
5 *
6 * This code is derived from software donated to Berkeley by
7 * Jan-Simon Pendry.
8 *
9 * %sccs.include.redist.c%
10 *
7e77633b 11 * @(#)mount_portal.c 5.1 (Berkeley) %G%
bdeaeb8f
JSP
12 *
13 * $Id: portald.c,v 1.3 1992/05/27 07:09:27 jsp Exp jsp $
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <unistd.h>
19#include <string.h>
20#include <errno.h>
21#include <signal.h>
22#include <sys/types.h>
23#include <sys/param.h>
24#include <sys/wait.h>
25#include <sys/socket.h>
26#include <sys/un.h>
27#include <sys/syslog.h>
28#include <sys/mount.h>
29
30#include "pathnames.h"
31#include "portald.h"
32
33static sig_atomic_t readcf; /* Set when SIGHUP received */
34
35static void sigchld(sig)
36int sig;
37{
38 pid_t pid;
39
40 while ((pid = waitpid((pid_t) -1, (int *) 0, WNOHANG)) > 0)
41 ;
42 if (pid < 0)
43 syslog(LOG_WARNING, "waitpid: %s", strerror(errno));
44}
45
46int main(c, v)
47int c;
48char *v[];
49{
50 struct portal_args args;
51 struct sockaddr_un un;
52 char *conf;
53 char *mountpt;
54 int mntflags = 0;
55 int usage = 0;
56 char tag[32];
57
58 qelem q;
59 int rc;
60 int so;
61
62 /*
63 * Crack command line args
64 */
65 int ch;
66
67 while ((ch = getopt(c, v, "F:")) != EOF) {
68 switch (ch) {
69 case 'F':
70 mntflags = atoi(optarg);
71 break;
72 default:
73 usage = 1;
74 break;
75 }
76 }
77
78 if (optind != (c - 2))
79 usage = 1;
80
81 if (usage) {
82 fprintf(stderr, "Usage: mount_portal [ fsoptions ] config mount-point\n");
83 exit(1);
84 }
85
86 /*
87 * Get config file and mount point
88 */
89 conf = v[optind];
90 mountpt = v[optind+1];
91
92 /*
93 * Construct the listening socket
94 */
95 un.sun_family = AF_UNIX;
96 if (sizeof(_PATH_TMPPORTAL) >= sizeof(un.sun_path)) {
97 fprintf(stderr, "mount_portal: portal socket name too long\n");
98 exit(1);
99 }
100 strcpy(un.sun_path, _PATH_TMPPORTAL);
101 mktemp(un.sun_path);
102 un.sun_len = strlen(un.sun_path);
103
104 so = socket(AF_UNIX, SOCK_STREAM, 0);
105 if (so < 0) {
106 fprintf(stderr, "mount_portal: socket: %s\n", strerror(errno));
107 exit(1);
108 }
109 (void) unlink(un.sun_path);
110 if (bind(so, (struct sockaddr *) &un, sizeof(un)) < 0) {
111 fprintf(stderr, "mount_portal: bind: %s\n", strerror(errno));
112 exit(1);
113 }
114 (void) unlink(un.sun_path);
115
116 (void) listen(so, 5);
117
118 args.pa_socket = so;
119 sprintf(tag, "portal:%d", getpid());
120 args.pa_config = tag;
121
122 rc = mount(MOUNT_PORTAL, mountpt, mntflags, &args);
123 if (rc < 0) {
124 fprintf(stderr, "mount_portal: mount: %s\n", strerror(errno));
125 exit(1);
126 }
127
128#ifdef notdef
129 /*
130 * Everything is ready to go - now is a good time to fork
131 */
132 daemon(0, 0);
133#endif
134
135 /*
136 * Start logging (and change name)
137 */
138 openlog("portald", LOG_CONS|LOG_PID, LOG_DAEMON);
139
140 q.q_forw = q.q_back = &q;
141 readcf = 1;
142
143 signal(SIGCHLD, sigchld);
144
145 /*
146 * Just loop waiting for new connections and activating them
147 */
148 for (;;) {
149 struct sockaddr_un un2;
150 int len2 = sizeof(un2);
151 int so2;
152 pid_t pid;
153 fd_set fdset;
154 int rc;
155
156 /*
157 * Check whether we need to re-read the configuration file
158 */
159 if (readcf) {
160 readcf = 0;
161 conf_read(&q, conf);
162 continue;
163 }
164
165 /*
166 * Accept a new connection
167 * Will get EINTR if a signal has arrived, so just
168 * ignore that error code
169 */
170 FD_SET(so, &fdset);
171 rc = select(so+1, &fdset, (void *) 0, (void *) 0, (void *) 0);
172 if (rc < 0) {
173 if (errno == EINTR)
174 continue;
175 syslog(LOG_ERR, "select: %s", strerror(errno));
176 exit(1);
177 }
178 if (rc == 0)
179 break;
180 so2 = accept(so, (struct sockaddr *) &un2, &len2);
181 if (so2 < 0) {
182 /*
183 * The unmount function does a shutdown on the socket
184 * which will generated ECONNABORTED on the accept.
185 */
186 if (errno == ECONNABORTED)
187 break;
188 if (errno != EINTR) {
189 syslog(LOG_ERR, "accept: %s", strerror(errno));
190 exit(1);
191 }
192 continue;
193 }
194
195 /*
196 * Now fork a new child to deal with the connection
197 */
198#ifdef notdef
199 eagain:;
200 switch (pid = fork()) {
201 case -1:
202 if (errno == EAGAIN) {
203 sleep(1);
204 goto eagain;
205 }
206 syslog(LOG_ERR, "fork: %s", strerror(errno));
207 break;
208 case 0:
209 (void) close(so);
210 activate(&q, so2);
211 break;
212 default:
213 (void) close(so2);
214 break;
215 }
216#endif
217 activate(&q, so2);
218 }
219 syslog(LOG_INFO, "%s unmounted", mountpt);
220 exit(0);
221}