1 |
/* Proc server host management calls |
/* Proc server host management calls |
2 |
Copyright (C) 1992,93,94,96,97,2001 Free Software Foundation |
Copyright (C) 1992,93,94,96,97,2001,02 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of the GNU Hurd. |
This file is part of the GNU Hurd. |
5 |
|
|
8 |
the Free Software Foundation; either version 2, or (at your option) |
the Free Software Foundation; either version 2, or (at your option) |
9 |
any later version. |
any later version. |
10 |
|
|
11 |
The GNU Hurd is distributed in the hope that it will be useful, |
The GNU Hurd is distributed in the hope that it will be useful, |
12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
GNU General Public License for more details. |
GNU General Public License for more details. |
49 |
} *server_versions; |
} *server_versions; |
50 |
int nserver_versions, server_versions_nalloc; |
int nserver_versions, server_versions_nalloc; |
51 |
|
|
52 |
struct execdata_notify |
struct execdata_notify |
53 |
{ |
{ |
54 |
mach_port_t notify_port; |
mach_port_t notify_port; |
55 |
struct execdata_notify *next; |
struct execdata_notify *next; |
64 |
{ |
{ |
65 |
if (!p) |
if (!p) |
66 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
67 |
|
|
68 |
if (! check_uid (p, 0)) |
if (! check_uid (p, 0)) |
69 |
return EPERM; |
return EPERM; |
70 |
|
|
71 |
*hostpriv = master_host_port; |
*hostpriv = master_host_port; |
72 |
*devpriv = master_device_port; |
*devpriv = master_device_port; |
73 |
return 0; |
return 0; |
78 |
kern_return_t |
kern_return_t |
79 |
S_proc_setexecdata (struct proc *p, |
S_proc_setexecdata (struct proc *p, |
80 |
mach_port_t *ports, |
mach_port_t *ports, |
81 |
u_int nports, |
size_t nports, |
82 |
int *ints, |
int *ints, |
83 |
u_int nints) |
size_t nints) |
84 |
{ |
{ |
85 |
int i; |
int i; |
86 |
struct execdata_notify *n; |
struct execdata_notify *n; |
89 |
|
|
90 |
if (!p) |
if (!p) |
91 |
return EOPNOTSUPP; |
return EOPNOTSUPP; |
92 |
|
|
93 |
if (!check_uid (p, 0)) |
if (!check_uid (p, 0)) |
94 |
return EPERM; |
return EPERM; |
95 |
|
|
104 |
free (std_port_array_new); |
free (std_port_array_new); |
105 |
return ENOMEM; |
return ENOMEM; |
106 |
} |
} |
107 |
|
|
108 |
if (std_port_array) |
if (std_port_array) |
109 |
{ |
{ |
110 |
for (i = 0; i < n_std_ports; i++) |
for (i = 0; i < n_std_ports; i++) |
113 |
} |
} |
114 |
if (std_int_array) |
if (std_int_array) |
115 |
free (std_int_array); |
free (std_int_array); |
116 |
|
|
117 |
std_port_array = std_port_array_new; |
std_port_array = std_port_array_new; |
118 |
n_std_ports = nports; |
n_std_ports = nports; |
119 |
memcpy (std_port_array, ports, sizeof (mach_port_t) * nports); |
memcpy (std_port_array, ports, sizeof (mach_port_t) * nports); |
120 |
|
|
121 |
std_int_array = std_int_array_new; |
std_int_array = std_int_array_new; |
122 |
n_std_ints = nints; |
n_std_ints = nints; |
123 |
memcpy (std_int_array, ints, sizeof (int) * nints); |
memcpy (std_int_array, ints, sizeof (int) * nints); |
124 |
|
|
125 |
for (n = execdata_notifys; n; n = n->next) |
for (n = execdata_notifys; n; n = n->next) |
126 |
exec_setexecdata (n->notify_port, std_port_array, MACH_MSG_TYPE_COPY_SEND, |
exec_setexecdata (n->notify_port, std_port_array, MACH_MSG_TYPE_COPY_SEND, |
127 |
n_std_ports, std_int_array, n_std_ints); |
n_std_ports, std_int_array, n_std_ints); |
128 |
|
|
129 |
return 0; |
return 0; |
130 |
} |
} |
131 |
|
|
132 |
/* Implement proc_getexecdata as described in <hurd/process.defs>. */ |
/* Implement proc_getexecdata as described in <hurd/process.defs>. */ |
133 |
kern_return_t |
kern_return_t |
134 |
S_proc_getexecdata (struct proc *p, |
S_proc_getexecdata (struct proc *p, |
135 |
mach_port_t **ports, |
mach_port_t **ports, |
136 |
mach_msg_type_name_t *portspoly, |
mach_msg_type_name_t *portspoly, |
137 |
u_int *nports, |
size_t *nports, |
138 |
int **ints, |
int **ints, |
139 |
u_int *nints) |
size_t *nints) |
140 |
{ |
{ |
141 |
int i; |
int i; |
142 |
int ports_allocated = 0; |
int ports_allocated = 0; |
155 |
} |
} |
156 |
memcpy (*ports, std_port_array, n_std_ports * sizeof (mach_port_t)); |
memcpy (*ports, std_port_array, n_std_ports * sizeof (mach_port_t)); |
157 |
*nports = n_std_ports; |
*nports = n_std_ports; |
158 |
|
|
159 |
if (*nints < n_std_ints) |
if (*nints < n_std_ints) |
160 |
{ |
{ |
161 |
*ints = mmap (0, round_page (n_std_ints * sizeof (int)), |
*ints = mmap (0, round_page (n_std_ints * sizeof (int)), |
195 |
n->next = execdata_notifys; |
n->next = execdata_notifys; |
196 |
execdata_notifys = n; |
execdata_notifys = n; |
197 |
|
|
198 |
mach_port_request_notification (mach_task_self (), notify, |
mach_port_request_notification (mach_task_self (), notify, |
199 |
MACH_NOTIFY_DEAD_NAME, 1, |
MACH_NOTIFY_DEAD_NAME, 1, |
200 |
generic_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, |
generic_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, |
201 |
&foo); |
&foo); |
202 |
|
|
203 |
if (foo) |
if (foo) |
204 |
mach_port_deallocate (mach_task_self (), foo); |
mach_port_deallocate (mach_task_self (), foo); |
205 |
|
|
206 |
if (std_port_array) |
if (std_port_array) |
207 |
exec_setexecdata (n->notify_port, std_port_array, MACH_MSG_TYPE_COPY_SEND, |
exec_setexecdata (n->notify_port, std_port_array, MACH_MSG_TYPE_COPY_SEND, |
208 |
n_std_ports, std_int_array, n_std_ints); |
n_std_ports, std_int_array, n_std_ints); |
209 |
return 0; |
return 0; |
210 |
} |
} |
215 |
check_dead_execdata_notify (mach_port_t port) |
check_dead_execdata_notify (mach_port_t port) |
216 |
{ |
{ |
217 |
struct execdata_notify *en, **prevp; |
struct execdata_notify *en, **prevp; |
218 |
|
|
219 |
for (en = execdata_notifys, prevp = &execdata_notifys; en; en = *prevp) |
for (en = execdata_notifys, prevp = &execdata_notifys; en; en = *prevp) |
220 |
{ |
{ |
221 |
if (en->notify_port == port) |
if (en->notify_port == port) |
239 |
The uname version string is composed of all the server names and |
The uname version string is composed of all the server names and |
240 |
versions, omitting special mention of those which match the uname |
versions, omitting special mention of those which match the uname |
241 |
release, plus the kernel version string. */ |
release, plus the kernel version string. */ |
242 |
|
|
243 |
char *kernel_name, *kernel_version; |
char *kernel_name, *kernel_version; |
244 |
|
|
245 |
|
|
314 |
|
|
315 |
/* release is the most popular version */ |
/* release is the most popular version */ |
316 |
strcpy (uname_info.release, versions[0].version); |
strcpy (uname_info.release, versions[0].version); |
317 |
|
|
318 |
initstr (uname_info.version); |
initstr (uname_info.version); |
319 |
|
|
320 |
addstr (kernel_name, kernel_version); |
addstr (kernel_name, kernel_version); |
329 |
if (versions[0].count == 1 |
if (versions[0].count == 1 |
330 |
|| strcmp (server_versions[i].version, versions[0].version)) |
|| strcmp (server_versions[i].version, versions[0].version)) |
331 |
addstr (server_versions[i].name, server_versions[i].version); |
addstr (server_versions[i].name, server_versions[i].version); |
332 |
|
|
333 |
if (p > end) |
if (p > end) |
334 |
#ifdef notyet |
#ifdef notyet |
335 |
syslog (LOG_EMERG, |
syslog (LOG_EMERG, |
350 |
kernel_version_t kv; |
kernel_version_t kv; |
351 |
char *p; |
char *p; |
352 |
struct host_basic_info info; |
struct host_basic_info info; |
353 |
unsigned int n = sizeof info; |
size_t n = sizeof info; |
354 |
error_t err; |
error_t err; |
355 |
|
|
356 |
/* Fill in fixed slots sysname and machine. */ |
/* Fill in fixed slots sysname and machine. */ |
357 |
strcpy (uname_info.sysname, "GNU"); |
strcpy (uname_info.sysname, "GNU"); |
358 |
|
|
359 |
err = host_info (mach_host_self (), HOST_BASIC_INFO, (int *) &info, &n); |
err = host_info (mach_host_self (), HOST_BASIC_INFO, |
360 |
|
(host_info_t) &info, &n); |
361 |
assert (! err); |
assert (! err); |
362 |
snprintf (uname_info.machine, sizeof uname_info.machine, "%s-%s", |
snprintf (uname_info.machine, sizeof uname_info.machine, "%s-%s", |
363 |
mach_cpu_types[info.cpu_type], |
mach_cpu_types[info.cpu_type], |
393 |
nserver_versions = 1; |
nserver_versions = 1; |
394 |
|
|
395 |
rebuild_uname (); |
rebuild_uname (); |
396 |
|
|
397 |
uname_info.nodename[0] = '\0'; |
uname_info.nodename[0] = '\0'; |
398 |
} |
} |
399 |
|
|
410 |
S_proc_register_version (pstruct_t server, |
S_proc_register_version (pstruct_t server, |
411 |
mach_port_t credential, |
mach_port_t credential, |
412 |
char *name, |
char *name, |
413 |
char *release, |
char *release, |
414 |
char *version) |
char *version) |
415 |
{ |
{ |
416 |
error_t err = 0; |
error_t err = 0; |
421 |
if (credential != master_host_port) |
if (credential != master_host_port) |
422 |
/* Must be privileged to register for uname. */ |
/* Must be privileged to register for uname. */ |
423 |
return EPERM; |
return EPERM; |
424 |
|
|
425 |
for (i = 0; i < nserver_versions; i++) |
for (i = 0; i < nserver_versions; i++) |
426 |
if (!strcmp (name, server_versions[i].name)) |
if (!strcmp (name, server_versions[i].name)) |
427 |
{ |
{ |
459 |
err = ENOMEM; |
err = ENOMEM; |
460 |
goto out; |
goto out; |
461 |
} |
} |
462 |
server_versions[nserver_versions].version = malloc (strlen (version) |
server_versions[nserver_versions].version = malloc (strlen (version) |
463 |
+ 1); |
+ 1); |
464 |
if (! server_versions[nserver_versions].version) |
if (! server_versions[nserver_versions].version) |
465 |
{ |
{ |
471 |
strcpy (server_versions[nserver_versions].version, version); |
strcpy (server_versions[nserver_versions].version, version); |
472 |
nserver_versions++; |
nserver_versions++; |
473 |
} |
} |
474 |
|
|
475 |
rebuild_uname (); |
rebuild_uname (); |
476 |
out: |
out: |
477 |
mach_port_deallocate (mach_task_self (), credential); |
mach_port_deallocate (mach_task_self (), credential); |
478 |
return err; |
return err; |
479 |
} |
} |
|
|
|