2 * Copyright (c) 1997-2014 Erez Zadok
3 * Copyright (c) 2005 Daniel P. Ottavio
4 * Copyright (c) 1990 Jan-Simon Pendry
5 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
6 * Copyright (c) 1990 The Regents of the University of California.
9 * This code is derived from software contributed to Berkeley by
10 * Jan-Simon Pendry at Imperial College, London.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * File: am-utils/amd/sun_map.c
43 #endif /* HAVE_CONFIG_H */
51 * Add a data pointer to the end of the list.
54 sun_list_add(struct sun_list *list, qelem *item)
56 if (list->last == NULL) {
62 list->last->q_forw = item;
63 item->q_back = list->last;
72 * Sun2Amd conversion routines
78 #define AMD_OPTS_KW "addopts:=" /* add entry options */
79 #define AMD_RHOST_KW "rhost:=" /* remote host */
80 #define AMD_RFS_KW "rfs:=" /* remote file system */
81 #define AMD_FS_KW "fs:=" /* local file system */
82 #define AMD_DEV_KW "dev:=" /* device */
83 #define AMD_TYPE_NFS_KW "type:=nfs;" /* fs type nfs */
84 #define AMD_TYPE_AUTO_KW "type:=auto;" /* fs type auto */
85 #define AMD_TYPE_CDFS_KW "type:=cdfs;" /* fs type cd */
86 #define AMD_MAP_FS_KW "fs:=${map};" /* set the mount map as current map */
87 #define AMD_MAP_PREF_KW "pref:=${key}/" /* set the mount map as current map */
90 * A set of string Sun fstypes.
92 #define SUN_NFS_TYPE "nfs"
93 #define SUN_HSFS_TYPE "hsfs" /* CD fs */
94 #define SUN_AUTOFS_TYPE "autofs"
95 #define SUN_CACHEFS_TYPE "cachefs"
97 #define SUN_KEY_SUB "&" /* Sun key substitution */
99 /* a set a Sun variable substitutions for map entries */
100 #define SUN_ARCH "$ARCH" /* host architecture */
101 #define SUN_CPU "$CPU" /* processor type */
102 #define SUN_HOST "$HOST" /* host name */
103 #define SUN_OSNAME "$OSNAME" /* OS name */
104 #define SUN_OSREL "$OSREL" /* OS release */
105 #define SUN_OSVERS "$OSVERS" /* OS version */
106 #define SUN_NATISA "$NATISA" /* native instruction set */
108 /* a set of Amd variable substitutions */
109 #define AMD_ARCH "${arch}" /* host architecture */
110 #define AMD_HOST "${host}" /* host name */
111 #define AMD_OSNAME "${os}" /* OS name */
112 #define AMD_OSVER "${osver}" /* OS version */
116 * Return a copy of src that has all occurrences of 'str' replaced
119 * param src - the original string
120 * param str - string that is the replaced with str
121 * param sub - string that replaces an occurrences of 'delim'
123 * return - new string with str substitutions, NULL on error
126 sun_strsub(const char *src, const char *str, const char *sub)
129 char *retval = NULL, *str_start, *str_end, *src_end;
130 size_t total_size, first_half, second_half, sub_size;
132 /* assign pointers to the start and end of str */
133 if ((str_start = strstr(src, str)) == NULL) {
136 str_end = (strlen(str) - 1) + str_start;
138 /* assign to the end of the src. */
139 src_end = (strlen(src) - 1) + (char*)src;
141 /* size from the beginning of src to the start of str */
142 first_half = (size_t)(str_start - src);
144 /* size from the end of str to the end of src */
145 second_half = (size_t)(src_end - str_end);
147 sub_size = strlen(sub);
149 total_size = (first_half + sub_size + second_half + 1);
151 retval = (char*)xmalloc(total_size);
152 memset(retval, 0, total_size);
155 * Put together the string such that the first half is copied
156 * followed the sub and second half.
158 * We use strncpy instead of xstrlcpy because we are intentionally
159 * causing truncation and we don't want this to cause errors in the
162 (void)strncpy(retval, src, first_half);
163 (void)strncat(retval, sub, sub_size);
164 (void)strncat(retval, str_end + 1, second_half);
166 if (strstr(retval, str) != NULL) {
168 * If there is another occurrences of str call this function
172 if ((tmp = sun_strsub(retval, str, sub)) != NULL) {
182 * Return a new string that is a copy of str, all occurrences of a Sun
183 * variable substitutions are replaced by there equivalent Amd
186 * param str - source string
188 * return - A new string with the expansions, NULL if str does not
189 * exist in src or error.
192 sun_expand2amd(const char *str)
195 char *retval = NULL, *tmp = NULL, *tmp2 = NULL;
199 * Iterator through the string looking for '$' chars. For each '$'
200 * found try to replace it with Sun variable substitutions. If we
201 * find a '$' that is not a substation each of the i.e $blah than
202 * each of the replace attempt will fail and we'll move on to the
206 for (pos = str; *pos != '\0'; pos++) {
216 * If a 'replace' does not return NULL than a variable was
217 * successfully substituted.
221 if ((tmp2 = sun_strsub(tmp, SUN_ARCH, AMD_ARCH)) != NULL) {
224 /* cpu - there is not POSIX uname for cpu so just use machine */
225 if ((tmp2 = sun_strsub(tmp, SUN_CPU, AMD_ARCH)) != NULL) {
229 if ((tmp2 = sun_strsub(tmp, SUN_HOST, AMD_HOST)) != NULL) {
233 if ((tmp2 = sun_strsub(tmp, SUN_OSNAME, AMD_OSNAME)) != NULL) {
237 * os release - Amd doesn't hava a OS release var just usr os
240 if ((tmp2 = sun_strsub(tmp, SUN_OSREL, AMD_OSVER)) != NULL) {
244 if ((tmp2 = sun_strsub(tmp, SUN_OSVERS, AMD_OSVER)) != NULL) {
247 /* native instruction set - there is no POSIX natisa so just use system */
248 if ((tmp2 = sun_strsub(tmp, SUN_NATISA, AMD_ARCH)) != NULL) {
265 * This is a wrapper function for appending Amd entry information to a
266 * buffer. Any Sun variable substitutions will be converted into Amd
269 * param dest - destination buffer
270 * param deslen - destination buffer length
271 * param key - entry key, this might be needed for key substitutions
272 * param str - string to append
275 sun_append_str(char *dest,
280 char *sub = NULL, *sub2 = NULL, *out = NULL;
282 /* By default we are going to just write the original string. */
286 * Resolve variable substitutions in two steps; 1) replace any key
287 * map substitutions with the entry key 2) expand any variable
288 * substitutions i.e $HOST.
290 * Try to replace the key substitution '&'. If this function returns
291 * with a new string, one or more key subs. where replaced with the
294 if ((sub = sun_strsub(str, SUN_KEY_SUB, "${key}")) != NULL) {
297 * Try to convert any variable substitutions. If this function
298 * returns a new string one or more var subs where expanded.
300 if ((sub2 = sun_expand2amd(sub)) != NULL) {
305 * Try to convert any variable substitutions. If this function
306 * returns a new string one or more var subs where expanded.
308 else if (out != NULL && (sub = sun_expand2amd(out)) != NULL) {
313 xstrlcat(dest, out, destlen);
321 * Convert the list of Sun mount options to Amd mount options. The
322 * result is concatenated to dest.
324 * param dest - destination buffer
325 * param destlen - destination buffer length
326 * param key - automount key
327 * param opt_list - list of Sun mount options
330 sun_opts2amd(char *dest,
333 const struct sun_opt *opt_list)
335 const struct sun_opt *opt;
337 xstrlcat(dest, AMD_OPTS_KW, destlen);
339 /* Iterate through each option and append it to the buffer. */
340 for(opt = opt_list; opt != NULL; opt = NEXT(struct sun_opt, opt)) {
341 sun_append_str(dest, destlen, key, opt->str);
342 /* If there are more options add some commas. */
343 if (NEXT(struct sun_opt, opt) != NULL) {
344 xstrlcat(dest, ",", destlen);
347 xstrlcat(dest, ";", destlen);
352 * Convert the list of Sun mount locations to a list of Amd mount
353 * locations. The result is concatenated to dest.
355 * param dest - destination buffer
356 * param destlen - destination buffer length
357 * param key - automount key
358 * param local_list - list of Sun mount locations
361 sun_locations2amd(char *dest,
364 const struct sun_location *local_list)
366 const struct sun_location *local;
367 const struct sun_host *host;
369 for (local = local_list;
371 local = NEXT(struct sun_location,local)) {
373 * Check to see if the list of hosts is empty. Some mount types
374 * i.e cd-rom may have mount location with no host.
376 if (local->host_list != NULL) {
377 /* Write each host that belongs to this location. */
378 for (host = local->host_list;
380 host = NEXT(struct sun_host, host)) {
382 xstrlcat(dest, AMD_TYPE_NFS_KW, destlen);
383 /* add rhost key word */
384 xstrlcat(dest, AMD_RHOST_KW, destlen);
386 sun_append_str(dest, destlen, key, host->name);
387 xstrlcat(dest, ";", destlen);
388 /* add remote fs key word */
389 xstrlcat(dest, AMD_RFS_KW, destlen);
391 sun_append_str(dest, destlen, key, local->path);
392 if (NEXT(struct sun_host, host) != NULL) {
393 xstrlcat(dest, ";", destlen);
394 xstrlcat(dest, " ", destlen);
399 /* no host location */
400 xstrlcat(dest, AMD_FS_KW, destlen);
401 sun_append_str(dest, destlen, key, local->path);
403 if (NEXT(struct sun_location, local) != NULL) {
404 /* add a space to separate each location */
405 xstrlcat(dest, " ", destlen);
412 * Convert a Sun HSFS mount point to an Amd. The result is
413 * concatenated intp dest.
415 * param dest - destination buffer
416 * param destlen - destination buffer length
417 * param key - automount key
418 * param s_entry - Sun entry
421 sun_hsfs2amd(char *dest,
424 const struct sun_entry *s_entry)
426 /* set fstype CDFS */
427 xstrlcat(dest, AMD_TYPE_CDFS_KW, destlen);
428 /* set the cdrom device */
429 xstrlcat(dest, AMD_DEV_KW, destlen);
430 /* XXX: For now just assume that there is only one device. */
431 xstrlcat(dest, s_entry->location_list->path, destlen);
436 * Convert a Sun NFS automount entry to an Amd. The result is concatenated
439 * param dest - destination buffer
440 * param destlen - destination buffer length
441 * param key - automount key
442 * param s_entry - Sun entry
445 sun_nfs2amd(char *dest,
448 const struct sun_entry *s_entry)
450 if (s_entry->location_list != NULL) {
451 /* write out the list of mountpoint locations */
452 sun_locations2amd(dest, destlen, key, s_entry->location_list);
458 * Convert a Sun multi-mount point entry to an Amd. This is done
459 * using the Amd type auto. Each auto entry is separated with a \n.
461 * param dest - destination buffer
462 * param destlen - destination buffer length
463 * param key - automount key
464 * param s_entry - Sun entry
467 sun_multi2amd(char *dest,
470 const struct sun_entry *s_entry)
472 const struct sun_mountpt *mountpt;
474 /* We need to setup a auto fs Amd automount point. */
475 xstrlcat(dest, AMD_TYPE_AUTO_KW, destlen);
476 xstrlcat(dest, AMD_MAP_FS_KW, destlen);
477 xstrlcat(dest, AMD_MAP_PREF_KW, destlen);
479 /* write the mountpts to dest */
480 for (mountpt = s_entry->mountpt_list;
482 mountpt = NEXT(struct sun_mountpt, mountpt)) {
483 xstrlcat(dest, "\n", destlen);
485 xstrlcat(dest, key, destlen);
486 /* write the mount path */
487 sun_append_str(dest, destlen, key, mountpt->path);
489 xstrlcat(dest, " ", destlen);
490 /* Write all the host locations for this mount point. */
491 sun_locations2amd(dest, destlen, key, mountpt->location_list);
497 * Convert the sun_entry into an Amd equivalent string.
499 * param key - automount key
500 * param s_entry - Sun style automap entry
502 * return - Amd entry on succes, NULL on error
505 sun_entry2amd(const char *key, const char *s_entry_str)
508 char line_buff[INFO_MAX_LINE_LEN];
510 struct sun_entry *s_entry = NULL;
512 /* The key should not be NULL. */
514 plog(XLOG_ERROR,"Sun key value was null");
517 /* The Sun entry string should never be NULL. */
518 if (s_entry_str == NULL) {
519 plog(XLOG_ERROR,"Sun entry value was null");
523 /* Make sure there are no trailing white spaces or '\n'. */
524 xstrlcpy(line_buff, s_entry_str, sizeof(line_buff));
525 ws = strlen(line_buff) - 1;
526 while (ws >= 0 && (isspace((unsigned char)line_buff[ws]) || line_buff[ws] == '\n')) {
527 line_buff[ws--] = '\0';
530 /* Parse the sun entry line. */
531 s_entry = sun_map_parse_read(line_buff);
532 if (s_entry == NULL) {
533 plog(XLOG_ERROR,"could not parse Sun style map");
537 memset(line_buff, 0, sizeof(line_buff));
539 if (s_entry->opt_list != NULL) {
540 /* write the mount options to the buffer */
541 sun_opts2amd(line_buff, sizeof(line_buff), key, s_entry->opt_list);
544 /* Check if this is a multi-mount entry. */
545 if (s_entry->mountpt_list != NULL) {
546 /* multi-mount point */
547 sun_multi2amd(line_buff, sizeof(line_buff), key, s_entry);
548 retval = xstrdup(line_buff);
551 /* single mount point */
552 if (s_entry->fstype != NULL) {
553 if (NSTREQ(s_entry->fstype, SUN_NFS_TYPE, strlen(SUN_NFS_TYPE))) {
555 sun_nfs2amd(line_buff, sizeof(line_buff), key, s_entry);
556 retval = xstrdup(line_buff);
558 else if (NSTREQ(s_entry->fstype, SUN_HSFS_TYPE, strlen(SUN_HSFS_TYPE))) {
559 /* HSFS Type (CD fs) */
560 sun_hsfs2amd(line_buff, sizeof(line_buff), key, s_entry);
561 retval = xstrdup(line_buff);
564 * XXX: The following fstypes are not yet supported.
566 else if (NSTREQ(s_entry->fstype, SUN_AUTOFS_TYPE, strlen(SUN_AUTOFS_TYPE))) {
568 plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
573 else if (NSTREQ(s_entry->fstype, SUN_CACHEFS_TYPE, strlen(SUN_CACHEFS_TYPE))) {
575 plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
580 plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.",
586 plog(XLOG_INFO, "No SUN fstype specified defaulting to NFS.");
587 sun_nfs2amd(line_buff, sizeof(line_buff), key, s_entry);
588 retval = xstrdup(line_buff);