1 |
# Copyright 1999-2005 Gentoo Foundation |
2 |
# Distributed under the terms of the GNU General Public License v2 |
3 |
# $Header: /var/cvsroot/gentoo-x86/eclass/portability.eclass,v 1.16 2010/09/24 02:22:08 vapier Exp $ |
4 |
# |
5 |
# Author: Diego Pettenò <flameeyes@gentoo.org> |
6 |
# |
7 |
# This eclass is created to avoid using non-portable GNUisms inside ebuilds |
8 |
# |
9 |
# NB: If you add anything, please comment it! |
10 |
|
11 |
# treecopy orig1 orig2 orig3 .... dest |
12 |
# |
13 |
# mimic cp --parents copy, but working on BSD userland as well |
14 |
treecopy() { |
15 |
dest=${!#} |
16 |
files_count=$# |
17 |
|
18 |
while(( $# > 1 )); do |
19 |
dirstruct=$(dirname "$1") |
20 |
mkdir -p "${dest}/${dirstruct}" |
21 |
cp -pPR "$1" "${dest}/${dirstruct}" |
22 |
|
23 |
shift |
24 |
done |
25 |
} |
26 |
|
27 |
# seq min max |
28 |
# |
29 |
# compatibility function that mimes seq command if not available |
30 |
seq() { |
31 |
# First try `seq` |
32 |
local p=$(type -P seq) |
33 |
if [[ -n ${p} ]] ; then |
34 |
"${p}" "$@" |
35 |
return $? |
36 |
fi |
37 |
|
38 |
case $# in |
39 |
1) min=1 max=$1 step=1 ;; |
40 |
2) min=$1 max=$2 step=1 ;; |
41 |
3) min=$1 max=$3 step=$2 ;; |
42 |
*) die "seq called with wrong number of arguments" ;; |
43 |
esac |
44 |
|
45 |
# Then try `jot` |
46 |
p=$(type -P jot) |
47 |
if [[ -n ${p} ]] ; then |
48 |
local reps |
49 |
# BSD userland |
50 |
if [[ ${step} != 0 ]] ; then |
51 |
reps=$(( (max - min) / step + 1 )) |
52 |
else |
53 |
reps=0 |
54 |
fi |
55 |
|
56 |
jot $reps $min $max $step |
57 |
return $? |
58 |
fi |
59 |
|
60 |
# Screw it, do the output ourselves |
61 |
while :; do |
62 |
[[ $max < $min && $step > 0 ]] && break |
63 |
[[ $min < $max && $step < 0 ]] && break |
64 |
echo $min |
65 |
: $(( min += step )) |
66 |
done |
67 |
return 0 |
68 |
} |
69 |
|
70 |
# Gets the linker flag to link to dlopen() function |
71 |
dlopen_lib() { |
72 |
# - Solaris needs nothing |
73 |
# - Darwin needs nothing |
74 |
# - *BSD needs nothing |
75 |
# - Linux needs -ldl (glibc and uclibc) |
76 |
# - Interix needs -ldl |
77 |
case "${CHOST}" in |
78 |
*-linux-gnu*|*-linux-uclibc|*-interix*) |
79 |
echo "-ldl" |
80 |
;; |
81 |
esac |
82 |
} |
83 |
|
84 |
# Gets the home directory for the specified user |
85 |
# it's a wrap around egetent as the position of the home directory in the line |
86 |
# varies depending on the os used. |
87 |
# |
88 |
# To use that, inherit eutils, not portability! |
89 |
egethome() { |
90 |
ent=$(egetent passwd $1) |
91 |
|
92 |
case ${CHOST} in |
93 |
*-darwin*|*-freebsd*|*-dragonfly*) |
94 |
# Darwin, OSX, FreeBSD and DragonFly use position 9 to store homedir |
95 |
echo ${ent} | cut -d: -f9 |
96 |
;; |
97 |
*) |
98 |
# Linux, NetBSD and OpenBSD use position 6 instead |
99 |
echo ${ent} | cut -d: -f6 |
100 |
;; |
101 |
esac |
102 |
} |
103 |
|
104 |
# Gets the shell for the specified user |
105 |
# it's a wrap around egetent as the position of the home directory in the line |
106 |
# varies depending on the os used. |
107 |
# |
108 |
# To use that, inherit eutils, not portability! |
109 |
egetshell() { |
110 |
ent=$(egetent passwd "$1") |
111 |
|
112 |
case ${CHOST} in |
113 |
*-darwin*|*-freebsd*|*-dragonfly*) |
114 |
# Darwin, OSX, FreeBSD and DragonFly use position 9 to store homedir |
115 |
echo ${ent} | cut -d: -f10 |
116 |
;; |
117 |
*) |
118 |
# Linux, NetBSD and OpenBSD use position 6 instead |
119 |
echo ${ent} cut -d: -f7 |
120 |
;; |
121 |
esac |
122 |
} |
123 |
|
124 |
# Returns true if specified user has a shell that precludes logins |
125 |
# on whichever operating system. |
126 |
is-login-disabled() { |
127 |
shell=$(egetshell "$1") |
128 |
|
129 |
case ${shell} in |
130 |
/bin/false|/usr/bin/false|/sbin/nologin|/usr/sbin/nologin) |
131 |
return 0 ;; |
132 |
*) |
133 |
return 1 ;; |
134 |
esac |
135 |
} |
136 |
|
137 |
# Gets the name of the BSD-ish make command (pmake from NetBSD) |
138 |
# |
139 |
# This will return make (provided by system packages) for BSD userlands, |
140 |
# or bsdmake for Darwin userlands and pmake for the rest of userlands, |
141 |
# both of which are provided by sys-devel/pmake package. |
142 |
# |
143 |
# Note: the bsdmake for Darwin userland is with compatibility with MacOSX |
144 |
# default name. |
145 |
get_bmake() { |
146 |
if [[ ${USERLAND} == *BSD ]]; then |
147 |
echo make |
148 |
elif [[ ${USERLAND} == "Darwin" ]]; then |
149 |
echo bsdmake |
150 |
else |
151 |
echo pmake |
152 |
fi |
153 |
} |
154 |
|
155 |
# Portable method of getting mount names and points. |
156 |
# Returns as "point node fs options" |
157 |
# Remember to convert 040 back to a space. |
158 |
get_mounts() { |
159 |
local point= node= fs= opts= foo= |
160 |
|
161 |
# Linux has /proc/mounts which should always exist |
162 |
if [[ $(uname -s) == "Linux" ]] ; then |
163 |
while read node point fs opts foo ; do |
164 |
echo "${point} ${node} ${fs} ${opts}" |
165 |
done < /proc/mounts |
166 |
return |
167 |
fi |
168 |
|
169 |
# OK, pray we have a -p option that outputs mounts in fstab format |
170 |
# using tabs as the seperator. |
171 |
# Then pray that there are no tabs in the either. |
172 |
# Currently only FreeBSD supports this and the other BSDs will |
173 |
# have to be patched. |
174 |
# Athough the BSD's may support /proc, they do NOT put \040 in place |
175 |
# of the spaces and we should not force a /proc either. |
176 |
local IFS=$'\t' |
177 |
LC_ALL=C mount -p | while read node point fs foo ; do |
178 |
opts=${fs#* } |
179 |
fs=${fs%% *} |
180 |
echo "${point// /\040} ${node// /\040} ${fs%% *} ${opts// /\040}" |
181 |
done |
182 |
} |
183 |
|