summaryrefslogtreecommitdiffstats
path: root/pacsync
blob: 45337916cb9a42dc5a40bea580cc578840c7cb9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#!/bin/bash

version="1.22"
tanpath="/var/lib/pacman"
tandb="pacsync.db"
errors=0
upgrade=0
INSTALL_ROOT="/"

message() {
	echo "==> $1" >&2
}

usage() {
	echo "pacsync version $version"
	echo "usage: $0 [--root <root>] <operation> [package]"
	echo ""
	echo "operations:"
	echo "  sync               Download a fresh package list from the server"
	echo "  install <pkg>      Download and install <pkg>"
	echo "  upgrade <pkg>      Download and upgrade <pkg>"
	echo "  report             Generate a report of all packages that could be upgraded"
	echo "  sysupgrade         Same as \"report\", but actually do the upgrades"
	echo "  clean              Removes all files from package cache to clear up diskspace"
	echo ""
}

checkdb() {
	if [ ! -f $INSTALL_ROOT/$tanpath/$tandb ]; then
		message "missing package list.  (use \"sync\" first)"
		exit 1
	fi
}

download() {
	targ=$1
	shift
	cl=
	for file in $*; do
		cl="$cl $SYNC_SERVER/$file"
	done
	message "Downloading $targ"
	$ftpagent $cl 2>&1
	if [ $? -gt 0 ]; then
		message "error: could not download $targ"
		return 1
	fi
	return 0
}

dosync() {
	cd /tmp
	download "package list" pacsync/$tandb
	if [ $? -gt 0 ]; then
		exit 1
	fi
	rm -f $INSTALL_ROOT/$tanpath/$tandb
	mv /tmp/$tandb $INSTALL_ROOT/$tanpath/$tandb
	message "Done."
}

doinstall() {
	pkg2dl=
	pkg2inst=
	for pkgname in $*; do
		line=`egrep "^[a-z]+/$pkgname-[a-zA-Z0-9\.]+-[0-9]+\.pkg\.tar\.gz$" $INSTALL_ROOT/$tanpath/$tandb`
		if [ $? -gt 0 ]; then
			message "package $pkgname not found"
			exit 1
		fi
		pacman=`pacman -Q -r $INSTALL_ROOT $pkgname 2>/dev/null`
		if [ $? -eq 0 ]; then
			message "$pkgname is already installed (try using \"upgrade\")"
			exit 1
		fi
		filename=`echo $line | sed 's|^[a-z]*/||g'`
		pkg2inst="$pkg2inst $filename"
		if [ ! -f $INSTALL_ROOT/var/cache/pacman/pkg/$filename ]; then
			pkg2dl="$pkg2dl $filename"
		fi
	done

	# download packages that aren't already cached
	if [ "$pkg2dl" != "" ]; then
		download "packages" $pkg2dl
		if [ $? -gt 0 ]; then
			exit 1
		fi
		if [ `pwd` != "$INSTALL_ROOT/var/cache/pacman/pkg" ]; then
			# move downloaded files into cache
			mkdir -p $INSTALL_ROOT/var/cache/pacman/pkg
			mv $pkg2dl $INSTALL_ROOT/var/cache/pacman/pkg/
		fi
	fi

	# install packages
	message "Installing packages"
	cd $INSTALL_ROOT/var/cache/pacman/pkg
	pacman -A -r $INSTALL_ROOT $pkg2inst
	if [ $? -gt 0 ]; then
		message "error: some packages failed to install"
		exit 1
	fi

	message "Done"
	exit 0
}

doupgrade() {
	pkg2dl=
	pkg2up=
	for pkgname in $*; do
		line=`egrep "^[a-z]+/$pkgname-[a-zA-Z0-9\.]+-[0-9]+\.pkg\.tar\.gz$" $INSTALL_ROOT/$tanpath/$tandb`
		if [ $? -gt 0 ]; then
			message "package $pkgname not found"
			exit 1
		fi
		pacman=`pacman -Q -r $INSTALL_ROOT $pkgname 2>/dev/null`
		if [ $? -gt 0 ]; then
						message "$pkgname is not installed (use \"install\" first)"
			exit 1
		fi
		pkgver=`echo $pacman | awk '{print $2}'`
		package="$pkgname-$pkgver"
		filename=`echo $line | sed 's|^[a-z]*/||g'`
		# compare filename and package.  if they are at all different, we
		# assume that the newer version is on the server and do the upgrade
		if [ "$filename" = "$package.pkg.tar.gz" ]; then
			message "$pkgname is already up to date (skipping)"
		else
			pkg2up="$pkg2up $filename"
			if [ ! -f $INSTALL_ROOT/var/cache/pacman/pkg/$filename ]; then
				pkg2dl="$pkg2dl $filename"
			fi
		fi
	done

	# download packages that aren't already cached
	if [ "$pkg2dl" != "" ]; then
		download "packages" $pkg2dl
		if [ $? -gt 0 ]; then
			exit 1
		fi
		if [ `pwd` != "$INSTALL_ROOT/var/cache/pacman/pkg" ]; then
			# move downloaded files into cache
			mkdir -p $INSTALL_ROOT/var/cache/pacman/pkg
			mv $pkg2dl $INSTALL_ROOT/var/cache/pacman/pkg/
		fi
	fi

	# install packages
	if [ "$pkg2up" != "" ]; then
		message "Upgrading packages"
		cd $INSTALL_ROOT/var/cache/pacman/pkg
		pacman -U -r $INSTALL_ROOT $pkg2up
		if [ $? -gt 0 ]; then
			message "error: some packages failed to upgrade"
			exit 1
		fi
		message "Done"
	fi

	exit 0
}

