summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-07-22 11:41:00 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-07-22 11:44:28 +0100
commit897a8b5abc3ce3af89c78aa4ce4522487c75f38c (patch)
treec13c7a92c022cb178399a8b9d9795b88b4794412 /scripts
parentdc807f54f858419f97e211cd62fd2d30db9a80de (diff)
downloadpoky-897a8b5abc3ce3af89c78aa4ce4522487c75f38c.tar.gz
stagemanager: Move functionality into the scripts directory
Since scripts is now in PATH thanks to the layer functionality there is no longer any need to have this recipe full of special cases, the scripts can just be placed there. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/stage-manager156
-rwxr-xr-xscripts/stage-manager-ipkg1186
-rwxr-xr-xscripts/stage-manager-ipkg-build246
3 files changed, 1588 insertions, 0 deletions
diff --git a/scripts/stage-manager b/scripts/stage-manager
new file mode 100755
index 0000000000..536d1afda0
--- /dev/null
+++ b/scripts/stage-manager
@@ -0,0 +1,156 @@
1#!/usr/bin/env python
2
3# Copyright (C) 2006-2007 Richard Purdie
4#
5# This program is free software; you can redistribute it and/or modify it under
6# the terms of the GNU General Public License version 2 as published by the Free
7# Software Foundation;
8#
9# This program is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13import optparse
14import os, sys, stat
15
16__version__ = "0.0.1"
17
18
19def write_cache(cachefile, cachedata):
20 fd = open(cachefile, 'w')
21 for f in cachedata:
22 s = f + '|' + str(cachedata[f]['ts']) + '|' + str(cachedata[f]['size'])
23 fd.write(s + '\n')
24 fd.close()
25
26def read_cache(cachefile):
27 cache = {}
28 f = open(cachefile, 'r')
29 lines = f.readlines()
30 f.close()
31 for l in lines:
32 data = l.split('|')
33 cache[data[0]] = {}
34 cache[data[0]]['ts'] = int(data[1])
35 cache[data[0]]['size'] = int(data[2])
36 cache[data[0]]['seen'] = False
37 return cache
38
39def mkdirhier(dir):
40 """Create a directory like 'mkdir -p', but does not complain if
41 directory already exists like os.makedirs
42 """
43 try:
44 os.makedirs(dir)
45 except OSError, e:
46 if e.errno != 17: raise e
47
48if __name__ == "__main__":
49 parser = optparse.OptionParser( version = "Metadata Stage Manager version %s" % ( __version__ ),
50 usage = """%prog [options]\n\nPerforms mamagement tasks on a metadata staging area.""" )
51
52 parser.add_option( "-p", "--parentdir", help = "the path to the metadata parent directory",
53 action = "store", dest = "parentdir", default = None)
54
55 parser.add_option( "-c", "--cachefile", help = "the cache file to use",
56 action = "store", dest = "cachefile", default = None)
57
58 parser.add_option( "-d", "--copydir", help = "copy changed files to this directory",
59 action = "store", dest = "copydir", default = None)
60
61 parser.add_option( "-u", "--update", help = "update the cache file",
62 action = "store_true", dest = "update", default = False)
63
64 (options, args) = parser.parse_args()
65
66 if options.parentdir is None:
67 print("Error, --parentdir option not supplied")
68 sys.exit(1)
69
70 if options.cachefile is None:
71 print("Error, --cachefile option not supplied")
72 sys.exit(1)
73
74 if not options.parentdir.endswith('/'):
75 options.parentdir = options.parentdir + '/'
76
77 cache = {}
78 if os.access(options.cachefile, os.F_OK):
79 cache = read_cache(options.cachefile)
80
81 found_difference = False
82
83 def updateCache(path, fstamp):
84 cache[path] = {}
85 cache[path]['ts'] = fstamp[stat.ST_MTIME]
86 cache[path]['size'] = fstamp[stat.ST_SIZE]
87 cache[path]['seen'] = True
88 found_difference = True
89
90 def copyfile(path):
91 if options.copydir:
92 copypath = os.path.join(options.copydir, path.replace(options.parentdir, '', 1))
93 mkdirhier(os.path.split(copypath)[0])
94 os.system("cp -dp " + path + " " + copypath)
95
96 def copydir(path, fstamp):
97 if options.copydir:
98 copypath = os.path.join(options.copydir, path.replace(options.parentdir, '', 1))
99 if os.path.exists(copypath):
100 os.system("rm -rf " + copypath)
101 if os.path.islink(path):
102 os.symlink(os.readlink(path), copypath)
103 else:
104 mkdirhier(copypath)
105 os.utime(copypath, (fstamp[stat.ST_ATIME], fstamp[stat.ST_MTIME]))
106
107 for root, dirs, files in os.walk(options.parentdir):
108 for f in files:
109 path = os.path.join(root, f)
110 if not os.access(path, os.R_OK):
111 continue
112 fstamp = os.lstat(path)
113 if path not in cache:
114 print "new file %s" % path
115 updateCache(path, fstamp)
116 copyfile(path)
117 else:
118 if cache[path]['ts'] != fstamp[stat.ST_MTIME] or cache[path]['size'] != fstamp[stat.ST_SIZE]:
119 print "file %s changed" % path
120 updateCache(path, fstamp)
121 copyfile(path)
122 cache[path]['seen'] = True
123 for d in dirs:
124 path = os.path.join(root, d)
125 fstamp = os.lstat(path)
126 if path not in cache:
127 print "new dir %s" % path
128 updateCache(path, fstamp)
129 copydir(path, fstamp)
130 else:
131 if cache[path]['ts'] != fstamp[stat.ST_MTIME]:
132 print "dir %s changed" % path
133 updateCache(path, fstamp)
134 copydir(path, fstamp)
135 cache[path]['seen'] = True
136
137 todel = []
138 for path in cache:
139 if not cache[path]['seen']:
140 print "%s removed" % path
141 found_difference = True
142 todel.append(path)
143
144 if options.update:
145 print "Updating"
146 for path in todel:
147 del cache[path]
148 mkdirhier(os.path.split(options.cachefile)[0])
149 write_cache(options.cachefile, cache)
150
151 if found_difference:
152 sys.exit(5)
153 sys.exit(0)
154
155
156
diff --git a/scripts/stage-manager-ipkg b/scripts/stage-manager-ipkg
new file mode 100755
index 0000000000..2559fdbcd8
--- /dev/null
+++ b/scripts/stage-manager-ipkg
@@ -0,0 +1,1186 @@
1#!/bin/sh
2# ipkg - the itsy package management system
3#
4# Copyright (C) 2001 Carl D. Worth
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2, or (at your option)
9# any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15
16set -e
17
18# Uncomment for debugging
19#set -x
20
21# By default do not do globbing. Any command wanting globbing should
22# explicitly enable it first and disable it afterwards.
23set -o noglob
24
25ipkg_srcs() {
26 local srcre="$1"
27 sed -ne "s/^src[[:space:]]\+$srcre[[:space:]]\+//p" < $IPKG_CONF
28}
29
30ipkg_src_names() {
31 sed -ne "s/^src[[:space:]]\+\([^[:space:]]\+\).*/\1/p" < $IPKG_CONF
32}
33
34ipkg_src_byname() {
35 local src="$1"
36 ipkg_srcs $src | head -n1
37}
38
39ipkg_dests() {
40 local destre=`echo $1 | ipkg_protect_slashes`
41 sed -ne "/^dest[[:space:]]\+$destre/{
42s/^dest[[:space:]]\+[^[:space:]]\+[[:space:]]\+//
43s/^/`echo $IPKG_OFFLINE_ROOT | ipkg_protect_slashes`/
44p
45}" < $IPKG_CONF
46}
47
48ipkg_dest_names() {
49 sed -ne "s/^dest[[:space:]]\+\([^[:space:]]\+\).*/\1/p" < $IPKG_CONF
50}
51
52ipkg_dests_all() {
53 ipkg_dests '.*'
54}
55
56ipkg_state_dirs() {
57 ipkg_dests_all | sed "s|\$|/$IPKG_DIR_PREFIX|"
58}
59
60ipkg_dest_default() {
61 ipkg_dests_all | head -n1
62}
63
64ipkg_dest_default_name() {
65 ipkg_dest_names | head -n1
66}
67
68ipkg_dest_byname() {
69 local dest="$1"
70 ipkg_dests $dest | head -n1
71}
72
73ipkg_option() {
74 local option="$1"
75 sed -ne "s/^option[[:space:]]\+$option[[:space:]]\+//p" < $IPKG_CONF
76}
77
78ipkg_load_configuration() {
79 if [ -z "$IPKG_CONF_DIR" ]; then
80 IPKG_CONF_DIR=/etc
81 fi
82
83 if [ -z "$IPKG_CONF" ]; then
84 IPKG_CONF=$IPKG_CONF_DIR/ipkg.conf
85 fi
86
87 if [ -z "$IPKG_OFFLINE_ROOT" ]; then
88 IPKG_OFFLINE_ROOT=`ipkg_option offline_root`
89 fi
90 # Export IPKG_OFFLINE_ROOT for use by update-alternatives
91 export IPKG_OFFLINE_ROOT
92 if [ -n "$DEST_NAME" ]; then
93 IPKG_ROOT=`ipkg_dest_byname $DEST_NAME`
94 if [ -z "$IPKG_ROOT" ]; then
95 if [ -d "$IPKG_OFFLINE_ROOT$DEST_NAME" ]; then
96 IPKG_ROOT="$IPKG_OFFLINE_ROOT$DEST_NAME";
97 else
98 echo "ipkg: invalid destination specification: $DEST_NAME
99Valid destinations are directories or one of the dest names from $IPKG_CONF:" >&2
100 ipkg_dest_names >&2
101 return 1
102 fi
103 fi
104 else
105 IPKG_ROOT=`ipkg_dest_default`
106 fi
107
108 # Global ipkg state directories
109 IPKG_DIR_PREFIX=usr/lib/ipkg
110 IPKG_LISTS_DIR=$IPKG_OFFLINE_ROOT/$IPKG_DIR_PREFIX/lists
111 IPKG_PENDING_DIR=$IPKG_OFFLINE_ROOT/$IPKG_DIR_PREFIX/pending
112 IPKG_TMP=`mktemp -d`
113
114 if [ ! -d "$IPKG_TMP" ]; then
115 echo "Error, could not create a temp directory"
116 return 1
117 fi
118
119 # Destination specific ipkg meta-data directory
120 IPKG_STATE_DIR=$IPKG_ROOT/$IPKG_DIR_PREFIX
121
122 # Proxy Support
123 IPKG_PROXY_USERNAME=`ipkg_option proxy_username`
124 IPKG_PROXY_PASSWORD=`ipkg_option proxy_password`
125 IPKG_HTTP_PROXY=`ipkg_option http_proxy`
126 IPKG_FTP_PROXY=`ipkg_option ftp_proxy`
127 IPKG_NO_PROXY=`ipkg_option no_proxy`
128 if [ -n "$IPKG_HTTP_PROXY" ]; then
129 export http_proxy="$IPKG_HTTP_PROXY"
130 fi
131
132 if [ -n "$IPKG_FTP_PROXY" ]; then
133 export ftp_proxy="$IPKG_FTP_PROXY"
134 fi
135
136 if [ -n "$IPKG_NO_PROXY" ]; then
137 export no_proxy="$IPKG_NO_PROXY"
138 fi
139
140 IPKG_STATUS_FIELDS='\(Package\|Status\|Essential\|Version\|Conffiles\|Root\)'
141}
142
143ipkg_usage() {
144 [ $# -gt 0 ] && echo "ipkg: $*"
145 echo "
146usage: ipkg [options...] sub-command [arguments...]
147where sub-command is one of:
148
149Package Manipulation:
150 update Update list of available packages
151 upgrade Upgrade all installed packages to latest version
152 install <pkg> Download and install <pkg> (and dependencies)
153 install <file.ipk> Install package <file.ipk>
154 install <file.deb> Install package <file.deb>
155 remove <pkg> Remove package <pkg>
156
157Informational Commands:
158 list List available packages and descriptions
159 files <pkg> List all files belonging to <pkg>
160 search <file> Search for a packaging providing <file>
161 info [pkg [<field>]] Display all/some info fields for <pkg> or all
162 status [pkg [<field>]] Display all/some status fields for <pkg> or all
163 depends <pkg> Print uninstalled package dependencies for <pkg>
164
165Options:
166 -d <dest_name> Use <dest_name> as the the root directory for
167 -dest <dest_name> package installation, removal, upgrading.
168 <dest_name> should be a defined dest name from the
169 configuration file, (but can also be a directory
170 name in a pinch).
171 -o <offline_root> Use <offline_root> as the root for offline installation.
172 -offline <offline_root>
173
174Force Options (use when ipkg is too smart for its own good):
175 -force-depends Make dependency checks warnings instead of errors
176 -force-defaults Use default options for questions asked by ipkg.
177 (no prompts). Note that this will not prevent
178 package installation scripts from prompting.
179" >&2
180 exit 1
181}
182
183ipkg_dir_part() {
184 local dir=`echo $1 | sed -ne 's/\(.*\/\).*/\1/p'`
185 if [ -z "$dir" ]; then
186 dir="./"
187 fi
188 echo $dir
189}
190
191ipkg_file_part() {
192 echo $1 | sed 's/.*\///'
193}
194
195ipkg_protect_slashes() {
196 sed -e 's/\//\\\//g'
197}
198
199ipkg_download() {
200 local src="$1"
201 local dest="$2"
202
203 local src_file=`ipkg_file_part $src`
204 local dest_dir=`ipkg_dir_part $dest`
205 if [ -z "$dest_dir" ]; then
206 dest_dir="$IPKG_TMP"
207 fi
208
209 local dest_file=`ipkg_file_part $dest`
210 if [ -z "$dest_file" ]; then
211 dest_file="$src_file"
212 fi
213
214 # Proxy support
215 local proxyuser=""
216 local proxypassword=""
217 local proxyoption=""
218
219 if [ -n "$IPKG_PROXY_USERNAME" ]; then
220 proxyuser="--proxy-user=\"$IPKG_PROXY_USERNAME\""
221 proxypassword="--proxy-passwd=\"$IPKG_PROXY_PASSWORD\""
222 fi
223
224 if [ -n "$IPKG_PROXY_HTTP" -o -n "$IPKG_PROXY_FTP" ]; then
225 proxyoption="--proxy=on"
226 fi
227
228 echo "Downloading $src ..."
229 rm -f $IPKG_TMP/$src_file
230 case "$src" in
231 http://* | ftp://*)
232 if ! wget --passive-ftp -nd $proxyoption $proxyuser $proxypassword -P $IPKG_TMP $src; then
233 echo "ipkg_download: ERROR: Failed to retrieve $src, returning $err"
234 return 1
235 fi
236 mv $IPKG_TMP/$src_file $dest_dir/$dest_file 2>/dev/null
237 ;;
238 file:/* )
239 ln -s `echo $src | sed 's/^file://'` $dest_dir/$dest_file 2>/dev/null
240 ;;
241 *)
242 echo "DEBUG: $src"
243 ;;
244 esac
245
246 echo "Done."
247 return 0
248}
249
250ipkg_update() {
251 if [ ! -e "$IPKG_LISTS_DIR" ]; then
252 mkdir -p $IPKG_LISTS_DIR
253 fi
254
255 local err=
256 for src_name in `ipkg_src_names`; do
257 local src=`ipkg_src_byname $src_name`
258 if ! ipkg_download $src/Packages $IPKG_LISTS_DIR/$src_name; then
259 echo "ipkg_update: Error downloading $src/Packages to $IPKG_LISTS_DIR/$src_name" >&2
260 err=t
261 else
262 echo "Updated list of available packages in $IPKG_LISTS_DIR/$src_name"
263 fi
264 done
265
266 [ -n "$err" ] && return 1
267
268 return 0
269}
270
271ipkg_list() {
272 for src in `ipkg_src_names`; do
273 if ipkg_require_list $src; then
274# black magic...
275sed -ne "
276/^Package:/{
277s/^Package:[[:space:]]*\<\([a-z0-9.+-]*$1[a-z0-9.+-]*\).*/\1/
278h
279}
280/^Description:/{
281s/^Description:[[:space:]]*\(.*\)/\1/
282H
283g
284s/\\
285/ - /
286p
287}
288" $IPKG_LISTS_DIR/$src
289 fi
290 done
291}
292
293ipkg_extract_paragraph() {
294 local pkg="$1"
295 sed -ne "/Package:[[:space:]]*$pkg[[:space:]]*\$/,/^\$/p"
296}
297
298ipkg_extract_field() {
299 local field="$1"
300# blacker magic...
301 sed -ne "
302: TOP
303/^$field:/{
304p
305n
306b FIELD
307}
308d
309: FIELD
310/^$/b TOP
311/^[^[:space:]]/b TOP
312p
313n
314b FIELD
315"
316}
317
318ipkg_extract_value() {
319 sed -e "s/^[^:]*:[[:space:]]*//"
320}
321
322ipkg_require_list() {
323 [ $# -lt 1 ] && return 1
324 local src="$1"
325 if [ ! -f "$IPKG_LISTS_DIR/$src" ]; then
326 echo "ERROR: File not found: $IPKG_LISTS_DIR/$src" >&2
327 echo " You probably want to run \`ipkg update'" >&2
328 return 1
329 fi
330 return 0
331}
332
333ipkg_info() {
334 for src in `ipkg_src_names`; do
335 if ipkg_require_list $src; then
336 case $# in
337 0)
338 cat $IPKG_LISTS_DIR/$src
339 ;;
340 1)
341 ipkg_extract_paragraph $1 < $IPKG_LISTS_DIR/$src
342 ;;
343 *)
344 ipkg_extract_paragraph $1 < $IPKG_LISTS_DIR/$src | ipkg_extract_field $2
345 ;;
346 esac
347 fi
348 done
349}
350
351ipkg_status_sd() {
352 [ $# -lt 1 ] && return 0
353 sd="$1"
354 shift
355 if [ -f $sd/status ]; then
356 case $# in
357 0)
358 cat $sd/status
359 ;;
360 1)
361 ipkg_extract_paragraph $1 < $sd/status
362 ;;
363 *)
364 ipkg_extract_paragraph $1 < $sd/status | ipkg_extract_field $2
365 ;;
366 esac
367 fi
368 return 0
369}
370
371ipkg_status_all() {
372 for sd in `ipkg_state_dirs`; do
373 ipkg_status_sd $sd $*
374 done
375}
376
377ipkg_status() {
378 if [ -n "$DEST_NAME" ]; then
379 ipkg_status_sd $IPKG_STATE_DIR $*
380 else
381 ipkg_status_all $*
382 fi
383}
384
385ipkg_status_matching_sd() {
386 local sd="$1"
387 local re="$2"
388 if [ -f $sd/status ]; then
389 sed -ne "
390: TOP
391/^Package:/{
392s/^Package:[[:space:]]*//
393s/[[:space:]]*$//
394h
395}
396/$re/{
397g
398p
399b NEXT
400}
401d
402: NEXT
403/^$/b TOP
404n
405b NEXT
406" < $sd/status
407 fi
408 return 0
409}
410
411ipkg_status_matching_all() {
412 for sd in `ipkg_state_dirs`; do
413 ipkg_status_matching_sd $sd $*
414 done
415}
416
417ipkg_status_matching() {
418 if [ -n "$DEST_NAME" ]; then
419 ipkg_status_matching_sd $IPKG_STATE_DIR $*
420 else
421 ipkg_status_matching_all $*
422 fi
423}
424
425ipkg_status_installed_sd() {
426 local sd="$1"
427 local pkg="$2"
428 ipkg_status_sd $sd $pkg Status | grep -q "Status: install ok installed"
429}
430
431ipkg_status_installed_all() {
432 local ret=1
433 for sd in `ipkg_state_dirs`; do
434 if `ipkg_status_installed_sd $sd $*`; then
435 ret=0
436 fi
437 done
438 return $ret
439}
440
441ipkg_status_mentioned_sd() {
442 local sd="$1"
443 local pkg="$2"
444 [ -n "`ipkg_status_sd $sd $pkg Status`" ]
445}
446
447ipkg_files() {
448 local pkg="$1"
449 if [ -n "$DEST_NAME" ]; then
450 dests=$IPKG_ROOT
451 else
452 dests=`ipkg_dests_all`
453 fi
454 for dest in $dests; do
455 if [ -f $dest/$IPKG_DIR_PREFIX/info/$pkg.list ]; then
456 dest_sed=`echo $dest | ipkg_protect_slashes`
457 sed -e "s/^/$dest_sed/" < $dest/$IPKG_DIR_PREFIX/info/$pkg.list
458 fi
459 done
460}
461
462ipkg_search() {
463 local pattern="$1"
464
465 for dest_name in `ipkg_dest_names`; do
466 dest=`ipkg_dest_byname $dest_name`
467 dest_sed=`echo $dest | ipkg_protect_slashes`
468
469 set +o noglob
470 local list_files=`ls -1 $dest/$IPKG_DIR_PREFIX/info/*.list 2>/dev/null`
471 set -o noglob
472 for file in $list_files; do
473 if sed "s/^/$dest_sed/" $file | grep -q $pattern; then
474 local pkg=`echo $file | sed "s/^.*\/\(.*\)\.list/\1/"`
475 [ "$dest_name" != `ipkg_dest_default_name` ] && pkg="$pkg ($dest_name)"
476 sed "s/^/$dest_sed/" $file | grep $pattern | sed "s/^/$pkg: /"
477 fi
478 done
479 done
480}
481
482ipkg_status_remove_sd() {
483 local sd="$1"
484 local pkg="$2"
485
486 if [ ! -f $sd/status ]; then
487 mkdir -p $sd
488 touch $sd/status
489 fi
490 sed -ne "/Package:[[:space:]]*$pkg[[:space:]]*\$/,/^\$/!p" < $sd/status > $sd/status.new
491 mv $sd/status.new $sd/status
492}
493
494ipkg_status_remove_all() {
495 for sd in `ipkg_state_dirs`; do
496 ipkg_status_remove_sd $sd $*
497 done
498}
499
500ipkg_status_remove() {
501 if [ -n "$DEST_NAME" ]; then
502 ipkg_status_remove_sd $IPKG_STATE_DIR $*
503 else
504 ipkg_status_remove_all $*
505 fi
506}
507
508ipkg_status_update_sd() {
509 local sd="$1"
510 local pkg="$2"
511
512 ipkg_status_remove_sd $sd $pkg
513 ipkg_extract_field "$IPKG_STATUS_FIELDS" >> $sd/status
514 echo "" >> $sd/status
515}
516
517ipkg_status_update() {
518 ipkg_status_update_sd $IPKG_STATE_DIR $*
519}
520
521ipkg_unsatisfied_dependences() {
522 local pkg=$1
523 local deps=`ipkg_get_depends $pkg`
524 local remaining_deps=
525 for dep in $deps; do
526 local installed=`ipkg_get_installed $dep`
527 if [ "$installed" != "installed" ] ; then
528 remaining_deps="$remaining_deps $dep"
529 fi
530 done
531 ## echo "ipkg_unsatisfied_dependences pkg=$pkg $remaining_deps" > /dev/console
532 echo $remaining_deps
533}
534
535ipkg_safe_pkg_name() {
536 local pkg=$1
537 local spkg=`echo pkg_$pkg | sed -e y/-+./___/`
538 echo $spkg
539}
540
541ipkg_set_depends() {
542 local pkg=$1; shift
543 local new_deps="$*"
544 pkg=`ipkg_safe_pkg_name $pkg`
545 ## setvar ${pkg}_depends "$new_deps"
546 echo $new_deps > $IPKG_TMP/${pkg}.depends
547}
548
549ipkg_get_depends() {
550 local pkg=$1
551 pkg=`ipkg_safe_pkg_name $pkg`
552 cat $IPKG_TMP/${pkg}.depends
553 ## eval "echo \$${pkg}_depends"
554}
555
556ipkg_set_installed() {
557 local pkg=$1
558 pkg=`ipkg_safe_pkg_name $pkg`
559 echo installed > $IPKG_TMP/${pkg}.installed
560 ## setvar ${pkg}_installed "installed"
561}
562
563ipkg_set_uninstalled() {
564 local pkg=$1
565 pkg=`ipkg_safe_pkg_name $pkg`
566 ### echo ipkg_set_uninstalled $pkg > /dev/console
567 echo uninstalled > $IPKG_TMP/${pkg}.installed
568 ## setvar ${pkg}_installed "uninstalled"
569}
570
571ipkg_get_installed() {
572 local pkg=$1
573 pkg=`ipkg_safe_pkg_name $pkg`
574 if [ -f $IPKG_TMP/${pkg}.installed ]; then
575 cat $IPKG_TMP/${pkg}.installed
576 fi
577 ## eval "echo \$${pkg}_installed"
578}
579
580ipkg_depends() {
581 local new_pkgs="$*"
582 local all_deps=
583 local installed_pkgs=`ipkg_status_matching_all 'Status:.*[[:space:]]installed'`
584 for pkg in $installed_pkgs; do
585 ipkg_set_installed $pkg
586 done
587 while [ -n "$new_pkgs" ]; do
588 all_deps="$all_deps $new_pkgs"
589 local new_deps=
590 for pkg in $new_pkgs; do
591 if echo $pkg | grep -q '[^a-z0-9.+-]'; then
592 echo "ipkg_depends: ERROR: Package name $pkg contains illegal characters (should be [a-z0-9.+-])" >&2
593 return 1
594 fi
595 # TODO: Fix this. For now I am ignoring versions and alternations in dependencies.
596 new_deps="$new_deps "`ipkg_info $pkg '\(Pre-\)\?Depends' | ipkg_extract_value | sed -e 's/([^)]*)//g
597s/\(|[[:space:]]*[a-z0-9.+-]\+[[:space:]]*\)\+//g
598s/,/ /g
599s/ \+/ /g'`
600 ipkg_set_depends $pkg $new_deps
601 done
602
603 new_deps=`echo $new_deps | sed -e 's/[[:space:]]\+/\\
604/g' | sort | uniq`
605
606 local maybe_new_pkgs=
607 for pkg in $new_deps; do
608 if ! echo $installed_pkgs | grep -q "\<$pkg\>"; then
609 maybe_new_pkgs="$maybe_new_pkgs $pkg"
610 fi
611 done
612
613 new_pkgs=
614 for pkg in $maybe_new_pkgs; do
615 if ! echo $all_deps | grep -q "\<$pkg\>"; then
616 if [ -z "`ipkg_info $pkg`" ]; then
617 echo "ipkg_depends: Warning: $pkg mentioned in dependency but no package found in $IPKG_LISTS_DIR" >&2
618 ipkg_set_installed $pkg
619 else
620 new_pkgs="$new_pkgs $pkg"
621 ipkg_set_uninstalled $pkg
622 fi
623 else
624 ipkg_set_uninstalled $pkg
625 fi
626 done
627 done
628
629 echo $all_deps
630}
631
632ipkg_get_install_dest() {
633 local dest="$1"
634 shift
635 local sd=$dest/$IPKG_DIR_PREFIX
636 local info_dir=$sd/info
637
638 local requested_pkgs="$*"
639 local pkgs=`ipkg_depends $*`
640
641 mkdir -p $info_dir
642 for pkg in $pkgs; do
643 if ! ipkg_status_mentioned_sd $sd $pkg; then
644 echo "Package: $pkg
645Status: install ok not-installed" | ipkg_status_update_sd $sd $pkg
646 fi
647 done
648 ## mark the packages that we were directly requested to install as uninstalled
649 for pkg in $requested_pkgs; do ipkg_set_uninstalled $pkg; done
650
651 local new_pkgs=
652 local pkgs_installed=0
653 while [ -n "pkgs" ]; do
654 curcheck=0
655 ## echo "pkgs to install: {$pkgs}" > /dev/console
656 for pkg in $pkgs; do
657 curcheck=`expr $curcheck + 1`
658 local is_installed=`ipkg_get_installed $pkg`
659 if [ "$is_installed" = "installed" ]; then
660 echo "$pkg is installed" > /dev/console
661 continue
662 fi
663
664 local remaining_deps=`ipkg_unsatisfied_dependences $pkg`
665 if [ -n "$remaining_deps" ]; then
666 new_pkgs="$new_pkgs $pkg"
667 ### echo "Dependences not satisfied for $pkg: $remaining_deps"
668 if [ $curcheck -ne `echo $pkgs|wc -w` ]; then
669 continue
670 fi
671 fi
672
673 local filename=
674 for src in `ipkg_src_names`; do
675 if ipkg_require_list $src; then
676 filename=`ipkg_extract_paragraph $pkg < $IPKG_LISTS_DIR/$src | ipkg_extract_field Filename | ipkg_extract_value`
677 [ -n "$filename" ] && break
678 fi
679 done
680
681 if [ -z "$filename" ]; then
682 echo "ipkg_get_install: ERROR: Cannot find package $pkg in $IPKG_LISTS_DIR"
683 echo "ipkg_get_install: Check the spelling and maybe run \`ipkg update'."
684 ipkg_status_remove_sd $sd $pkg
685 return 1;
686 fi
687
688 echo ""
689 local tmp_pkg_file="$IPKG_TMP/"`ipkg_file_part $filename`
690 if ! ipkg_download `ipkg_src_byname $src`/$filename $tmp_pkg_file; then
691 echo "ipkg_get_install: Perhaps you need to run \`ipkg update'?"
692 return 1
693 fi
694
695 if ! ipkg_install_file_dest $dest $tmp_pkg_file; then
696 echo "ipkg_get_install: ERROR: Failed to install $tmp_pkg_file"
697 echo "ipkg_get_install: I'll leave it there for you to try a manual installation"
698 return 1
699 fi
700
701 ipkg_set_installed $pkg
702 pkgs_installed=`expr $pkgs_installed + 1`
703 rm $tmp_pkg_file
704 done
705 ### echo "Installed $pkgs_installed package(s) this round"
706 if [ $pkgs_installed -eq 0 ]; then
707 if [ -z "$new_pkgs" ]; then
708 break
709 fi
710 fi
711 pkgs_installed=0
712 pkgs="$new_pkgs"
713 new_pkgs=
714 curcheck=0
715 done
716}
717
718ipkg_get_install() {
719 ipkg_get_install_dest $IPKG_ROOT $*
720}
721
722ipkg_install_file_dest() {
723 local dest="$1"
724 local filename="$2"
725 local sd=$dest/$IPKG_DIR_PREFIX
726 local info_dir=$sd/info
727
728 if [ ! -f "$filename" ]; then
729 echo "ipkg_install_file: ERROR: File $filename not found"
730 return 1
731 fi
732
733 local pkg=`ipkg_file_part $filename | sed 's/\([a-z0-9.+-]\+\)_.*/\1/'`
734 local ext=`echo $filename | sed 's/.*\.//'`
735 local pkg_extract_stdout
736 #if [ "$ext" = "ipk" ]; then
737 # pkg_extract_stdout="tar -xzOf"
738 #elif [ "$ext" = "deb" ]; then
739 pkg_extract_stdout="ar p"
740 #else
741 # echo "ipkg_install_file: ERROR: File $filename has unknown extension $ext (not .ipk or .deb)"
742 # return 1
743 #fi
744
745 # Check dependencies
746 local depends=`ipkg_depends $pkg | sed -e "s/\<$pkg\>//"`
747
748 # Don't worry about deps that are scheduled for installation
749 local missing_deps=
750 for dep in $depends; do
751 if ! ipkg_status_all $dep | grep -q 'Status:[[:space:]]install'; then
752 missing_deps="$missing_deps $dep"
753 fi
754 done
755
756 if [ ! -z "$missing_deps" ]; then
757 if [ -n "$FORCE_DEPENDS" ]; then
758 echo "ipkg_install_file: Warning: $pkg depends on the following uninstalled programs: $missing_deps"
759 else
760 echo "ipkg_install_file: ERROR: $pkg depends on the following uninstalled programs:
761 $missing_deps"
762 echo "ipkg_install_file: You may want to use \`ipkg install' to install these."
763 return 1
764 fi
765 fi
766
767 mkdir -p $IPKG_TMP/$pkg/control
768 mkdir -p $IPKG_TMP/$pkg/data
769 mkdir -p $info_dir
770
771 if ! $pkg_extract_stdout $filename control.tar.gz | (cd $IPKG_TMP/$pkg/control; tar -xzf - ) ; then
772 echo "ipkg_install_file: ERROR unpacking control.tar.gz from $filename"
773 return 1
774 fi
775
776 if [ -n "$IPKG_OFFLINE_ROOT" ]; then
777 if grep -q '^InstallsOffline:[[:space:]]*no' $IPKG_TMP/$pkg/control/control; then
778 echo "*** Warning: Package $pkg may not be installed in offline mode"
779 echo "*** Warning: Scheduling $filename for pending installation (installing into $IPKG_PENDING_DIR)"
780 echo "Package: $pkg
781Status: install ok pending" | ipkg_status_update_sd $sd $pkg
782 mkdir -p $IPKG_PENDING_DIR
783 cp $filename $IPKG_PENDING_DIR
784 rm -r $IPKG_TMP/$pkg/control
785 rm -r $IPKG_TMP/$pkg/data
786 rmdir $IPKG_TMP/$pkg
787 return 0
788 fi
789 fi
790
791
792 echo -n "Unpacking $pkg..."
793 set +o noglob
794 for file in $IPKG_TMP/$pkg/control/*; do
795 local base_file=`ipkg_file_part $file`
796 mv $file $info_dir/$pkg.$base_file
797 done
798 set -o noglob
799 rm -r $IPKG_TMP/$pkg/control
800
801 if ! $pkg_extract_stdout $filename ./data.tar.gz | (cd $IPKG_TMP/$pkg/data; tar -xzf - ) ; then
802 echo "ipkg_install_file: ERROR unpacking data.tar.gz from $filename"
803 return 1
804 fi
805 echo "Done."
806
807 echo -n "Configuring $pkg..."
808 export PKG_ROOT=$dest
809 if [ -x "$info_dir/$pkg.preinst" ]; then
810 if ! $info_dir/$pkg.preinst install; then
811 echo "$info_dir/$pkg.preinst failed. Aborting installation of $pkg"
812 rm -rf $IPKG_TMP/$pkg/data
813 rmdir $IPKG_TMP/$pkg
814 return 1
815 fi
816 fi
817
818 local old_conffiles=`ipkg_status_sd $sd $pkg Conffiles | ipkg_extract_value`
819 local new_conffiles=
820 if [ -f "$info_dir/$pkg.conffiles" ]; then
821 for conffile in `cat $info_dir/$pkg.conffiles`; do
822 if [ -f "$dest/$conffile" ] && ! echo " $old_conffiles " | grep -q " $conffile "`md5sum $dest/$conffile | sed 's/ .*//'`; then
823 local use_maintainers_conffile=
824 if [ -z "$FORCE_DEFAULTS" ]; then
825 while true; do
826 echo -n "Configuration file \`$conffile'
827 ==> File on system created by you or by a script.
828 ==> File also in package provided by package maintainer.
829 What would you like to do about it ? Your options are:
830 Y or I : install the package maintainer's version
831 N or O : keep your currently-installed version
832 D : show the differences between the versions (if diff is installed)
833 The default action is to keep your current version.
834*** `ipkg_file_part $conffile` (Y/I/N/O/D) [default=N] ? "
835 read response
836 case "$response" in
837 [YyIi] | [Yy][Ee][Ss])
838 use_maintainers_conffile=t
839 break
840 ;;
841 [Dd])
842 echo "
843diff -u $dest/$conffile $IPKG_TMP/$pkg/data/$conffile"
844 diff -u $dest/$conffile $IPKG_TMP/$pkg/data/$conffile || true
845 echo "[Press ENTER to continue]"
846 read junk
847 ;;
848 *)
849 break
850 ;;
851 esac
852 done
853 fi
854 if [ -n "$use_maintainers_conffile" ]; then
855 local md5sum=`md5sum $IPKG_TMP/$pkg/data/$conffile | sed 's/ .*//'`
856 new_conffiles="$new_conffiles $conffile $md5sum"
857 else
858 new_conffiles="$new_conffiles $conffile <custom>"
859 rm $IPKG_TMP/$pkg/data/$conffile
860 fi
861 else
862 md5sum=`md5sum $IPKG_TMP/$pkg/data/$conffile | sed 's/ .*//'`
863 new_conffiles="$new_conffiles $conffile $md5sum"
864 fi
865 done
866 fi
867
868 local owd=`pwd`
869 (cd $IPKG_TMP/$pkg/data/; tar cf - . | (cd $owd; cd $dest; tar xf -))
870 rm -rf $IPKG_TMP/$pkg/data
871 rmdir $IPKG_TMP/$pkg
872 $pkg_extract_stdout $filename ./data.tar.gz | tar tzf - | sed -e 's/^\.//' > $info_dir/$pkg.list
873
874 if [ -x "$info_dir/$pkg.postinst" ]; then
875 $info_dir/$pkg.postinst configure
876 fi
877
878 if [ -n "$new_conffiles" ]; then
879 new_conffiles='Conffiles: '`echo $new_conffiles | ipkg_protect_slashes`
880 fi
881 local sed_safe_root=`echo $dest | sed -e "s#^${IPKG_OFFLINE_ROOT}##" | ipkg_protect_slashes`
882 sed -e "s/\(Package:.*\)/\1\\
883Status: install ok installed\\
884Root: ${sed_safe_root}\\
885${new_conffiles}/" $info_dir/$pkg.control | ipkg_status_update_sd $sd $pkg
886
887 rm -f $info_dir/$pkg.control
888 rm -f $info_dir/$pkg.conffiles
889 rm -f $info_dir/$pkg.preinst
890 rm -f $info_dir/$pkg.postinst
891
892 echo "Done."
893}
894
895ipkg_install_file() {
896 ipkg_install_file_dest $IPKG_ROOT $*
897}
898
899ipkg_install() {
900
901 while [ $# -gt 0 ]; do
902 local pkg="$1"
903 shift
904
905 case "$pkg" in
906 http://* | ftp://*)
907 local tmp_pkg_file="$IPKG_TMP/"`ipkg_file_part $pkg`
908 if ipkg_download $pkg $tmp_pkg_file; then
909 ipkg_install_file $tmp_pkg_file
910 rm $tmp_pkg_file
911 fi
912 ;;
913 file:/*.ipk | file://*.deb)
914 local ipkg_filename="`echo $pkg|sed 's/^file://'`"
915 ipkg_install_file $ipkg_filename
916 ;;
917 *.ipk | *.deb)
918 if [ -f "$pkg" ]; then
919 ipkg_install_file $pkg
920 else
921 echo "File not found $pkg" >&2
922 fi
923 ;;
924 *)
925 ipkg_get_install $pkg || true
926 ;;
927 esac
928 done
929}
930
931ipkg_install_pending() {
932 [ -n "$IPKG_OFFLINE_ROOT" ] && return 0
933
934 if [ -d "$IPKG_PENDING_DIR" ]; then
935 set +o noglob
936 local pending=`ls -1d $IPKG_PENDING_DIR/*.ipk 2> /dev/null` || true
937 set -o noglob
938 if [ -n "$pending" ]; then
939 echo "The following packages in $IPKG_PENDING_DIR will now be installed:"
940 echo $pending
941 for filename in $pending; do
942 if ipkg_install_file $filename; then
943 rm $filename
944 fi
945 done
946 fi
947 fi
948 return 0
949}
950
951ipkg_install_wanted() {
952 local wanted=`ipkg_status_matching 'Status:[[:space:]]*install.*not-installed'`
953
954 if [ -n "$wanted" ]; then
955 echo "The following package were previously requested but have not been installed:"
956 echo $wanted
957
958 if [ -n "$FORCE_DEFAULTS" ]; then
959 echo "Installing them now."
960 else
961 echo -n "Install them now [Y/n] ? "
962 read response
963 case "$response" in
964 [Nn] | [Nn][Oo])
965 return 0
966 ;;
967 esac
968 fi
969
970 ipkg_install $wanted
971 fi
972
973 return 0
974}
975
976ipkg_upgrade_pkg() {
977 local pkg="$1"
978 local avail_ver=`ipkg_info $pkg Version | ipkg_extract_value | head -n1`
979
980 is_installed=
981 for dest_name in `ipkg_dest_names`; do
982 local dest=`ipkg_dest_byname $dest_name`
983 local sd=$dest/$IPKG_DIR_PREFIX
984 local inst_ver=`ipkg_status_sd $sd $pkg Version | ipkg_extract_value`
985 if [ -n "$inst_ver" ]; then
986 is_installed=t
987
988 if [ -z "$avail_ver" ]; then
989 echo "Assuming locally installed package $pkg ($inst_ver) is up to date"
990 return 0
991 fi
992
993 if [ "$avail_ver" = "$inst_ver" ]; then
994 echo "Package $pkg ($inst_ver) installed in $dest_name is up to date"
995 elif ipkg-compare-versions $avail_ver '>>' $inst_ver; then
996 echo "Upgrading $pkg ($dest_name) from $inst_ver to $avail_ver"
997 ipkg_get_install_dest $dest $pkg
998 else
999 echo "Not downgrading package $pkg from $inst_ver to $avail_ver"
1000 fi
1001 fi
1002 done
1003
1004 if [ -z "$is_installed" ]; then
1005 echo "Package $pkg does not appear to be installed"
1006 return 0
1007 fi
1008
1009}
1010
1011ipkg_upgrade() {
1012 if [ $# -lt 1 ]; then
1013 local pkgs=`ipkg_status_matching 'Status:.*[[:space:]]installed'`
1014 else
1015 pkgs="$*"
1016 fi
1017
1018 for pkg in $pkgs; do
1019 ipkg_upgrade_pkg $pkg
1020 done
1021}
1022
1023ipkg_remove_pkg_dest() {
1024 local dest="$1"
1025 local pkg="$2"
1026 local sd=$dest/$IPKG_DIR_PREFIX
1027 local info_dir=$sd/info
1028
1029 if ! ipkg_status_installed_sd $sd $pkg; then
1030 echo "ipkg_remove: Package $pkg does not appear to be installed in $dest"
1031 if ipkg_status_mentioned_sd $sd $pkg; then
1032 echo "Purging mention of $pkg from the ipkg database"
1033 ipkg_status_remove_sd $sd $pkg
1034 fi
1035 return 1
1036 fi
1037
1038 echo "ipkg_remove: Removing $pkg... "
1039
1040 local files=`cat $info_dir/$pkg.list`
1041
1042 export PKG_ROOT=$dest
1043 if [ -x "$info_dir/$pkg.prerm" ]; then
1044 $info_dir/$pkg.prerm remove
1045 fi
1046
1047 local conffiles=`ipkg_status_sd $sd $pkg Conffiles | ipkg_extract_value`
1048
1049 local dirs_to_remove=
1050 for file in $files; do
1051 if [ -d "$dest/$file" ]; then
1052 dirs_to_remove="$dirs_to_remove $dest/$file"
1053 else
1054 if echo " $conffiles " | grep -q " $file "; then
1055 if echo " $conffiles " | grep -q " $file "`md5sum $dest/$file | sed 's/ .*//'`; then
1056 rm -f $dest/$file
1057 fi
1058 else
1059 rm -f $dest/$file
1060 fi
1061 fi
1062 done
1063
1064 local removed_a_dir=t
1065 while [ -n "$removed_a_dir" ]; do
1066 removed_a_dir=
1067 local new_dirs_to_remove=
1068 for dir in $dirs_to_remove; do
1069 if rmdir $dir >/dev/null 2>&1; then
1070 removed_a_dir=t
1071 else
1072 new_dirs_to_remove="$new_dirs_to_remove $dir"
1073 fi
1074 done
1075 dirs_to_remove="$new_dirs_to_remove"
1076 done
1077
1078 if [ -n "$dirs_to_remove" ]; then
1079 echo "ipkg_remove: Warning: Not removing the following directories since they are not empty:" >&2
1080 echo "$dirs_to_remove" | sed -e 's/\/[/]\+/\//g' >&2
1081 fi
1082
1083 if [ -x "$info_dir/$pkg.postrm" ]; then
1084 $info_dir/$pkg.postrm remove
1085 fi
1086
1087 ipkg_status_remove_sd $sd $pkg
1088 set +o noglob
1089 rm -f $info_dir/$pkg.*
1090 set -o noglob
1091
1092 echo "Done."
1093}
1094
1095ipkg_remove_pkg() {
1096 local pkg="$1"
1097 for dest in `ipkg_dests_all`; do
1098 local sd=$dest/$IPKG_DIR_PREFIX
1099 if ipkg_status_mentioned_sd $sd $pkg; then
1100 ipkg_remove_pkg_dest $dest $pkg
1101 fi
1102 done
1103}
1104
1105ipkg_remove() {
1106 while [ $# -gt 0 ]; do
1107 local pkg="$1"
1108 shift
1109 if [ -n "$DEST_NAME" ]; then
1110 ipkg_remove_pkg_dest $IPKG_ROOT $pkg
1111 else
1112 ipkg_remove_pkg $pkg
1113 fi
1114 done
1115}
1116
1117ipkg_list_installed() {
1118 echo `ipkg_status_matching 'Status:.*[[:space:]]installed'`
1119}
1120###########
1121# ipkg main
1122###########
1123
1124# Parse options
1125while [ $# -gt 0 ]; do
1126 arg="$1"
1127 case $arg in
1128 -d | -dest)
1129 [ $# -gt 1 ] || ipkg_usage "option $arg requires an argument"
1130 DEST_NAME="$2"
1131 shift
1132 ;;
1133 -o | -offline)
1134 [ $# -gt 1 ] || ipkg_usage "option $arg requires an argument"
1135 IPKG_OFFLINE_ROOT="$2"
1136 shift
1137 ;;
1138 -force-depends)
1139 FORCE_DEPENDS=t
1140 ;;
1141 -force-defaults)
1142 FORCE_DEFAULTS=t
1143 ;;
1144 -f)
1145 [ $# -gt 1 ] || ipkg_usage "option $arg requires an argument"
1146 IPKG_CONF="$2"
1147 shift
1148 ;;
1149 -*)
1150 ipkg_usage "unknown option $arg"
1151 ;;
1152 *)
1153 break
1154 ;;
1155 esac
1156 shift
1157done
1158
1159[ $# -lt 1 ] && ipkg_usage "ipkg must have one sub-command argument"
1160cmd="$1"
1161shift
1162
1163ipkg_load_configuration
1164
1165case "$cmd" in
1166update|upgrade|list|info|status|install_pending|list_installed)
1167 ;;
1168install|depends|remove|files|search)
1169 [ $# -lt 1 ] && ipkg_usage "ERROR: the \`\`$cmd'' command requires an argument"
1170 ;;
1171*)
1172 echo "ERROR: unknown sub-command \`$cmd'"
1173 ipkg_usage
1174 ;;
1175esac
1176
1177# Only install pending if we have an interactive sub-command
1178case "$cmd" in
1179upgrade|install)
1180 ipkg_install_pending
1181 ipkg_install_wanted
1182 ;;
1183esac
1184
1185ipkg_$cmd $*
1186rm -rf $IPKG_TMP
diff --git a/scripts/stage-manager-ipkg-build b/scripts/stage-manager-ipkg-build
new file mode 100755
index 0000000000..77367ac35a
--- /dev/null
+++ b/scripts/stage-manager-ipkg-build
@@ -0,0 +1,246 @@
1#!/bin/sh
2
3# ipkg-build -- construct a .ipk from a directory
4# Carl Worth <cworth@east.isi.edu>
5# based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
6# 2003-04-25 rea@sr.unh.edu
7# Updated to work on Familiar Pre0.7rc1, with busybox tar.
8# Note it Requires: binutils-ar (since the busybox ar can't create)
9# For UID debugging it needs a better "find".
10set -e
11
12version=1.0
13
14ipkg_extract_value() {
15 sed -e "s/^[^:]*:[[:space:]]*//"
16}
17
18required_field() {
19 field=$1
20
21 value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
22 if [ -z "$value" ]; then
23 echo "*** Error: $CONTROL/control is missing field $field" >&2
24 return 1
25 fi
26 echo $value
27 return 0
28}
29
30disallowed_field() {
31 field=$1
32
33 value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
34 if [ -n "$value" ]; then
35 echo "*** Error: $CONTROL/control contains disallowed field $field" >&2
36 return 1
37 fi
38 echo $value
39 return 0
40}
41
42pkg_appears_sane() {
43 local pkg_dir=$1
44
45 local owd=`pwd`
46 cd $pkg_dir
47
48 PKG_ERROR=0
49
50 tilde_files=`find . -name '*~'`
51 if [ -n "$tilde_files" ]; then
52 if [ "$noclean" = "1" ]; then
53 echo "*** Warning: The following files have names ending in '~'.
54You probably want to remove them: " >&2
55 ls -ld $tilde_files
56 echo >&2
57 else
58 echo "*** Removing the following files: $tilde_files"
59 rm -f "$tilde_files"
60 fi
61 fi
62
63 large_uid_files=`find . -uid +99 || true`
64
65 if [ "$ogargs" = "" ] && [ -n "$large_uid_files" ]; then
66 echo "*** Warning: The following files have a UID greater than 99.
67You probably want to chown these to a system user: " >&2
68 ls -ld $large_uid_files
69 echo >&2
70 fi
71
72
73 if [ ! -f "$CONTROL/control" ]; then
74 echo "*** Error: Control file $pkg_dir/$CONTROL/control not found." >&2
75 cd $owd
76 return 1
77 fi
78
79 pkg=`required_field Package`
80 [ "$?" -ne 0 ] && PKG_ERROR=1
81
82 version=`required_field Version | sed 's/Version://; s/^.://g;'`
83 [ "$?" -ne 0 ] && PKG_ERROR=1
84
85 arch=`required_field Architecture`
86 [ "$?" -ne 0 ] && PKG_ERROR=1
87
88 required_field Maintainer >/dev/null
89 [ "$?" -ne 0 ] && PKG_ERROR=1
90
91 required_field Description >/dev/null
92 [ "$?" -ne 0 ] && PKG_ERROR=1
93
94 section=`required_field Section`
95 [ "$?" -ne 0 ] && PKG_ERROR=1
96 if [ -z "$section" ]; then
97 echo "The Section field should have one of the following values:" >&2
98 echo "admin, base, comm, editors, extras, games, graphics, kernel, libs, misc, net, text, web, x11" >&2
99 fi
100
101 priority=`required_field Priority`
102 [ "$?" -ne 0 ] && PKG_ERROR=1
103 if [ -z "$priority" ]; then
104 echo "The Priority field should have one of the following values:" >&2
105 echo "required, important, standard, optional, extra." >&2
106 echo "If you don't know which priority value you should be using, then use \`optional'" >&2
107 fi
108
109 source=`required_field Source`
110 [ "$?" -ne 0 ] && PKG_ERROR=1
111 if [ -z "$source" ]; then
112 echo "The Source field contain the URL's or filenames of the source code and any patches"
113 echo "used to build this package. Either gnu-style tarballs or Debian source packages "
114 echo "are acceptable. Relative filenames may be used if they are distributed in the same"
115 echo "directory as the .ipk file."
116 fi
117
118 disallowed_filename=`disallowed_field Filename`
119 [ "$?" -ne 0 ] && PKG_ERROR=1
120
121 if echo $pkg | grep '[^a-z0-9.+-]'; then
122 echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
123 PKG_ERROR=1;
124 fi
125
126 local bad_fields=`sed -ne 's/^\([^[:space:]][^:[:space:]]\+[[:space:]]\+\)[^:].*/\1/p' < $CONTROL/control | sed -e 's/\\n//'`
127 if [ -n "$bad_fields" ]; then
128 bad_fields=`echo $bad_fields`
129 echo "*** Error: The following fields in $CONTROL/control are missing a ':'" >&2
130 echo " $bad_fields" >&2
131 echo "ipkg-build: This may be due to a missing initial space for a multi-line field value" >&2
132 PKG_ERROR=1
133 fi
134
135 for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
136 if [ -f $script -a ! -x $script ]; then
137 echo "*** Error: package script $script is not executable" >&2
138 PKG_ERROR=1
139 fi
140 done
141
142 if [ -f $CONTROL/conffiles ]; then
143 for cf in `cat $CONTROL/conffiles`; do
144 if [ ! -f ./$cf ]; then
145 echo "*** Error: $CONTROL/conffiles mentions conffile $cf which does not exist" >&2
146 PKG_ERROR=1
147 fi
148 done
149 fi
150
151 cd $owd
152 return $PKG_ERROR
153}
154
155###
156# ipkg-build "main"
157###
158ogargs=""
159outer=ar
160noclean=0
161usage="Usage: $0 [-c] [-C] [-o owner] [-g group] <pkg_directory> [<destination_directory>]"
162while getopts "cg:ho:v" opt; do
163 case $opt in
164 o ) owner=$OPTARG
165 ogargs="--owner=$owner"
166 ;;
167 g ) group=$OPTARG
168 ogargs="$ogargs --group=$group"
169 ;;
170 c ) outer=tar
171 ;;
172 C ) noclean=1
173 ;;
174 v ) echo $version
175 exit 0
176 ;;
177 h ) echo $usage >&2 ;;
178 \? ) echo $usage >&2
179 esac
180done
181
182
183shift $(($OPTIND - 1))
184
185# continue on to process additional arguments
186
187case $# in
1881)
189 dest_dir=$PWD
190 ;;
1912)
192 dest_dir=$2
193 if [ "$dest_dir" = "." -o "$dest_dir" = "./" ] ; then
194 dest_dir=$PWD
195 fi
196 ;;
197*)
198 echo $usage >&2
199 exit 1
200 ;;
201esac
202
203pkg_dir=$1
204
205if [ ! -d $pkg_dir ]; then
206 echo "*** Error: Directory $pkg_dir does not exist" >&2
207 exit 1
208fi
209
210# CONTROL is second so that it takes precedence
211CONTROL=
212[ -d $pkg_dir/DEBIAN ] && CONTROL=DEBIAN
213[ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
214if [ -z "$CONTROL" ]; then
215 echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
216 exit 1
217fi
218
219if ! pkg_appears_sane $pkg_dir; then
220 echo >&2
221 echo "ipkg-build: Please fix the above errors and try again." >&2
222 exit 1
223fi
224
225tmp_dir=$dest_dir/IPKG_BUILD.$$
226mkdir $tmp_dir
227
228echo $CONTROL > $tmp_dir/tarX
229( cd $pkg_dir && tar $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . )
230( cd $pkg_dir/$CONTROL && tar $ogargs -czf $tmp_dir/control.tar.gz . )
231rm $tmp_dir/tarX
232
233echo "2.0" > $tmp_dir/debian-binary
234
235pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
236rm -f $pkg_file
237if [ "$outer" = "ar" ] ; then
238 ( cd $tmp_dir && ar -crf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
239else
240 ( cd $tmp_dir && tar -zcf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
241fi
242
243rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
244rmdir $tmp_dir
245
246echo "Packaged contents of $pkg_dir into $pkg_file"