Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / bsd / am-utils / dist / amd / sun_map.c
blob9eee11dbd16cf41213d60bc88e815706e2ccf9b3
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 1997-2009 Erez Zadok
5 * Copyright (c) 2005 Daniel P. Ottavio
6 * Copyright (c) 1990 Jan-Simon Pendry
7 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
8 * Copyright (c) 1990 The Regents of the University of California.
9 * All rights reserved.
11 * This code is derived from software contributed to Berkeley by
12 * Jan-Simon Pendry at Imperial College, London.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 * must display the following acknowledgment:
24 * This product includes software developed by the University of
25 * California, Berkeley and its contributors.
26 * 4. Neither the name of the University nor the names of its contributors
27 * may be used to endorse or promote products derived from this software
28 * without specific prior written permission.
30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
43 * File: am-utils/amd/sun_map.c
47 #ifdef HAVE_CONFIG_H
48 # include <config.h>
49 #endif /* HAVE_CONFIG_H */
50 #include <am_defs.h>
51 #include <amd.h>
52 #include <sun_map.h>
57 * Add a data pointer to the end of the list.
59 void
60 sun_list_add(struct sun_list *list, qelem *item)
62 if (list->last == NULL) {
63 list->last = item;
64 list->first = item;
65 item->q_back = NULL;
67 else {
68 list->last->q_forw = item;
69 item->q_back = list->last;
70 list->last = item;
73 item->q_forw = NULL;
78 * Sun2Amd conversion routines
82 * AMD entry keywords
84 #define AMD_OPTS_KW "addopts:=" /* add entry options */
85 #define AMD_RHOST_KW "rhost:=" /* remote host */
86 #define AMD_RFS_KW "rfs:=" /* remote file system */
87 #define AMD_FS_KW "fs:=" /* local file system */
88 #define AMD_DEV_KW "dev:=" /* device */
89 #define AMD_TYPE_NFS_KW "type:=nfs;" /* fs type nfs */
90 #define AMD_TYPE_AUTO_KW "type:=auto;" /* fs type auto */
91 #define AMD_TYPE_CDFS_KW "type:=cdfs;" /* fs type cd */
92 #define AMD_MAP_FS_KW "fs:=${map};" /* set the mount map as current map */
93 #define AMD_MAP_PREF_KW "pref:=${key}/" /* set the mount map as current map */
96 * A set of string Sun fstypes.
98 #define SUN_NFS_TYPE "nfs"
99 #define SUN_HSFS_TYPE "hsfs" /* CD fs */
100 #define SUN_AUTOFS_TYPE "autofs"
101 #define SUN_CACHEFS_TYPE "cachefs"
103 #define SUN_KEY_SUB "&" /* Sun key substitution */
105 /* a set a Sun variable substitutions for map entries */
106 #define SUN_ARCH "$ARCH" /* host architecture */
107 #define SUN_CPU "$CPU" /* processor type */
108 #define SUN_HOST "$HOST" /* host name */
109 #define SUN_OSNAME "$OSNAME" /* OS name */
110 #define SUN_OSREL "$OSREL" /* OS release */
111 #define SUN_OSVERS "$OSVERS" /* OS version */
112 #define SUN_NATISA "$NATISA" /* native instruction set */
114 /* a set of Amd variable substitutions */
115 #define AMD_ARCH "${arch}" /* host architecture */
116 #define AMD_HOST "${host}" /* host name */
117 #define AMD_OSNAME "${os}" /* OS name */
118 #define AMD_OSVER "${osver}" /* OS version */
122 * Return a copy of src that has all occurrences of 'str' replaced
123 * with sub.
125 * param src - the original string
126 * param str - string that is the replaced with str
127 * param sub - string that replaces an occurrences of 'delim'
129 * return - new string with str substitutions, NULL on error
131 static char *
132 sun_strsub(const char *src, const char *str, const char *sub)
135 char *retval = NULL, *str_start, *str_end, *src_end;
136 size_t total_size, first_half, second_half, sub_size;
138 /* assign pointers to the start and end of str */
139 if ((str_start = strstr(src, str)) == NULL) {
140 return retval;
142 str_end = (strlen(str) - 1) + str_start;
144 /* assign to the end of the src. */
145 src_end = (strlen(src) - 1) + (char*)src;
147 /* size from the beginning of src to the start of str */
148 first_half = (size_t)(str_start - src);
150 /* size from the end of str to the end of src */
151 second_half = (size_t)(src_end - str_end);
153 sub_size = strlen(sub);
155 total_size = (first_half + sub_size + second_half + 1);
157 retval = (char*)xmalloc(total_size);
158 memset(retval, 0, total_size);
161 * Put together the string such that the first half is copied
162 * followed the sub and second half.
164 * We use strncpy instead of xstrlcpy because we are intentionally
165 * causing truncation and we don't want this to cause errors in the
166 * log.
168 (void)strncpy(retval, src, first_half);
169 (void)strncat(retval, sub, sub_size);
170 (void)strncat(retval, str_end + 1, second_half);
172 if ((str_start = strstr(retval, str)) != NULL) {
174 * If there is another occurrences of str call this function
175 * recursively.
177 char* tmp;
178 if ((tmp = sun_strsub(retval, str, sub)) != NULL) {
179 XFREE(retval);
180 retval = tmp;
183 return retval;
188 * Return a new string that is a copy of str, all occurrences of a Sun
189 * variable substitutions are replaced by there equivalent Amd
190 * substitutions.
192 * param str - source string
194 * return - A new string with the expansions, NULL if str does not
195 * exist in src or error.
197 static char *
198 sun_expand2amd(const char *str)
201 char *retval = NULL, *tmp = NULL, *tmp2 = NULL;
202 const char *pos;
205 * Iterator through the string looking for '$' chars. For each '$'
206 * found try to replace it with Sun variable substitutions. If we
207 * find a '$' that is not a substation each of the i.e $blah than
208 * each of the replace attempt will fail and we'll move on to the
209 * next char.
211 tmp = strdup(str);
212 for (pos = str; *pos != '\0'; pos++) {
213 if (*pos != '$') {
214 continue;
216 if (tmp2 != NULL) {
217 XFREE(tmp);
218 tmp = tmp2;
222 * If a 'replace' does not return NULL than a variable was
223 * successfully substituted.
226 /* architecture */
227 if ((tmp2 = sun_strsub(tmp, SUN_ARCH, AMD_ARCH)) != NULL) {
228 continue;
230 /* cpu - there is not POSIX uname for cpu so just use machine */
231 if ((tmp2 = sun_strsub(tmp, SUN_CPU, AMD_ARCH)) != NULL) {
232 continue;
234 /* hostname */
235 if ((tmp2 = sun_strsub(tmp, SUN_HOST, AMD_HOST)) != NULL) {
236 continue;
238 /* os name */
239 if ((tmp2 = sun_strsub(tmp, SUN_OSNAME, AMD_OSNAME)) != NULL) {
240 continue;
243 * os release - Amd doesn't hava a OS release var just usr os
244 * version or now.
246 if ((tmp2 = sun_strsub(tmp, SUN_OSREL, AMD_OSVER)) != NULL) {
247 continue;
249 /* os version */
250 if ((tmp2 = sun_strsub(tmp, SUN_OSVERS, AMD_OSVER)) != NULL) {
251 continue;
253 /* native instruction set - there is no POSIX natisa so just use system */
254 if ((tmp2 = sun_strsub(tmp, SUN_NATISA, AMD_ARCH)) != NULL) {
255 continue;
258 if (tmp2 == NULL) {
259 retval = tmp;
261 else {
262 retval = tmp2;
263 if (tmp != NULL) {
264 XFREE(tmp);
268 return retval;
273 * This is a wrapper function for appending Amd entry information to a
274 * buffer. Any Sun variable substitutions will be converted into Amd
275 * equivalents.
277 * param dest - destination buffer
278 * param deslen - destination buffer length
279 * param key - entry key, this might be needed for key substitutions
280 * param str - string to append
282 static void
283 sun_append_str(char *dest,
284 size_t destlen,
285 const char *key,
286 const char *str)
288 char *sub = NULL, *sub2 = NULL, *out = NULL;
290 /* By default we are going to just write the original string. */
291 out = (char*)str;
294 * Resolve variable substitutions in two steps; 1) replace any key
295 * map substitutions with the entry key 2) expand any variable
296 * substitutions i.e $HOST.
298 * Try to replace the key substitution '&'. If this function returns
299 * with a new string, one or more key subs. where replaced with the
300 * entry key.
302 if ((sub = sun_strsub(str, SUN_KEY_SUB, "${key}")) != NULL) {
303 out = sub;
305 * Try to convert any variable substitutions. If this function
306 * returns a new string one or more var subs where expanded.
308 if ((sub2 = sun_expand2amd(sub)) != NULL) {
309 out = sub2;
313 * Try to convert any variable substitutions. If this function
314 * returns a new string one or more var subs where expanded.
316 else if ((sub = sun_expand2amd(out)) != NULL) {
317 out = sub;
320 if (out != NULL) {
321 xstrlcat(dest, out, destlen);
323 if (sub != NULL) {
324 XFREE(sub);
326 if (sub2 != NULL) {
327 XFREE(sub2);
333 * Convert the list of Sun mount options to Amd mount options. The
334 * result is concatenated to dest.
336 * param dest - destination buffer
337 * param destlen - destination buffer length
338 * param key - automount key
339 * param opt_list - list of Sun mount options
341 static void
342 sun_opts2amd(char *dest,
343 size_t destlen,
344 const char *key,
345 const struct sun_opt *opt_list)
347 const struct sun_opt *opt;
349 xstrlcat(dest, AMD_OPTS_KW, destlen);
351 /* Iterate through each option and append it to the buffer. */
352 for(opt = opt_list; opt != NULL; opt = NEXT(struct sun_opt, opt)) {
353 sun_append_str(dest, destlen, key, opt->str);
354 /* If there are more options add some commas. */
355 if (NEXT(struct sun_opt, opt) != NULL) {
356 xstrlcat(dest, ",", destlen);
359 xstrlcat(dest, ";", destlen);
364 * Convert the list of Sun mount locations to a list of Amd mount
365 * locations. The result is concatenated to dest.
367 * param dest - destination buffer
368 * param destlen - destination buffer length
369 * param key - automount key
370 * param local_list - list of Sun mount locations
372 static void
373 sun_locations2amd(char *dest,
374 size_t destlen,
375 const char *key,
376 const struct sun_location *local_list)
378 const struct sun_location *local;
379 const struct sun_host *host;
381 for (local = local_list;
382 local != NULL;
383 local = NEXT(struct sun_location,local)) {
385 * Check to see if the list of hosts is empty. Some mount types
386 * i.e cd-rom may have mount location with no host.
388 if (local->host_list != NULL) {
389 /* Write each host that belongs to this location. */
390 for (host = local->host_list;
391 host != NULL;
392 host = NEXT(struct sun_host, host)) {
393 /* set fstype NFS */
394 xstrlcat(dest, AMD_TYPE_NFS_KW, destlen);
395 /* add rhost key word */
396 xstrlcat(dest, AMD_RHOST_KW, destlen);
397 /* add host name */
398 sun_append_str(dest, destlen, key, host->name);
399 xstrlcat(dest, ";", destlen);
400 /* add remote fs key word */
401 xstrlcat(dest, AMD_RFS_KW, destlen);
402 /* add local path */
403 sun_append_str(dest, destlen, key, local->path);
404 if (NEXT(struct sun_host, host) != NULL) {
405 xstrlcat(dest, ";", destlen);
406 xstrlcat(dest, " ", destlen);
410 else {
411 /* no host location */
412 xstrlcat(dest, AMD_FS_KW, destlen);
413 sun_append_str(dest, destlen, key, local->path);
415 if (NEXT(struct sun_location, local) != NULL) {
416 /* add a space to separate each location */
417 xstrlcat(dest, " ", destlen);
424 * Convert a Sun HSFS mount point to an Amd. The result is
425 * concatenated intp dest.
427 * param dest - destination buffer
428 * param destlen - destination buffer length
429 * param key - automount key
430 * param s_entry - Sun entry
432 static void
433 sun_hsfs2amd(char *dest,
434 size_t destlen,
435 const char *key,
436 const struct sun_entry *s_entry)
438 /* set fstype CDFS */
439 xstrlcat(dest, AMD_TYPE_CDFS_KW, destlen);
440 /* set the cdrom device */
441 xstrlcat(dest, AMD_DEV_KW, destlen);
442 /* XXX: For now just assume that there is only one device. */
443 xstrlcat(dest, s_entry->location_list->path, destlen);
448 * Convert a Sun NFS automount entry to an Amd. The result is concatenated
449 * into dest.
451 * param dest - destination buffer
452 * param destlen - destination buffer length
453 * param key - automount key
454 * param s_entry - Sun entry
456 static void
457 sun_nfs2amd(char *dest,
458 size_t destlen,
459 const char *key,
460 const struct sun_entry *s_entry)
462 if (s_entry->location_list != NULL) {
463 /* write out the list of mountpoint locations */
464 sun_locations2amd(dest, destlen, key, s_entry->location_list);
470 * Convert a Sun multi-mount point entry to an Amd. This is done
471 * using the Amd type auto. Each auto entry is separated with a \n.
473 * param dest - destination buffer
474 * param destlen - destination buffer length
475 * param key - automount key
476 * param s_entry - Sun entry
478 static void
479 sun_multi2amd(char *dest,
480 size_t destlen,
481 const char *key,
482 const struct sun_entry *s_entry)
484 const struct sun_mountpt *mountpt;
486 /* We need to setup a auto fs Amd automount point. */
487 xstrlcat(dest, AMD_TYPE_AUTO_KW, destlen);
488 xstrlcat(dest, AMD_MAP_FS_KW, destlen);
489 xstrlcat(dest, AMD_MAP_PREF_KW, destlen);
491 /* write the mountpts to dest */
492 for (mountpt = s_entry->mountpt_list;
493 mountpt != NULL;
494 mountpt = NEXT(struct sun_mountpt, mountpt)) {
495 xstrlcat(dest, "\n", destlen);
496 /* write the key */
497 xstrlcat(dest, key, destlen);
498 /* write the mount path */
499 sun_append_str(dest, destlen, key, mountpt->path);
500 /* space */
501 xstrlcat(dest, " ", destlen);
502 /* Write all the host locations for this mount point. */
503 sun_locations2amd(dest, destlen, key, mountpt->location_list);
509 * Convert the sun_entry into an Amd equivalent string.
511 * param key - automount key
512 * param s_entry - Sun style automap entry
514 * return - Amd entry on succes, NULL on error
516 char *
517 sun_entry2amd(const char *key, const char *s_entry_str)
519 char *retval = NULL;
520 char line_buff[INFO_MAX_LINE_LEN];
521 int ws;
522 struct sun_entry *s_entry = NULL;
524 /* The key should not be NULL. */
525 if (key == NULL) {
526 plog(XLOG_ERROR,"Sun key value was null");
527 goto err;
529 /* The Sun entry string should never be NULL. */
530 if (s_entry_str == NULL) {
531 plog(XLOG_ERROR,"Sun entry value was null");
532 goto err;
535 /* Make sure there are no trailing white spaces or '\n'. */
536 xstrlcpy(line_buff, s_entry_str, sizeof(line_buff));
537 ws = strlen(line_buff) - 1;
538 while (ws >= 0 && (isspace((unsigned char)line_buff[ws]) || line_buff[ws] == '\n')) {
539 line_buff[ws--] = '\0';
542 /* Parse the sun entry line. */
543 s_entry = sun_map_parse_read(line_buff);
544 if (s_entry == NULL) {
545 plog(XLOG_ERROR,"could not parse Sun style map");
546 goto err;
549 memset(line_buff, 0, sizeof(line_buff));
551 if (s_entry->opt_list != NULL) {
552 /* write the mount options to the buffer */
553 sun_opts2amd(line_buff, sizeof(line_buff), key, s_entry->opt_list);
556 /* Check if this is a multi-mount entry. */
557 if (s_entry->mountpt_list != NULL) {
558 /* multi-mount point */
559 sun_multi2amd(line_buff, sizeof(line_buff), key, s_entry);
560 retval = strdup(line_buff);
562 else {
563 /* single mount point */
564 if (s_entry->fstype != NULL) {
565 if (NSTREQ(s_entry->fstype, SUN_NFS_TYPE, strlen(SUN_NFS_TYPE))) {
566 /* NFS Type */
567 sun_nfs2amd(line_buff, sizeof(line_buff), key, s_entry);
568 retval = strdup(line_buff);
570 else if (NSTREQ(s_entry->fstype, SUN_HSFS_TYPE, strlen(SUN_HSFS_TYPE))) {
571 /* HSFS Type (CD fs) */
572 sun_hsfs2amd(line_buff, sizeof(line_buff), key, s_entry);
573 retval = strdup(line_buff);
576 * XXX: The following fstypes are not yet supported.
578 else if (NSTREQ(s_entry->fstype, SUN_AUTOFS_TYPE, strlen(SUN_AUTOFS_TYPE))) {
579 /* AutoFS Type */
580 plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
581 s_entry->fstype);
582 goto err;
585 else if (NSTREQ(s_entry->fstype, SUN_CACHEFS_TYPE, strlen(SUN_CACHEFS_TYPE))) {
586 /* CacheFS Type */
587 plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
588 s_entry->fstype);
589 goto err;
591 else {
592 plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
593 s_entry->fstype);
594 goto err;
597 else {
598 plog(XLOG_INFO, "No SUN fstype specified defaulting to NFS.");
599 sun_nfs2amd(line_buff, sizeof(line_buff), key, s_entry);
600 retval = strdup(line_buff);
604 err:
605 if (s_entry != NULL) {
606 XFREE(s_entry);
608 return retval;