doreport() {
	headers=0
	newkernel=0
	pkg2up=
	for pkgfile in `cat $INTALL_ROOT/$tanpath/$tandb | sed "s|^[a-z]*/||g"`; do
		pkgname=`echo $pkgfile | sed 's|-[a-zA-Z0-9\.]*-[0-9]*\.pkg\.tar\.gz||g'`
		pacman=`pacman -Q -r $INSTALL_ROOT $pkgname 2>/dev/null`
		if [ $? -gt 0 ]; then
			# skip this one, it's not installed
			continue
		fi
		pkgver=`echo $pacman | awk '{print $2}'`
		locfile="$pkgname-$pkgver"
		remfile=`echo $pkgfile | sed 's|^[a-zA-Z]*/||g' | sed 's|\.pkg\.tar\.gz||g'`
		# compare locfile and remfile
		if [ "$locfile" = "$remfile" ]; then
			# this package is up to date
			continue
		else
			if  [ `echo "$locfile" | egrep '^kernel-[a-zA-Z0-9\.]+-[0-9]+$'` ]; then
				newkernel=1
				continue
			fi
			if [ "$headers" = "0" ]; then
				echo "+--------------------------------------+--------------------------------------+"
				echo "|               LOCAL                  |                 REMOTE               |"
				echo "+--------------------------------------+--------------------------------------+"
				headers=1
			fi
			echo -n "| $locfile"
			awk "BEGIN { for (j=length(\"$locfile\"); j<36; j++) printf \" \" }"
			echo -n " | "
			awk "BEGIN { for (j=length(\"$remfile\"); j<36; j++) printf \" \" }"
			echo "$remfile |"
			pkg2up="$pkg2up $pkgname"
		fi
	done
	if [ "$headers" = "1" ]; then
		echo "+--------------------------------------+--------------------------------------+"
	fi

	if [ "$newkernel" = "1" ]; then
		echo
		echo "NOTICE: A new kernel is available for upgrade, but this process will not"
		echo "        upgrade it for you.  If you wish to upgrade, you must explicitly"
		echo "        request it by running 'pacsync upgrade kernel'.  If you choose to"
		echo "        upgrade, make sure you re-run 'lilo' as well!"
		echo
	fi

	# do we upgrade?
	if [ "$upgrade" = "1" -a "$pkg2up" != "" ]; then
		echo ""
		echo -n "Do you want to upgrade these packages? [Y/n] "
		read answer
		echo ""
		if [ "$answer" = "y" -o "$answer" = "Y" -o "$answer" = "" ]; then
			doupgrade $pkg2up
		fi
	fi
	
	exit 0
}

if [ $# -lt 1 ]; then
	usage
	exit 0
fi

if [ "$1" = "--root" ]; then
	shift
	INSTALL_ROOT=$1
	shift
fi

if [ -f /etc/pacsync.conf ]; then
	. /etc/pacsync.conf
else
	message "error: Missing /etc/pacsync.conf configuration file!"
	exit 1
fi

proto=`echo $SYNC_SERVER | sed 's|://.*||'`
# check for a download utility
if [ -x /usr/bin/snarf ]; then
	ftpagent="/usr/bin/snarf"
elif [ -x /usr/bin/lftpget -a "$proto" = "ftp" ]; then
	ftpagent="/usr/bin/lftpget"
elif [ -x /usr/bin/wget ]; then
	ftpagent="/usr/bin/wget --passive-ftp --tries=3 --waitretry=3"
else
	message "error: you need an ftp client installed (snarf/lftp/wget) in /usr/bin"
	exit 1
fi

op=$1
shift
if [ "$1" = "-v" ]; then
	verbose=1
	shift
fi
case $op in
	sync)
		dosync
	;;
	install)
		checkdb
		if [ "$1" = "" ]; then
			message "error: no package specified"
			exit 1
		fi
		doinstall $*
	;;
	upgrade)
		checkdb
		if [ "$1" = "" ]; then
			message "error: no package specified"
			exit 1
		fi
		doupgrade $*
	;;
	report)
		checkdb
		doreport
	;;
	sysupgrade)
		checkdb
		upgrade=1
		doreport
	;;
	clean)
		message "Removing packages from cache"
		rm -f $INSTALL_ROOT/var/cache/pacman/pkg/*
	;;
	*)
		message "error: invalid operation"
		exit 1
	;;
esac