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.
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
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
43 * File: am-utils/amd/sun_map.c
49 #endif /* HAVE_CONFIG_H */
57 * Add a data pointer to the end of the list.
60 sun_list_add(struct sun_list
*list
, qelem
*item
)
62 if (list
->last
== NULL
) {
68 list
->last
->q_forw
= item
;
69 item
->q_back
= list
->last
;
78 * Sun2Amd conversion routines
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
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
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
) {
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
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
178 if ((tmp
= sun_strsub(retval
, str
, sub
)) != NULL
) {
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
192 * param str - source string
194 * return - A new string with the expansions, NULL if str does not
195 * exist in src or error.
198 sun_expand2amd(const char *str
)
201 char *retval
= NULL
, *tmp
= NULL
, *tmp2
= NULL
;
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
212 for (pos
= str
; *pos
!= '\0'; pos
++) {
222 * If a 'replace' does not return NULL than a variable was
223 * successfully substituted.
227 if ((tmp2
= sun_strsub(tmp
, SUN_ARCH
, AMD_ARCH
)) != NULL
) {
230 /* cpu - there is not POSIX uname for cpu so just use machine */
231 if ((tmp2
= sun_strsub(tmp
, SUN_CPU
, AMD_ARCH
)) != NULL
) {
235 if ((tmp2
= sun_strsub(tmp
, SUN_HOST
, AMD_HOST
)) != NULL
) {
239 if ((tmp2
= sun_strsub(tmp
, SUN_OSNAME
, AMD_OSNAME
)) != NULL
) {
243 * os release - Amd doesn't hava a OS release var just usr os
246 if ((tmp2
= sun_strsub(tmp
, SUN_OSREL
, AMD_OSVER
)) != NULL
) {
250 if ((tmp2
= sun_strsub(tmp
, SUN_OSVERS
, AMD_OSVER
)) != NULL
) {
253 /* native instruction set - there is no POSIX natisa so just use system */
254 if ((tmp2
= sun_strsub(tmp
, SUN_NATISA
, AMD_ARCH
)) != NULL
) {
273 * This is a wrapper function for appending Amd entry information to a
274 * buffer. Any Sun variable substitutions will be converted into Amd
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
283 sun_append_str(char *dest
,
288 char *sub
= NULL
, *sub2
= NULL
, *out
= NULL
;
290 /* By default we are going to just write the original string. */
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
302 if ((sub
= sun_strsub(str
, SUN_KEY_SUB
, "${key}")) != NULL
) {
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
) {
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
) {
321 xstrlcat(dest
, out
, destlen
);
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
342 sun_opts2amd(char *dest
,
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
373 sun_locations2amd(char *dest
,
376 const struct sun_location
*local_list
)
378 const struct sun_location
*local
;
379 const struct sun_host
*host
;
381 for (local
= local_list
;
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
;
392 host
= NEXT(struct sun_host
, host
)) {
394 xstrlcat(dest
, AMD_TYPE_NFS_KW
, destlen
);
395 /* add rhost key word */
396 xstrlcat(dest
, AMD_RHOST_KW
, destlen
);
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
);
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
);
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
433 sun_hsfs2amd(char *dest
,
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
451 * param dest - destination buffer
452 * param destlen - destination buffer length
453 * param key - automount key
454 * param s_entry - Sun entry
457 sun_nfs2amd(char *dest
,
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
479 sun_multi2amd(char *dest
,
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
;
494 mountpt
= NEXT(struct sun_mountpt
, mountpt
)) {
495 xstrlcat(dest
, "\n", destlen
);
497 xstrlcat(dest
, key
, destlen
);
498 /* write the mount path */
499 sun_append_str(dest
, destlen
, key
, mountpt
->path
);
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
517 sun_entry2amd(const char *key
, const char *s_entry_str
)
520 char line_buff
[INFO_MAX_LINE_LEN
];
522 struct sun_entry
*s_entry
= NULL
;
524 /* The key should not be NULL. */
526 plog(XLOG_ERROR
,"Sun key value was null");
529 /* The Sun entry string should never be NULL. */
530 if (s_entry_str
== NULL
) {
531 plog(XLOG_ERROR
,"Sun entry value was null");
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");
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
);
563 /* single mount point */
564 if (s_entry
->fstype
!= NULL
) {
565 if (NSTREQ(s_entry
->fstype
, SUN_NFS_TYPE
, strlen(SUN_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
))) {
580 plog(XLOG_ERROR
, "Sun fstype %s is currently not supported by Amd.",
585 else if (NSTREQ(s_entry
->fstype
, SUN_CACHEFS_TYPE
, strlen(SUN_CACHEFS_TYPE
))) {
587 plog(XLOG_ERROR
, "Sun fstype %s is currently not supported by Amd.",
592 plog(XLOG_ERROR
, "Sun fstype %s is currently not supported by Amd.",
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
);
605 if (s_entry
!= NULL
) {