aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2006-07-16 15:00:39 +0200
committerWilly Tarreau <willy@wtap.(none)>2006-07-26 11:56:43 +0200
commit5948769d62fc83dd6640fdc97429286dbae617b7 (patch)
tree9f324643c410c0b6712e351e7388a4c332fe35ba
parent[RELEASE] flxutils-0.1.29 (diff)
downloadflxutils-5948769d62fc83dd6640fdc97429286dbae617b7.tar.xz
[MEDIUM] - pkg-0.7.1 : * newpkg: don't look for newname in .. anymore, and select only the packages containing a build.cfg * newpkg: do not propose a list of multiple identical new names * release: also identify non-shell text scripts. * release: put only package's basename in changelogs.
-rw-r--r--.flxpkg/ChangeLog62
-rw-r--r--.flxpkg/build.cfg64
-rw-r--r--ChangeLog54
-rw-r--r--findcdrom/findcdrom.c127
-rw-r--r--include/rules.make10
-rw-r--r--init/init-cleanup.c1808
-rwxr-xr-xscripts/flxextract11
-rwxr-xr-xscripts/flxfix84
-rwxr-xr-xscripts/pkg1010
-rwxr-xr-xscripts/pkg-0.5.31994
-rwxr-xr-xscripts/pkg-0.5.42035
-rwxr-xr-xscripts/pkg-0.5.52135
-rwxr-xr-xscripts/pkg-0.5.62183
-rwxr-xr-xscripts/pkg-0.5.72193
-rwxr-xr-xscripts/pkg-0.5.82195
-rwxr-xr-xscripts/pkg-0.6.02239
-rwxr-xr-xscripts/pkg-0.6.12239
-rwxr-xr-xscripts/pkg-0.7.01928
18 files changed, 21760 insertions, 611 deletions
diff --git a/.flxpkg/ChangeLog b/.flxpkg/ChangeLog
new file mode 100644
index 0000000..eeee872
--- /dev/null
+++ b/.flxpkg/ChangeLog
@@ -0,0 +1,62 @@
+2005/04/10 22:56 willy@pcw
+
+ * released flxutils-0.1.29-flx0.1
+
+2005/04/09 15:06 willy@pcw
+
+ * pkg 0.5.2 fixes a small bug and provides support for RANLIB
+ * finally located the old signfs sources, so the binary could
+ be replaced. Nobody should ever need it anyway, but it's
+ more for cleanness.
+ * flx: added the '--ignore-dir' option to ignore differences
+ in directories dates.
+ * flx: during a check, do not compute the md5 sums if the user
+ asks to ignore it. This makes simple diffs a lot faster.
+ * flx: bumped version to 0.7.1
+
+2005/03/01 00:19 willy@wtap
+
+ * released flxutils-0.1.28-flx0.1
+ * pkg 0.5.0 provides some cross-compilation variables
+ * some makefiles have been modified to support cross-compilation
+
+2004/12/22 12:06 willy@wtap
+
+ * released flxutils-0.1.27-flx0.1
+ * merged benoit's patch to escape unprintable characters in flx.
+ * bumped flx version to 0.7.0
+
+2004/12/14 14:52 willy@wtap
+
+ * released flxutils-0.1.26-flx0.1
+ * fixed a bug in fct1.c where two different but valid links would
+ not be reported as different.
+
+2004/12/07 19:39 willy@wtap
+
+ * released flxutils-0.1.25-flx0.1
+ * removed stupid debugging defines from init which prevented it from
+ working anymore in 0.1.24 !
+
+2004/11/21 14:27 root@pcw
+
+ * released flxutils-0.1.24-flx0.1
+ * added the "wk" command (waitkey) to init
+ * wdd now automatically opens /dev/misc/watchdog as presented by devfs
+ * flx 0.6.8 builds with gcc-3.3
+
+2004/08/06 16:51 willy@wtap
+
+ * released flxutils-0.1.23-flx0.1
+ * brought back lcdwrite and lcdtee sources which were lost
+ * the watchdog daemon (wdd) now has a man page and can check
+ reachability of arbitrary files.
+
+2004/02/24 21:31 willy@wtap
+
+ * released flxutils-0.1.22-flx0.1
+ * several major 'pkg' changes (update to 0.4.3)
+ * changed some makefiles to make use of new GCC options
+ provided by pkg-0.4
+ * included and packaged 'wdd' (the watchdog daemon)
+
diff --git a/.flxpkg/build.cfg b/.flxpkg/build.cfg
new file mode 100644
index 0000000..bba9d5a
--- /dev/null
+++ b/.flxpkg/build.cfg
@@ -0,0 +1,64 @@
+SUBDIRS="findcdrom init mktmp remount uname wd mii ifenslave lcd signfs"
+
+function do_compile {
+ for dir in $SUBDIRS; do
+ $FLXPMAKE -C $dir COPTS="$GCC_ARCH_SMALL $GCC_CPU_SMALL $GCC_OPT_SMALL"
+ done
+ # we still need a *fast* flx
+ $FLXPMAKE -C flx COPTS="$GCC_ARCH_COMMON $GCC_CPU_COMMON $GCC_OPT_FAST"
+}
+
+function do_distclean {
+ for dir in $SUBDIRS; do
+ $FLXPMAKE -C $dir clean
+ $FLXPMAKE -C $dir distclean
+ $FLXPMAKE -C $dir mrproper
+ done
+ $FLXPMAKE -C flx clean
+ ( do_delpack )
+}
+
+function do_clean {
+ for dir in $SUBDIRS; do
+ $FLXPMAKE -C $dir clean
+ done
+
+ $FLXPMAKE -C flx clean
+ #$FLXPMAKE -C ifenslave clean
+ #$FLXPMAKE -C mii clean
+ ( do_delpack )
+}
+
+function do_prepack {
+ #mkdir -p $ROOTDIR/usr/include $ROOTDIR/sbin $ROOTDIR/bin $ROOTDIR/usr/bin $ROOTDIR/usr/man/man8 $ROOTDIR/usr/man/man5 $ROOTDIR/usr/man/man1
+ mkdir -p $ROOTDIR/sbin $ROOTDIR/bin $ROOTDIR/usr/bin $ROOTDIR/usr/share/examples/flxutils/init $ROOTDIR/usr/sbin $ROOTDIR/usr/man/man8
+ cp findcdrom/findcdrom $ROOTDIR/sbin/
+ cp flx/flx signfs/signfs mktmp/mktmp remount/remountr lcd/lcd{tee,write} $ROOTDIR/bin/
+ ln -s flx $ROOTDIR/bin/flxcheck
+ ln -s flx $ROOTDIR/bin/flxsign
+ ln -s remountr $ROOTDIR/bin/remountw
+ cp -R ifenslave/ifenslave ifenslave/ifenslave-1.0.1[12] init/init init/mkdev wd/wdd mii/mii-diag scripts/{pci-listall,pcidev,noctrlaltdel,mkinstall.old,mkinstall} $ROOTDIR/sbin/
+ cp scripts/{pkg,reset,flxsearch,flxextract,flxrescan} $ROOTDIR/usr/bin/
+ cp wd/wdd.8 $ROOTDIR/usr/man/man8/
+ cp scripts/{flxadd,flxfix} $ROOTDIR/usr/sbin
+ cp init/examples/* $ROOTDIR/usr/share/examples/flxutils/init/
+
+ #chown -R root:root $ROOTDIR
+ #chmod -R og-w $ROOTDIR
+ #chown root:adm $ROOTDIR/bin/* $ROOTDIR/sbin/* $ROOTDIR/usr/sbin/* $ROOTDIR/usr/bin/*
+ #chmod 740 $ROOTDIR/sbin/* $ROOTDIR/usr/sbin/*
+ #chmod 755 $ROOTDIR/usr/bin/*
+ #chmod 751 $ROOTDIR/bin/*
+ set_default_perm $ROOTDIR
+ chmod 640 $ROOTDIR/usr/share/examples/flxutils/init/*
+ # flxfix is useful for normal users too.
+ chmod 755 $ROOTDIR/usr/sbin/flxfix
+}
+
+function do_strip {
+ # avoids a double strip on flx, which destroys it after sstrip
+ if ! objdump -h $ROOTDIR/bin/flx | grep -q '\.text'; then return; fi
+ strip --strip-unneeded -x -R .comment -R .note $ROOTDIR/bin/flx $ROOTDIR/bin/signfs $ROOTDIR/sbin/ifenslave
+ sstrip $ROOTDIR/bin/flx $ROOTDIR/bin/signfs #$ROOTDIR/sbin/ifenslave || :
+}
+
diff --git a/ChangeLog b/ChangeLog
index a45a808..2cdcea5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -103,3 +103,57 @@
- flx: during a check, do not compute the md5 sums if the user asks to
ignore it. This makes simple diffs a lot faster.
- flx: bumped version to 0.7.1
+
+2005/04/17
+ - flxfix: now also supports signature files in input ; added options to not
+ update timestamps or uid.
+
+2005/05/21
+ - pkg 0.5.3: added the NM variable, and changed options for OPT_SMALL
+
+2005/08/12
+ - pkg 0.5.4 : objdump is used to find lib dependencies instead of ldd, because
+ this last one is not cross-platform compatible, and abusively recurses
+ through the dependency tree instead of staying at the first level.
+ - pkg 0.5.4 : added some FLX* variables (notably FLXHOST* and FLXTARG*), and
+ the '--env' option to make pkg print the useful environment variables
+
+2005/08/13
+ - pkg 0.5.5 : executable dependencies are computed precisely with information
+ about every version needed for each library
+
+2005/08/17
+ - pkg 0.5.6 : reorganized the architecture detection a bit
+
+2005/08/21
+ - pkg 0.5.7 : added support for CXX and HOSTCXX variables
+ - pkg 0.5.8 : fixed .flxpkg symlink resolution ; tar now uses numeric owner
+
+2005/08/27
+ - pkg 0.6.0 : now supports local package repositories under .flxpkg as a
+ directory, and can ignore the local directory name if .flxpkg/Version
+ exists.
+
+2005/09/17
+ - pkg 0.6.1 : use --one-file-system instead of -l for tar (removes a warning)
+
+2005/10/04
+ - pkg 0.7.0 : * provide install-{ln,file,dir,dirs} so that build scripts can
+ work at the file level
+ * added a PKG_VERSION variable and a check_pkg_version function
+ * fixed a few package naming bugs which showed up when packaged
+ referenced absolute paths
+ * make sure that we chown root:root $ROOTDIR in prepack.
+
+2005/10/16
+ - findcdrom : * fixed parsing of /proc/sys/dev/cdrom/info
+ * code cleanup
+ - include/rules.make : add some configuration parameters
+
+2005/12/17
+ - pkg-0.7.1 : * newpkg: don't look for newname in .. anymore, and select only
+ the packages containing a build.cfg
+ * newpkg: do not propose a list of multiple identical new names
+ * release: also identify non-shell text scripts.
+ * release: put only package's basename in changelogs.
+
diff --git a/findcdrom/findcdrom.c b/findcdrom/findcdrom.c
index 3c99b34..d0c985e 100644
--- a/findcdrom/findcdrom.c
+++ b/findcdrom/findcdrom.c
@@ -13,61 +13,86 @@
// 3 : cdrom found but cannot creat /dev/cdrom
// 4 : no cdrom data found
+#define BUFF_SIZE 4096
+#define TMP_SIZE 4096
+
+#define STR_SECT ".rodata"
+#define STRING static const char __attribute__ ((__section__(STR_SECT),__aligned__(1)))
+
+STRING dev_str[] = "/dev";
+STRING cdrom_str[] = "cdrom";
+STRING info_str[] = "/proc/sys/dev/cdrom/info";
+STRING driver_name[] = "\ndrive name:";
+STRING found_str[] = "Found CDROM: ";
+STRING nocdrom_str[] = "No CDROM found\n";
+STRING eol_str[] = "\n";
int main() {
- int fd,fd2,s,t=0;
- char tmp[4096],buff[4096],*p,*f;
- static const char nocdrom[]="No CDROM found\n";
+ int fd, fd2, s, t=0;
+ char *p, *f;
+ char tmp[TMP_SIZE], buff[BUFF_SIZE];
+
+ // find CDROM detection in /proc/sys/dev/cdrom/info
+ if ((fd = open(info_str, O_RDONLY)) < 0) {
+ write(2, nocdrom_str, sizeof(nocdrom_str) - 1);
+ exit(1);
+ }
+ if (chdir(dev_str)) {
+ PRINTF("Cannot chdir to /dev\n");
+ exit(2);
+ }
+ // looking for "driver name:"
+ while ((s = read(fd, tmp + t, TMP_SIZE - t)) > 0) {
+ t += s;
+ if (t < TMP_SIZE)
+ tmp[t] = 0;
+ else
+ tmp[TMP_SIZE] = 0;
- // find CDROM detection in /proc/sys/dev/cdrom/info
- if ((fd=open("/proc/sys/dev/cdrom/info",O_RDONLY)) < 0) {
- write(2,nocdrom,sizeof(nocdrom));
- exit(1);
- }
- if (chdir("/dev")) {
- PRINTF("Cannot chdir to /dev\n");
- exit(2);
- }
- // looking for "driver name:"
- while ((s=read(fd,tmp+t,4096-t)) > 0) {
- t+=s;
- if ((p=(char*)strstr(tmp,"\ndrive name:")) && strchr(p+=13,'\n')) {
- // have found it, looking for drive name(s)
- while (*p != '\n') {
- while (*p == ' ' || *p == '\t') p++;
- for (f=p;*f > ' ' ; f++) ;
- if (*f == '\n') *f=0; else *f++=0;
- // found and now try
- PRINTF("Trying [%s]\n",p);
- if ((fd2=open(p,O_RDONLY)) >= 0) {
- // read a small packet to detect valid iso9660
- if (read(fd2,buff,4096) > 0) {
- close(fd2);
- close(fd);
- // creat the symbolic link to /dev/cdrom
- if (symlink(p,"cdrom") == 0) {
+ if ((p = (char*)strstr(tmp, driver_name)) && strchr(p += 13, '\n')) {
+ // have found it, looking for drive name(s)
+ while (*p && *p != '\n') {
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ for (f = p; *f > ' ' ; f++);
+
+ if (*f == '\n')
+ *f = 0;
+ else
+ *f++ = 0;
+
+ // found and now try
+ PRINTF("Trying [%s]\n", p);
+ if ((fd2 = open(p, O_RDONLY)) >= 0) {
+ // read a small packet to detect valid iso9660
+ if (read(fd2, buff, BUFF_SIZE) > 0) {
+ close(fd2);
+ close(fd);
+ // creat the symbolic link to /dev/cdrom
+ if (symlink(p, cdrom_str) == 0) {
#ifdef DEBUG
- write(2," ",2);
+ write(2, " ", 2);
#endif
- write(2,"Found CDROM: ",13);
- write(2,p,strlen(p));
- write(2,"\n",1);
- exit(0);
- }
- exit(3);
- }
- PRINTF(" read failed\n");
- close(fd2);
- } else {
- PRINTF(" open failed\n");
- }
- p=f;
- }
- break;
+ write(2, found_str, sizeof(found_str) - 1);
+ write(2, p, strlen(p));
+ write(2, eol_str, 1);
+ exit(0);
+ }
+ exit(3);
+ }
+ PRINTF(" read failed\n");
+ close(fd2);
+ } else {
+ PRINTF(" open failed\n");
+ }
+ p = f;
+ }
+ break;
+ }
}
- }
- if (s >= 0) close(fd);
- write(2,nocdrom,sizeof(nocdrom));
- return (4);
+ if (s >= 0)
+ close(fd);
+ write(2, nocdrom_str, sizeof(nocdrom_str) - 1);
+ return (4);
}
-
diff --git a/include/rules.make b/include/rules.make
index b1b5f17..8e4c36d 100644
--- a/include/rules.make
+++ b/include/rules.make
@@ -1,5 +1,11 @@
+CC ?= gcc
+STRIP ?= strip
+OBJDUMP ?= objdump
+SSTRIP ?= sstrip
+DIET ?= diet
+
CC_ORIG := $(CC)
-CC := diet $(CC)
+override CC := $(DIET) -Os $(CC)
CFLAGS=$(GCC_ARCH_SMALL) $(GCC_CPU_SMALL) $(GCC_OPT_SMALL)
#-mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0 -Os -march=i386 -mcpu=i386
@@ -12,7 +18,7 @@ all: $(OBJS)
$(STRIP) -x --strip-unneeded -R .comment -R .note $@
$(OBJDUMP) -h $@ | grep -q '\.data[ ]*00000000' && $(STRIP) -R .data $@ || true
$(OBJDUMP) -h $@ | grep -q '\.sbss[ ]*00000000' && $(STRIP) -R .sbss $@ || true
- -sstrip $@
+ -if [ -n "$(SSTRIP)" ]; then $(SSTRIP) $@ ; fi
%-debug: %.c
$(CC) $(LDFLAGS) $(CFLAGS) -DDEBUG -o $@ $<
diff --git a/init/init-cleanup.c b/init/init-cleanup.c
new file mode 100644
index 0000000..5cb6400
--- /dev/null
+++ b/init/init-cleanup.c
@@ -0,0 +1,1808 @@
+/*
+ WARNING ! THIS CODE IS OPTIMIZED FOR SIZE WITH COMPILED-IN ARGUMENTS. IT IS
+ SUBJECT TO BUFFER OVERFLOWS SO DON'T USE IT WITH RUNTIME ARGUMENTS !!!
+*/
+
+/* TODO :
+ - make the config buffer bigger
+ - a few security checks (buffer overflows...)
+ - cleanup the code a bit
+*/
+
+/*
+ preinit - new try on 2002/04/20 - Willy Tarreau <willy AT meta-x.org>
+
+ usage : /sbin/preinit [ \< config_file ] [ { init args | "rebuild" } ]
+
+ Note : the "\< config_file" is to be used within configuration files :
+ #!/sbin/preinit <
+ ....
+ Thus, when you pass "init=/.preinit", the kernel executes :
+ /sbin/preinit < /.preinit
+
+ The '<' character has been chosen for its rareness.
+
+ the "rebuild" argument make the tool only rebuild a complete /dev
+ tree from the informations contained in the .preinit file, and then
+ exit. It does this even if the pid is not 1, but doesn't execute nor
+ mount anything. Only mkdir, links, blocks, chars and fifo devices are
+ created. Very useful before a lilo :
+
+ # chroot /mnt/disk /.preinit rebuild
+ # lilo -r /mnt/disk
+ # umount /mnt/disk/dev
+
+ If /dev/console is found under /dev, it will not be rebuilt.
+
+ **** needs to rework the doc a bit since it's not up-to-date. ****
+
+ This code tries to build a few filesystem squeleton so that init has enough
+ to work correctly :
+ - mount -t proc /proc /proc
+ - mount -t tmpfs /dev /dev
+ - get information from a file : /.preinit which describes what to mount,
+ what ramdisks, links and dirs to make :
+
+ln L source dest
+ make a symlink from <source> to <dest>
+md D path [ mode ]
+ create a directory named <path> with the mode <mode>. If mode is left
+ undefined, 0755 is assumed.
+mt M blkdev[(major:minor)] path fstype [ { ro | rw } [ flags ] ]
+ if <major:minor> is specified, create a block device <blkdev>
+ with <major> and <minor> and mode 0600.
+ mount <blkdev> under <path> with type <fstype>, read-only, except if
+ rw is specified, and args <flags>.
+in I path
+ set the next init program to <path>
+ex E cmd [ args ]*
+ execute <cmd> with args <args> and wait for its completion.
+rx R dir cmd [ args ]*
+ chroot to <dir>, execute <cmd> with args <args> and wait for its completion.
+bl B mode uid gid major minor naming_rule
+ create a set of block devices
+ch C mode uid gid major minor naming_rule
+ create a set of char devices
+fi F mode uid gid name
+ create a fifo
+ma U mode
+ change umask
+pr P <new_root> <put_old_relative>
+ pivot root : old root is displaced into new_root/put_old_relative, and
+ new_root is displaced under /.
+mv K <old_dir> <new_dir>
+ keep directory <old_dir> after a pivot, then unmount it from old_dir.
+ usefull for /dev, /proc, /var ...
+um O <old_dir>
+ umount <old_dir> after a pivot for example.
+lo l </dev/loopX> <file>
+ losetup /dev/loopX file.
+ # anything
+ comment.
+
+ The devices naming rules consist in strings mixed with numbering rules delimited with
+ brackets. Each numbering rule has 4 comma-separated fields :
+ - type of this string portion : 'c' for a single char, 'i' for an int, 'I' for an int
+ for which 0 is not printed, 'h' for an hex digit
+ - the range :
+ - chars: any concatenation of character ranges separated with a dash '-': 'a-fk-npq'
+ - ints : either an int or a range composed of 2 ints separated with a dash : '1-16'
+ - hex : same as int, but with hex digits (case insensitive)
+ - the scale : how much to add to the minor device for each step in the range.
+
+ The commands may be prefixed with a '|' or '&', in which case, they will be
+ executed only if the previous command failed (|) or succeeded (&).
+
+ Example :
+ ln hda3 /dev/disk => symlinks /dev/disk to hda3
+ md /var/tmp 1777 => creates a directory /var/tmp with mode 1777
+ mt /dev/hda1 /boot ext2 => attempts to mount /dev/hda1 read-only under /boot.
+ |mt /dev/hda1(3:1) /boot ext2 => only if the previous command failed, creates /dev/hda1 with major 3, minor 1 and mounts it under /boot
+ in /sbin/init-std => the following init will be this /sbin/init-std (31 chars max)
+ ex /sbin/initramdisk /dev/ram6 1200 => executes /sbin/initramdisk with these args and waits for its completion
+ bl 0600 0 0 3 1 hd[c,ab,64][i,1-16,1] => makes all hdaX and hdbX with X ranging from 1 to 16
+ ch 0600 0 5 2 0 pty[c,p-za-f,16][h,0-f,1] => makes all 256 pty*
+ #comment => ignore this line
+
+ For executable reduction reasons, the .preinit file is limited to 4 kB.
+
+ The choice of the init program is quite complex, because we want to avoid
+ stupid loops and buggy behaviours while conservating quite a parametrable
+ init. Basically, we'll use environment variables that we will destroy once
+ read, to avoid getting them again if we loop on ourselves (imagine an
+ 'exec /sbin/init" from a shell cmd line, which will blindly re-exec a shell).
+ So there are two distinct cases (init and linuxrc) :
+
+ 1) linuxrc
+ We want to be able to either return or transfer execution to the real init.
+
+ - if we find "init2=xxxx" in the env, we memorize it and move it away from the env.
+ - if "in xxxx" has been specified on a keyboard input from an "rd"
+ statement, we unconditionnaly do an execve("xxx", "xxx", ##no args##, ##envp##).
+ - if the env contained "init2=xxxx", we do an execve("xxxx", "xxxx", ##no args##, ##envp##).
+ we don't pass the args because it is a rescue init, such as a shell, and
+ we don't want it to fail on "bash: auto: command not found" or similar.
+ - if the conf contained "in xxxx", we do an execve("xxxx", "xxxx", argv[], ##envp##)
+ because we want it to know about the original args. Eg: init=/linuxrc single
+ - if the conf didn't contain "in xxxx", we unmount all what we can and
+ return. The kernel will be able to switch over to the next init stage.
+
+ 2) init, or anything else (telinit, ...)
+ We want to transfer execution to the real init.
+
+ - if we find "INIT=xxxx" in the env, we memorize it and move it away from the env.
+ - if "in xxxx" has been specified on a keyboard input from an "rd"
+ statement, we unconditionnaly do an execve("xxx", "xxx", ##no args##, ##envp##).
+ - if the env contained "INIT=xxxx", we do an execve("xxxx", "xxxx", ##no args##, ##envp##).
+ we don't pass the args because it is a rescue init, such as a shell, and
+ we don't want it to fail on "bash: auto: command not found" or similar.
+ - if the conf contained "in xxxx", we do an execve("xxxx", "xxxx", argv[], ##envp##)
+ because we want it to know about the original args. Eg: init=/.preinit single
+ - if the conf didn't contain "in xxxx", we transfer execution to "/sbin/init-sysv".
+
+ Note: basically, each time an environment variable is read, it must be killed afterwards.
+ Eg: init2=, INIT=, ...
+
+
+ The root directory should contain the following dirs :
+ - /var (directory) -> can be a ramfs or a real dir on another device
+ - /var/tmp (directory) -> idem
+ - /tmp (directory) -> idem
+ - /etc (directory or symlink) -> several possibilities :
+ - directory on the root fs (preferably)
+ - directory on another fs
+ - ramfs (or ramdisk) and directory extracted from other source
+ - symlink to /boot/etc (in this case, /boot/etc must be a populated directory)
+ /etc will already have several symlinks
+
+ /boot (mandatory directory) contains the following :
+ - [kernel version] (directory) with vmlinuz, System.map, config and
+ the tree behind /lib/modules/[version]
+ - current (symlink to kernel version)
+ - vmlinuz (symlink to current/vmlinuz)
+ - System.map (symlink to current/System.map)
+ - config (symlink to current/config)
+ - eventually initrd (symlink to current/initrd)
+ - modules.dep (symlink to current/modules.dep)
+ - modules.pcimap (symlink to current/modules.pcimap)
+
+ /boot *may* contain the following :
+ - etc (populated directory)
+ - bootfstab (if /etc and /boot/etc empty or non-existant)
+
+ This helps in making /lib/modules : it will simply be a symlink to
+ /boot/current which will contain all modules.
+
+
+wrong for now:
+ /tmp will always be linked to fs/var/tmp.
+ /var will always be linked to fs/var.
+ /fs must contain a description file for it (what to mount where, what to
+ initialize) so that init has a working filesystem hierarchy and fstab works.
+ /fs should be FAT-compatible, at least for its root structure.
+*/
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/mount.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <linux/loop.h>
+
+#ifndef MNT_DETACH
+#define MNT_DETACH 2
+#endif
+
+#ifndef MS_MOVE
+#define MS_MOVE 8192
+#endif
+
+#define STR_SECT ".rodata"
+
+#ifdef DEBUG
+static void print(char *c) {
+ char *p = c;
+ while (*p)
+ p++;
+ write(0, c, p-c);
+}
+#else
+#define print(a,...) do{}while(0)
+#endif
+
+//#define ATOL(x) atol(x)
+#define ATOL(x) my_atoul(x)
+
+typedef unsigned char uchar;
+
+
+/* This ordering is awful but it's the most efficient regarding space wasted in
+ * long strings alignment with gcc-2.95.3 (gcc 3.2.3 doesn't try to align long
+ * strings).
+ */
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) msg_ent_console[] = "Entering command line mode : enter one command per line, end with '.'\n";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) root_dir[] = "/";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) cur_dir[] = ".";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) dev_name[] = "/dev";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) var_dir[] = "/var";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) cfg_fname[] = "/.preinit"; /* configuration file */
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) msg_err_console[] = "Command ignored, input alread bound to console !\n";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) dev_console[] = "dev/console";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) str_rebuild[] = "rebuild";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) var_tmp[] = "/var/tmp";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) var_run[] = "/var/run";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) proc_self_fd[] = "/proc/self/fd";
+//static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) proc_cmdline[] = "/proc/cmdline";
+//static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) sbin_init[] = "sbin/init";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) sbin_init_sysv[] = "sbin/init-sysv";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) cfg_linuxrc[] = "/.linuxrc";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) dev_options[] = "size=0,nr_inodes=4096,mode=755";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) str__linuxrc[] = "/linuxrc";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) proc_dir[] = "/proc";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) tmpfs_fs[] = "tmpfs";
+static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) dev_root[] = "dev/root";
+
+
+#define tmp_name (var_tmp + 4) // static const char tmp_name[] = "/tmp";
+#define proc_fs (proc_dir+1) // static const char proc_fs[] = "proc";
+#define fd_dir (proc_self_fd + 11) // static const char fd_dir[] = "fd";
+#define str_linuxrc (str__linuxrc+1) // "linuxrc"
+
+
+#define CONST_STR(x) ({ static const char __attribute__ ((__section__(STR_SECT),__aligned__(1))) ___str___[]=x; (char *)___str___; })
+
+/* used by naming rules */
+#define MAX_FIELDS 8
+#define MAX_DEVNAME_LEN 64
+#define MAX_CFG_SIZE 16384
+#define MAX_CFG_ARGS 64
+//#define MAX_CMDLINE_LEN 512
+#define MAX_BRACE_LEVEL 10
+
+struct dev_varstr {
+ char type;
+ union {
+ struct {
+ char *set;
+ char *ptr;
+ char value; /* value to be printed */
+ uchar index; /* index in the set */
+ } chr;
+ struct {
+ uchar low;
+ uchar high;
+ uchar value;
+ } num;
+ } u;
+ uchar scale;
+};
+
+enum {
+ TOK_LN = 0, /* ln : make a symlink */
+ TOK_MD, /* md : mkdir */
+ TOK_MT, /* mt : mount */
+ TOK_RE, /* re : remount */
+ TOK_IN, /* in : set init program */
+ TOK_EX, /* ex : execute */
+ TOK_RX, /* rx : execute under chroot */
+ TOK_BL, /* bl : make block devices */
+ TOK_CH, /* ch : make char devices */
+ TOK_FI, /* fi : make a fifo */
+ TOK_MA, /* ma : set umask */
+ TOK_PR, /* pr : pivot root */
+ TOK_MV, /* mv : move a filesystem */
+ TOK_BI, /* bi : bind a directory */
+ TOK_UM, /* um : umount a filesystem */
+ TOK_LO, /* lo : losetup */
+ TOK_EC, /* ec : echo */
+ TOK_TE, /* te : test an environment variable */
+ TOK_RD, /* rd : read a command from the console */
+ TOK_RM, /* rm : remove files */
+ TOK_ST, /* st : stat file existence */
+ TOK_WK, /* wk : wait key */
+ TOK_OB, /* { : begin a command block */
+ TOK_CB, /* } : end a command block */
+ TOK_DOT, /* . : end of config */
+ TOK_UNK, /* unknown command */
+ TOK_EOF, /* end of file */
+ TOK_COND_NEG = 0x20, /* negate the result before evaluation */
+ TOK_COND_OR = 0x40, /* conditionnal OR */
+ TOK_COND_AND = 0x80, /* conditionnal AND */
+ TOK_COND = 0xE0, /* any condition */
+};
+
+/* counts from TOK_LN to TOK_DOT */
+#define NB_TOKENS 25
+
+/* this contains all two-chars command, 1-char commands, followed by a token
+ * number.
+ */
+static const __attribute__ ((__section__(STR_SECT),__aligned__(1))) struct {
+ char lcmd[2]; /* long form */
+ char scmd; /* short form */
+ char minargs; /* min #args */
+} tokens[NB_TOKENS] = {
+ "ln", 'L', 2, /* TOK_LN */
+ "md", 'D', 1, /* TOK_MD */
+ "mt", 'M', 3, /* TOK_MT */
+ "re", 0, 3, /* TOK_RE */
+ "in", 'I', 1, /* TOK_IN */
+ "ex", 'E', 1, /* TOK_EX */
+ "rx", 'R', 2, /* TOK_RX */
+ "bl", 'B', 6, /* TOK_BL */
+ "ch", 'C', 6, /* TOK_CH */
+ "fi", 'F', 4, /* TOK_FI */
+ "ma", 'U', 1, /* TOK_MA */
+ "pr", 'P', 2, /* TOK_PR */
+ "mv", 'K', 2, /* TOK_MV */
+ "bi", 'K', 2, /* TOK_BI */
+ "um", 'O', 1, /* TOK_UM */
+ "lo", 'l', 2, /* TOK_LO */
+ "ec", 0, 0, /* TOK_EC */
+ "te", 0, 1, /* TOK_TE */
+ "rd", 0, 0, /* TOK_RD */
+ "rm", 0, 1, /* TOK_RM */
+ "st", 0, 1, /* TOK_ST */
+ "wk", 0, 2, /* TOK_WK */
+ "{", '{', 0, /* TOK_OB */
+ "}", '}', 0, /* TOK_CB */
+ ".", '.', 0, /* TOK_DOT : put every command before this one */
+};
+
+#define UID_ROOT 0
+#define GID_ROOT 0
+#define GID_TTY 5
+#define GID_KMEM 9
+
+static const __attribute__ ((__section__(STR_SECT),__aligned__(1))) struct {
+ char name[8];
+ short gid;
+ char major, minor;
+ mode_t mode; /* mode + S_IFCHR, S_IFBLK, S_IFIFO */
+} dev_nodes[] = {
+ /* console must always be at the first location */
+ { "console", GID_TTY, 5, 1, 0600 | S_IFCHR },
+ { "mem", GID_KMEM, 1, 1, 0640 | S_IFCHR },
+ { "kmem", GID_KMEM, 1, 2, 0640 | S_IFCHR },
+ { "null", GID_ROOT, 1, 3, 0666 | S_IFCHR },
+ { "port", GID_KMEM, 1, 4, 0640 | S_IFCHR },
+ { "zero", GID_ROOT, 1, 5, 0666 | S_IFCHR },
+ { "full", GID_ROOT, 1, 7, 0666 | S_IFCHR },
+ { "random", GID_ROOT, 1, 8, 0644 | S_IFCHR },
+ { "urandom", GID_ROOT, 1, 9, 0644 | S_IFCHR },
+ { "tty0", GID_TTY, 4, 0, 0600 | S_IFCHR },
+ { "tty", GID_TTY, 5, 0, 0666 | S_IFCHR },
+ { "ptmx", GID_TTY, 5, 2, 0666 | S_IFCHR },
+ { "initctl", GID_ROOT, 0, 0, 0600 | S_IFIFO },
+} ;
+
+static char cfg_data[MAX_CFG_SIZE];
+static char *cfg_args[MAX_CFG_ARGS];
+static char *cfg_line;
+//static char cmdline[MAX_CMDLINE_LEN];
+static char *cst_str[MAX_FIELDS];
+static char *var_str[MAX_FIELDS];
+static struct dev_varstr var[MAX_FIELDS];
+static int error; /* an error has emerged from last operation */
+static int linuxrc; /* non-zero if we were called as 'linuxrc' */
+
+/* the two input modes */
+#define INPUT_FILE 0
+#define INPUT_KBD 1
+
+static unsigned long my_atoul(const char *s) {
+ unsigned long res = 0;
+ unsigned long digit;
+
+ while (*s) {
+ digit = *s - '0';
+ if (digit > 9)
+ return 0;
+ res = res * 10 + digit;
+ s++;
+ }
+ return res;
+}
+
+static int streq(const char *str1, const char *str2) {
+ char c1;
+ while ((c1 = *str1) && c1 == *str2) { /* the second test ensures that *str2 != 0 */
+ str1++;
+ str2++;
+ }
+ return ((c1 | *str2) == 0);
+}
+
+/*
+ * copies at most <size-1> chars from <src> to <dst>. Last char is always
+ * set to 0, unless <size> is 0. The number of chars copied is returned
+ * (excluding the terminating zero).
+ * This code has been optimized for size and speed : on x86, it's 45 bytes
+ * long, uses only registers, and consumes only 4 cycles per char.
+ */
+static inline int my_strlcpy(char *dst, const char *src, int size) {
+ char *orig = dst;
+ if (size) {
+ while (--size && (*dst = *src)) {
+ src++; dst++;
+ }
+ *dst = 0;
+ }
+ return dst - orig;
+}
+
+static void reopen_console() {
+ int i, fd, oldfd;
+
+ oldfd = dup2(0, 3); // keep a valid console on fd 3
+
+ for (i = 0; i < 3; i++)
+ close(i);
+
+ fd = open(dev_console, O_RDWR); // fd = 0 (stdin) or -1 (error)
+ if (fd < 0)
+ dup(oldfd); // restore 0 from old console
+
+ close(oldfd);
+ dup(0); // stdout
+ dup(0); // stderr
+
+ print("init/info : reopened /dev/console\n");
+}
+
+#if 0
+/* reads the kernel command line </proc/cmdline> into memory and searches
+ * for the first assignment of the required variable. Return its value
+ * (which may be empty) or NULL if not found.
+ */
+char *find_arg(char *arg) {
+ char *a, *c;
+
+ /* read cmdline the first time */
+ if (!*cmdline) {
+ int fd, len;
+
+ if ((fd = open(proc_cmdline, O_RDONLY)) == -1)
+ return NULL;
+ if ((len = read(fd, cmdline, sizeof(cmdline)-1)) == -1) {
+ close(fd);
+ return NULL;
+ }
+ cmdline[len] = 0;
+ close(fd);
+ }
+
+ /* search for the required arg in cmdline */
+ c = cmdline;
+ a = arg;
+
+ while (*c) {
+ if (*a == 0) {
+ /* complete match. is it a full word ? */
+ if (*c == '=') {
+ a = ++c;
+ while ((*a != ' ') && (*a != '\0') && (*a != '\n'))
+ a++;
+ *a = 0;
+ return c; /* return value */
+ }
+ else if (*c == ' ' || *c == '\n' || *c == '\0') {
+ *c = 0;
+ return c; /* return pointer to empty string */
+ }
+ else { /* not full word. bad match. */
+ c -= (a - arg) - 1;
+ a = arg;
+ }
+ }
+ if (*c == *a) {
+ a++;
+ c++;
+ }
+ else {
+ c -= (a - arg) - 1;
+ a = arg;
+ }
+ }
+ if (*a == 0) /* complete match at end of string */
+ return c; /* pointer to empty string */
+ else
+ return NULL; /* not found */
+}
+#endif
+
+/*
+ * looks for the last assignment of variable 'var=' in 'envp'.
+ * the value found is returned (or NULL if not found).
+ * if 'remove' is not zero, the assignment is removed afterwards.
+ * eg: init=my_getenv(envp, "init=", 1);
+ */
+char *my_getenv(char **envp, char *var, const int remove) {
+ int namelen;
+ char **last;
+
+ last = NULL;
+ namelen = strlen(var);
+ while (*envp != NULL) {
+ if (!strncmp(*envp, var, namelen))
+ last = envp;
+ envp++;
+ }
+
+ if (last == NULL) {
+ return NULL;
+ } else {
+ char *ret = (*last) + namelen;
+ if (remove)
+ while (*last != NULL) {
+ *last = *(last+1);
+ last++;
+ }
+ return ret;
+ }
+}
+
+/* reads the configuration file <cfg_file> into memory.
+ * returns 0 if OK, -1 if error.
+ */
+static inline int read_cfg(char *cfg_file) {
+ int cfg_fd;
+ int cfg_size;
+
+ if (cfg_line == NULL) {
+ if (((cfg_fd = open(cfg_file, O_RDONLY)) == -1) ||
+ ((cfg_size = read(cfg_fd, cfg_data, sizeof(cfg_data) - 1)) == -1)) {
+ return -1;
+ }
+ close(cfg_fd);
+ cfg_line = cfg_data;
+ cfg_data[cfg_size] = 0;
+ }
+ return 0;
+}
+
+/* reads one line from <cfg_data>. comments are ignored. The command token is
+ * returned as the result of this function, or TOK_UNK if none matches, or
+ * TOK_EOF if nothing left. All args are copied into <cfg_args> as an array
+ * of pointers. Maximum line length is 256 chars and maximum args number is 15.
+ */
+static int parse_cfg(char **cfg_data) {
+ int nbargs;
+ int token;
+ int cond;
+ char *cfg_line = *cfg_data;
+
+ memset(cfg_args, 0, sizeof(cfg_args));
+ while (*cfg_line) {
+ char c, *p = cfg_line;
+
+ cond = 0;
+ /* search beginning of line */
+ do {
+ if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\r') {
+ if (*p == '|') {
+ cond |= TOK_COND_OR;
+ } else if (*p == '&') {
+ cond |= TOK_COND_AND;
+ } else if (*p == '!') {
+ cond ^= TOK_COND_NEG;
+ } else {
+ /* catches any printable char and the final zero */
+ break;
+ }
+ }
+ p++;
+ } while (1);
+
+ /* now search end of line */
+ cfg_line = p;
+ while (*cfg_line && *cfg_line != '#' && *cfg_line != '\n' && *cfg_line != '\r') {
+ cfg_line++;
+ }
+
+ /* terminate the line cleanly to avoid further tests */
+ while (c = *cfg_line) {
+ *cfg_line++ = '\0';
+ if (c == '\n')
+ break;
+ }
+
+ /* update the caller's pointer once for all. */
+ *cfg_data = cfg_line;
+
+ /* skip empty lines */
+ if (!*p)
+ continue;
+
+ /* fills the cfg_args[] array with the command itself, followed by all
+ * args. cfg_args[last+1]=NULL.
+ *
+ * We have a particular case here :
+ * if the line begins with '/', then we return TOK_EX so that it executes
+ * the command just as it would have done with 'ex' prefixed to the line.
+ * For this, we insert a fake cfg_args[0], also pointing to the '/', which
+ * will be matched later.
+ */
+ nbargs = 0;
+ if (*p == '/')
+ cfg_args[nbargs++] = p;
+
+ for (; *p && (nbargs < MAX_CFG_ARGS - 1); nbargs++) {
+ int backslash = 0, quote = 0;
+
+ cfg_args[nbargs] = p;
+
+ do {
+ if (backslash) {
+ backslash = 0;
+ if (*p == 'n')
+ *p = '\n';
+ else if (*p == 'r')
+ *p = '\r';
+ else if (*p == 't')
+ *p = '\t';
+ memmove(p - 1, p, cfg_line - p);
+ } else {
+ backslash = (*p == '\\');
+ if (*p == '"') {
+ memmove(p, p + 1, cfg_line - p - 1);
+ quote = !quote;
+ }
+ else
+ p++;
+ }
+ } while (*p && (backslash || quote || (*p != ' ' && *p != '\t')));
+ if (*p) {
+ *p = 0;
+ do p++; while (*p == ' ' || *p == '\t');
+ }
+ }
+
+ /* search a matching token for the command : it can either be a single
+ * char (old language) or a double char (new language).
+ *
+ * We have a particular case :
+ * if the line begins with '/', then we return TOK_EX so that it executes
+ * the command just as it would have done with 'ex' prefixed to the line.
+ */
+ if (**cfg_args == '/')
+ return TOK_EX | cond;
+
+ for (token = 0; token < NB_TOKENS; token++)
+ if ((!cfg_args[0][1] && tokens[token].scmd == cfg_args[0][0]) ||
+ (cfg_args[0][1] &&
+ (tokens[token].lcmd[1] == cfg_args[0][1]) &&
+ (tokens[token].lcmd[0] == cfg_args[0][0])))
+ return token | cond;
+
+ return TOK_UNK;
+ }
+ return TOK_EOF;
+}
+
+/* makes a dev entry. continues on error, but reports them. */
+static inline int mknod_chown(mode_t mode, uid_t uid, gid_t gid, uchar major, uchar minor, char *name) {
+ int error;
+
+ if (mknod(name, mode, makedev(major, minor)) == -1) {
+ error = 1;
+ print("init/error : mknod("); print(name); print(") failed\n");
+ }
+
+ if (chown(name, uid, gid) == -1) {
+ error = 1;
+ print("init/error : chown("); print(name); print(") failed\n");
+ }
+
+ return error;
+}
+
+/* breaks a 3-fields, comma-separated string into 3 fields */
+static inline int varstr_break(char *str, char *type, char **set, uchar *scale) {
+ int state;
+ char *res[3];
+
+ for (state = 0; state < 3; state++) {
+ res[state] = str;
+ while (*str && *str != ',')
+ str++;
+ if (*str)
+ *str++ = 0;
+ else if (state < 2)
+ return 1;
+ }
+
+ *type = *res[0];
+ *set = res[1];
+ *scale = ATOL(res[2]);
+ return 0;
+}
+
+/* reads a range from a string of the form "low-high" or "value".
+ * Returns 0 if OK, or 1 if error.
+ */
+static int int_range(char *from, uchar *low, uchar *high) {
+ char c;
+ *low = 0;
+ while ((c = *from) != '\0') {
+ if (isdigit(c))
+ *low = *low * 10 + c - '0';
+ else if (c == '-') {
+ low = high;
+ *low = 0;
+ }
+ else
+ return 1;
+ from++;
+ }
+ if (low != high) /* high has not been written to */
+ *high = *low;
+
+ return 0;
+}
+
+/* reads a range from a hex string of the form "low-high" or "value".
+ * Returns 0 if OK, or 1 if error.
+ */
+static int hex_range(char *from, uchar *low, uchar *high) {
+ uchar c;
+ *low = 0;
+ while ((c = *from) != '\0') {
+ if (c == '-') {
+ low = high; /* all writes will now be done on <high> */
+ *low = 0;
+ }
+ else {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'a' && c <= 'f')
+ c -= 'a' - 10;
+ else if (c >= 'A' && c <= 'F')
+ c -= 'A' - 10;
+ else
+ return 1;
+
+ *low = (*low << 4) + c;
+ }
+ from++;
+ }
+ if (low != high) /* high has not been written to */
+ *high = *low;
+
+ return 0;
+}
+
+static inline char *addcst(char *dest, char *cst) {
+ while ((*dest++ = *cst++) != '\0');
+ return dest - 1;
+}
+
+static inline char *addchr(char *dest, char chr) {
+ *dest++ = chr;
+ *dest = '\0';
+ return dest;
+}
+
+static char *addint(char *dest, uchar num) {
+ int div;
+ char *out = dest;
+ for (div = (1<<16) + (10<<8) + (100); div > 0;) {
+ int q, r, d;
+ d = (unsigned char)div;
+ q = num / d; r = num % d;
+ div >>= 8;
+ if (!div || (out != dest) || q) {
+ *out++ = q + '0';
+ }
+ num = r;
+ }
+ *out = '\0';
+ return out;
+}
+
+static char *addhex(char *dest, uchar num) {
+ uchar c;
+ if (num > 0x0F) {
+ c = num >> 4;
+ *dest++ = (c > 9) ? (c - 10 + 'a') : (c + '0');
+ }
+ c = num & 0x0F;
+ *dest++ = (c > 9) ? (c - 10 + 'a') : (c + '0');
+ *dest = '\0';
+ return dest;
+}
+
+/* builds a device name from the current <var> and <cst_str> arrays,
+ * and compute the corresponding minor number by adding all the relevant
+ * fields' values
+ */
+static void name_and_minor(char *name, uchar *minor, int fields) {
+ uchar min;
+ int f;
+
+ min = 0;
+ for (f = 0; f < fields; f++) {
+ if (*cst_str[f])
+ name = addcst(name, cst_str[f]);
+ switch (var[f].type) {
+ case 'c' :
+ name = addchr(name, var[f].u.chr.value);
+ min += var[f].u.chr.index * var[f].scale;
+ break;
+ case 'h' :
+ name = addhex(name, var[f].u.num.value);
+ goto recalc_int;
+ case 'i' :
+ name = addint(name, var[f].u.num.value);
+ goto recalc_int;
+ case 'I' :
+ if (var[f].u.num.value)
+ name = addint(name, var[f].u.num.value);
+ recalc_int:
+ min += (var[f].u.num.value - var[f].u.num.low) * var[f].scale;
+ break;
+ case 0 :
+ break;
+ default:
+ print("init/conf : field type must be c, h, i or I\n");
+ }
+ }
+ if (minor)
+ *minor = min;
+}
+
+/* increments the index for variable #f. When it overflows, it goes back to the
+ * beginning and a carry is returned for the next variable to be incremented.
+ * 0 is returned if no carry is returned, otherwise, 1 is returned.
+ */
+static int inc_var_index(int f) {
+ switch (var[f].type) {
+ case 'c' :
+ if ((var[f].u.chr.ptr[1] == '-') && (var[f].u.chr.value < var[f].u.chr.ptr[2])) {
+ var[f].u.chr.value++;
+ var[f].u.chr.index++;
+ return 0;
+ } else { /* we cannot increment within the current range */
+ if (*++var[f].u.chr.ptr == '-') {
+ if (*++var[f].u.chr.ptr)
+ var[f].u.chr.ptr++;
+ }
+ if (!*var[f].u.chr.ptr) { /* no other range found */
+ var[f].u.chr.value = *(var[f].u.chr.ptr = var[f].u.chr.set);
+ var[f].u.chr.index = 0;
+ return 1;
+ }
+ else { /* found a new range */
+ var[f].u.chr.value = *var[f].u.chr.ptr;
+ var[f].u.chr.index++;
+ return 0;
+ }
+ }
+ case 'h':
+ case 'i':
+ case 'I':
+ if (var[f].u.num.value == var[f].u.num.high) {
+ var[f].u.num.value = var[f].u.num.low;
+ return 1;
+ } else {
+ var[f].u.num.value++;
+ return 0;
+ }
+ default:
+ return 1; /* an empty variable propagates carry */
+ }
+}
+
+
+/* makes one or several device inodes depending on the rule <rule> */
+static void multidev(mode_t mode, uid_t uid, gid_t gid, uchar major, uchar minor, char *rule) {
+ char *p1, *p2;
+ int state;
+ int i;
+
+ enum {
+ ST_STRING = 0,
+ ST_CONST
+ };
+
+ int field; /* each field is a couple of a cst string and a var string */
+
+ p1 = p2 = rule;
+ state = ST_STRING;
+ field = 0;
+
+ cst_str[field] = var_str[field] = p2; /* be sure to point to something valid */
+
+ while (*p2) {
+ if (state == ST_STRING) {
+ if (*p2 == '[') {
+ state = ST_CONST;
+ cst_str[field] = p1;
+ *p2++ = 0;
+ p1 = p2;
+ }
+ else
+ p2++;
+ }
+ else if (state == ST_CONST) {
+ if (*p2 == ']') {
+ state = ST_STRING;
+ var_str[field++] = p1;
+ *p2++ = 0;
+ p1 = p2;
+ cst_str[field] = p1;
+ }
+ else
+ p2++;
+ }
+ }
+
+ if (state == ST_STRING) {
+ if (p2 > p1) {
+ state = ST_CONST;
+ cst_str[field] = p1;
+ var_str[field++] = p2;
+ *p2++ = 0;
+ }
+ }
+ else {
+ print("var string incomplete\n");
+ }
+
+ /* now we must "compile" the variable fields */
+ for (i = 0; i < field; i++) {
+ memset(&var[i], 0, sizeof(var[i]));
+ if (varstr_break(var_str[i], &var[i].type, &var[i].u.chr.set, &var[i].scale)) {
+ //print("empty variable field in string <"); print(var_str[i]); print(">\n");
+ continue;
+ }
+
+ switch (var[i].type) {
+ case 'c':
+ var[i].u.chr.value = *(var[i].u.chr.ptr = var[i].u.chr.set);
+ var[i].u.chr.index = 0;
+ break;
+ case 'h':
+ if (hex_range(var[i].u.chr.set, &var[i].u.num.low, &var[i].u.num.high)) {
+ print("init/conf : error in hex range\n");
+ continue;
+ }
+ var[i].u.num.value = var[i].u.num.low;
+ break;
+ case 'i':
+ case 'I':
+ if (int_range(var[i].u.chr.set, &var[i].u.num.low, &var[i].u.num.high)) {
+ print("init/conf : error in int range\n");
+ continue;
+ }
+ var[i].u.num.value = var[i].u.num.low;
+ break;
+ default:
+ // unknown type
+ break;
+ }
+ }
+
+ while (1) {
+ char name[MAX_DEVNAME_LEN];
+ uchar minor_offset;
+ int f;
+
+ name_and_minor(name, &minor_offset, field);
+
+ mknod_chown(mode, uid, gid, major, minor + minor_offset, name);
+ f = 0;
+ while (inc_var_index(f) && (f<field))
+ f++;
+
+ if (f >= field)
+ break;
+ }
+}
+
+/* converts an octal permission mode into the mode_t equivalent */
+static mode_t a2mode(char *ascii) {
+ mode_t m = 0;
+ while ((unsigned)(*ascii - '0') < 8) {
+ m = (m << 3) | (*ascii - '0');
+ ascii++;
+ }
+ return m;
+}
+
+void flush_stdin() {
+ int ret;
+ fd_set in;
+ struct timeval tv;
+
+ while (1) {
+ FD_ZERO(&in);
+ FD_SET(0, &in);
+ tv.tv_sec = tv.tv_usec = 0;
+ ret = select(1, &in, NULL, NULL, &tv);
+ if (ret <= 0)
+ break;
+ read(0, &ret, sizeof(ret));
+ }
+}
+
+/* waits <delay> seconds for a character to be entered from stdin. It returns
+ * zero if the timeout expires, otherwise it flushes stdin and returns 1
+ */
+int keypressed(int delay) {
+ int ret;
+ fd_set in;
+ struct timeval tv;
+ FD_ZERO(&in);
+ FD_SET(0, &in);
+ tv.tv_sec = delay; tv.tv_usec=0;
+ ret = select(1, &in, NULL, NULL, &tv);
+ if (ret <= 0)
+ return 0;
+ flush_stdin();
+ return 1;
+}
+
+int main(int argc, char **argv, char **envp) {
+ int old_umask;
+ int pid1, err;
+ int cfg_ok;
+ int rebuild;
+ int token;
+ int cmd_input = INPUT_FILE;
+ static char cmd_line[256]; /* one line of config from the prompt */
+ struct stat statf;
+ // char *cmdline_arg;
+ char *cfg_file;
+ int brace_level, kbd_level, run_level;
+ struct {
+ int error;
+ int cond;
+ } context[MAX_BRACE_LEVEL];
+
+ char *conf_init, *force_init;
+
+ /* first, we'll check if we have been called as 'linuxrc', used only in
+ initrd. In this particular case, we ignore all arguments and use
+ /.linuxrc as a configuration file.
+ */
+
+#ifdef DEBUG
+ print("argv[0]: "); print(argv[0]); print("\n");
+ sleep(1);
+#endif
+
+ /* if we are called as "linuxrc" or "/linuxrc", then we work a bit
+ * differently : /dev is unmounted at the end, and we proceed even if the
+ * pid is not 1.
+ *
+ * Warning: for an unknown reason (isolinux, kernel?) specifying
+ * 'init=/linuxrc' or 'init=linuxrc' on the command line doesn't work
+ * because 'init' is set in argv[0] ! But setting it by hand works,
+ * so does 'init=/.linuxrc'. Rather strange. So the best solution is
+ * to link /sbin/init to /.linuxrc so that the interpreter's name is
+ * used even if nothing is specified.
+ */
+ if (!strcmp(argv[0], str_linuxrc) || !strcmp(argv[0], str__linuxrc)) {
+ linuxrc = 1;
+ rebuild = 0;
+ pid1 = 0;
+ }
+ /* check if a config file name has been given to preinit : init [ \< <cfg_file> ] [ init args ] */
+ if (argc > 2 && *argv[1] == '<') {
+ cfg_file = argv[2];
+ argv[2] = argv[0];
+ argv += 2;
+ argc -= 2;
+ }
+ else
+ cfg_file = linuxrc ? (char *)cfg_linuxrc : (char *)cfg_fname;
+
+ if (!linuxrc) {
+ /*FIXME*/
+ /* restore the correct name. Warning: in the case where init is launched
+ * from userspace, the config file is not read again so only the hardcoded
+ * name will be used for the executable name.
+ */
+ //*argv = (char *)&sbin_init_sysv; /*"sbin/init-sysv"*/;
+ conf_init = (char *)&sbin_init_sysv; /*"sbin/init-sysv"*/;
+ force_init = my_getenv(envp, CONST_STR("INIT="), 1);
+ //printf("force_init=<%s>, INIT_new=%p\n", my_getenv(envp, "INIT=", 0));
+ /* if "rebuild" is passed as the only argument, then we'll try to rebuild a
+ * full /dev even if not pid==1, but only if it was not already populated
+ */
+ rebuild = (argc == 2 && streq(argv[1], str_rebuild/*"rebuild"*/));
+ pid1 = (getpid() == 1);
+ }
+ else {
+ conf_init = NULL;
+ force_init = my_getenv(envp, CONST_STR("init2="), 1);
+ //*argv = (char *)&sbin_init; /* "sbin/init" */
+ //printf("force_init=<%s>, init2_new=%s\n", my_getenv(envp, "init2=", 0));
+ }
+
+ if (pid1 || linuxrc) {
+ setsid();
+ }
+
+ old_umask = umask(0);
+ cfg_ok = (read_cfg(cfg_file) == 0);
+
+ chdir(root_dir); /* be sure not to stay under /dev ! */
+ /* do nothing if we're not called as the first process */
+ if (pid1 || linuxrc || rebuild) {
+ /* check if /dev is already populated : /dev/console should exist. We
+ * can safely ignore and overwrite /dev in case of linuxrc, reason why
+ * we don't test the presence of /dev/console.
+ */
+#ifndef I_AM_REALLY_DEBUGGING
+ if (linuxrc || stat(dev_console, &statf) == -1) {
+ print("init/info: /dev/console not found, rebuilding /dev.\n");
+ if (mount(dev_name, dev_name, tmpfs_fs, MS_MGC_VAL, dev_options) == -1)
+ print("init/err: cannot mount /dev.\n");
+ else {
+ int i;
+ if (chdir(dev_name) == -1)
+ print("init/error : cannot chdir(/dev)\n");
+
+ print("init/info: /dev has been mounted.\n");
+ for (i = 0; i < sizeof(dev_nodes) / sizeof(dev_nodes[0]); i++) {
+ mknod_chown(dev_nodes[i].mode, (uid_t)UID_ROOT, (gid_t)dev_nodes[i].gid,
+ dev_nodes[i].major, dev_nodes[i].minor, (char *)dev_nodes[i].name);
+ }
+ symlink(proc_self_fd, fd_dir);
+ print("init/info: /dev has been rebuilt.\n");
+
+ chdir(root_dir);
+ /* if /dev was empty, we may not have had /dev/console, so the
+ * kernel couldn't bind us to it. So let's attach to it now.
+ */
+ reopen_console();
+ }
+ } else if (!pid1) {
+ /* we don't want to rebuild anything else if pid is not 1 */
+#ifdef DEBUG
+ print("init/info: /dev is OK.\n");
+ sleep(10);
+#endif
+ return 0;
+ }
+#endif
+ /* if /dev/root is non-existent, we'll try to make it now */
+
+ if (stat(dev_root, &statf) == -1) {
+ print("init/info : /dev/root does not exist. Rebuilding...\n");
+ if (stat(root_dir, &statf) == 0) {
+ if (mknod(dev_root, 0600 | S_IFBLK, statf.st_dev) == -1) {
+ //error = 1;
+ print("init/error : mknod(/dev/root) failed\n");
+ }
+ }
+ else {
+ print("init/error : cannot stat(/)\n");
+ }
+ }
+ }
+
+ /* here, the cwd is still "/" */
+ if (cfg_ok) {
+ print("ready to parse file : "); print(cfg_file); print("\n");
+
+ run_level = brace_level = 0;
+ context[brace_level].error = 0;
+ context[brace_level].cond = 0;
+
+ /* main parsing loop */
+ while (1) {
+ int cond = 0;
+
+ if (cmd_input == INPUT_KBD) {
+ int len;
+ char *cmd_ptr = cmd_line;
+ static char prompt[MAX_BRACE_LEVEL + 4];
+ char *p = prompt;
+ int lev1, lev2;
+
+ p += my_strlcpy(p, error ? CONST_STR("ER\n>") : CONST_STR("OK\n>"), 5);
+
+ lev1 = run_level;
+ lev2 = brace_level;
+ while (lev1) {
+ *p++ = '>';
+ lev1--;
+ lev2--;
+ }
+ if (lev2) {
+ *p++ = '{';
+ while (lev2--)
+ *p++ = '>';
+ *p++ = '}';
+ }
+ *p++ = ' ';
+ write(1, prompt, p-prompt);
+
+ len = read(0, cmd_line, sizeof(cmd_line)-1);
+ if (len > 0) {
+ cmd_line[len] = 0;
+ token = parse_cfg(&cmd_ptr);
+ if (token == TOK_EOF) /* empty line */
+ continue;
+ } else {
+ token = TOK_DOT;
+ }
+
+ if (token == TOK_DOT) {
+ cmd_input = INPUT_FILE;
+ brace_level = kbd_level;
+ /* if it was not right, 'rd' would not have been called : */
+ run_level = brace_level;
+ /* don't report prompt errors to the rest of the config ! */
+ error = 0;
+ }
+ } /* end of kbd */
+
+ if (cmd_input == INPUT_FILE) {
+ token = parse_cfg(&cfg_line);
+ if (token == TOK_EOF || token == TOK_DOT)
+ break;
+ }
+
+ if (token == TOK_UNK) {
+ print("unknown command.\n");
+ continue;
+ }
+
+ cond = token & TOK_COND;
+ token &= ~TOK_COND;
+
+ if (cfg_args[(int)tokens[token].minargs] == NULL) {
+ print("Missing args\n");
+ continue;
+ }
+
+ /* now we can reset the error */
+ context[brace_level].error = error;
+ error = 0;
+
+ if (token == TOK_CB) { /* closing brace */
+ if (cond & TOK_COND) {
+ print("Conditions not permitted with a closing brace.\n");
+ /* we close the brace anyway, ignoring the condition. */
+ } else if (brace_level == 0) {
+ print("Too many closing braces.\n");
+ error = context[brace_level].error;
+ continue;
+ }
+ /* transmit the current error to the upper level, and restore the upper
+ * condition to know if we had to negate the result or not.
+ */
+ error = context[brace_level--].error;
+ cond = context[brace_level].cond;
+ if (run_level > brace_level)
+ run_level = brace_level;
+ goto finish_cmd;
+ }
+ else if (token == TOK_OB) { /* opening brace */
+ if (brace_level == MAX_BRACE_LEVEL - 1) {
+ print("Too many brace levels.\n");
+ error = context[brace_level].error;
+ break;
+ }
+
+ /* if this block should not be executed because of a particular
+ * condition, we'll mark the new level to be skipped, so that
+ * other braces are correctly counted but not evaluated.
+ */
+ if ((run_level == brace_level) &&
+ (!(cond & TOK_COND_OR) || context[brace_level].error) &&
+ (!(cond & TOK_COND_AND) || !context[brace_level].error)) {
+ /* save the current condition to properly handle a negation.
+ * The error code has already been set to 0.
+ */
+ context[brace_level++].cond = cond;
+ run_level = brace_level;
+ }
+ else {
+ /* the braces will not be evaluated because a & or | prevents
+ * it to do so. Since we want to be able to chain these
+ * expressions to do if/then/else with &{}|{}, we'll propagate
+ * the current error code and void the condition.
+ */
+ error = context[brace_level].error;
+ context[brace_level++].cond = 0;
+ }
+ continue;
+ }
+
+ //printf("parsing intruction <%s %s...> at level %d (%d)\n", cfg_args[0], cfg_args[1], brace_level, run_level);
+ /* skip conditionnal executions if they cannot change the error status,
+ * as well as blocks of code excluded from the evaluation
+ */
+ if ((cond & TOK_COND_OR) && !context[brace_level].error ||
+ (cond & TOK_COND_AND) && context[brace_level].error ||
+ (run_level < brace_level)) {
+ error = context[brace_level].error;
+ continue;
+ }
+
+
+ /*
+ * Now we begin to parse the 'real' commands. The first set is always available
+ */
+
+ if (token == TOK_IN) {
+ /* I | in <path> : specify the path to init.
+ * Problem: what to do with init args ?
+ * We could pass ours, but if init is replaced with a
+ * shell, this one might be called with 'auto'...
+ * So we flush them all.
+ */
+ print("<I>nit : used config name for init\n");
+
+ /* in keyboard mode, specifying init stops any further parsing,
+ * so that the rest of the config file can be skipped.
+ */
+ if (cmd_input == INPUT_KBD) {
+ force_init = cfg_args[1];
+ break;
+ } else {
+ /* non sense to switch error status when assigning init */
+ error = context[brace_level].error;
+ conf_init = cfg_args[1];
+ continue;
+ }
+ } else if (token == TOK_TE) {
+ /* te <var=val> : compare an environment variable to a value.
+ * In fact, look for the exact assignment in the environment.
+ * The result is OK if found, NOK if not.
+ */
+ char **env = envp;
+ while (*env) {
+ //printf("testing <%s> against <%s>\n", cfg_args[1], *env);
+ if (!strcmp(*env, cfg_args[1]))
+ break;
+ env++;
+ }
+ error = (*env == NULL);
+ goto finish_cmd;
+ }
+
+ /* other options are reserved for pid 1/linuxrc/rebuild and prompt mode */
+ if (!pid1 && !linuxrc && !rebuild && cmd_input != INPUT_KBD) {
+ print("Command ignored since pid not 1\n");
+ error = context[brace_level].error;
+ continue;
+
+ } else if (token == TOK_RD || token == TOK_EC || token == TOK_WK) {
+ /* ec <string> : echo a string
+ rd <string> : display message then read commands from the console instead of the file
+ wk <string> <delay> : display message and wait for a key for at most <delay> seconds.
+ returns TRUE if a key is pressed, FALSE otherwise.
+ */
+ char *msg;
+ int len;
+
+ if (cfg_args[1] != NULL) {
+ len = strlen(cfg_args[1]);
+ cfg_args[1][len] = '\n';
+ write(1, cfg_args[1], len + 1);
+ }
+
+ if (token == TOK_WK) {
+ error = !keypressed(ATOL(cfg_args[2]));
+ goto finish_cmd;
+ }
+
+ if (token != TOK_RD)
+ goto finish_cmd;
+
+ if (cmd_input == INPUT_KBD) {
+ msg = (char *)msg_err_console;
+ len = sizeof(msg_err_console) - 1;
+ } else {
+ msg = (char *)msg_ent_console;
+ len = sizeof(msg_ent_console) - 1;
+ kbd_level = brace_level;
+ }
+ error = context[brace_level].error;
+ write(1, msg, len);
+ cmd_input = INPUT_KBD;
+ continue;
+ }
+
+ /* the second command set is available if pid==1 or if "rebuild" is set */
+ switch (token) {
+ case TOK_MD:
+ /* md path [ mode ] : make a directory */
+ if (mkdir(cfg_args[1], (cfg_args[2] == NULL) ? 0755 : a2mode(cfg_args[2])) == -1) {
+ error = 1;
+ print("<D>irectory : mkdir() failed\n");
+ }
+ goto finish_cmd;
+ case TOK_LN:
+ /* ln from to : make a symlink */
+ if (symlink(cfg_args[1], cfg_args[2]) == -1) {
+ error = 1;
+ print("<S>ymlink : symlink() failed\n");
+ }
+ goto finish_cmd;
+ case TOK_ST: {
+ /* st file : return error if file does not exist */
+ struct stat stat_buf;
+ if (stat(cfg_args[1], &stat_buf) == -1) {
+ error = 1;
+ }
+ goto finish_cmd;
+ }
+ case TOK_RM: {
+ /* rm file... : unlink file or links */
+ int arg = 1;
+ while (cfg_args[arg]) {
+ if (unlink(cfg_args[arg]) == -1) {
+ error = 1;
+ print("Unlink : unlink() failed\n");
+ }
+ arg++;
+ }
+ goto finish_cmd;
+ }
+ case TOK_BL:
+ /* bl <mode> <uid> <gid> <major> <minor> <naming rule> : build a block device */
+ case TOK_CH:
+ /* ch <mode> <uid> <gid> <major> <minor> <naming rule> : build a character device */
+ if (chdir(dev_name) == -1) {
+ print("<B>lock_dev/<C>har_dev : cannot chdir(/dev)\n");
+ error = 1;
+ goto finish_cmd;
+ }
+
+ multidev(a2mode(cfg_args[1]) | ((token == TOK_BL) ? S_IFBLK : S_IFCHR),
+ (uid_t)ATOL(cfg_args[2]), (gid_t)ATOL(cfg_args[3]),
+ ATOL(cfg_args[4]), ATOL(cfg_args[5]), cfg_args[6]);
+ chdir(root_dir);
+ goto finish_cmd;
+ case TOK_FI:
+ /* F <mode> <uid> <gid> <name> : build a fifo */
+ if (chdir(dev_name) == -1) {
+ print("<F>ifo : cannot chdir(/dev)\n");
+ error = 1;
+ goto finish_cmd;
+ }
+
+ error = mknod_chown(a2mode(cfg_args[1]) | S_IFIFO,
+ (uid_t)ATOL(cfg_args[2]), (gid_t)ATOL(cfg_args[3]),
+ 0, 0, cfg_args[4]);
+ chdir(root_dir);
+ goto finish_cmd;
+ } /* end of switch() */
+
+ /* other options are reserved for pid 1/linuxrc/prompt mode only */
+ if (!pid1 && !linuxrc && cmd_input != INPUT_KBD) {
+ print("Command ignored since pid not 1\n");
+ error = context[brace_level].error;
+ continue;
+ }
+
+ switch (token) {
+ case TOK_MT:
+ case TOK_RE: {
+ /* M dev[(major:minor)] mnt type [ {rw|ro} [ flags ] ]: (re)mount dev on mnt (read-only) */
+ char *maj, *min, *end;
+ char *mntdev;
+ int mntarg;
+
+ /* if the device name doesn't begin with a slash, look for it
+ * in /proc/cmdline
+ */
+ mntdev = cfg_args[1];
+ // the following code handles "var=/dev/sda2" or "home=/dev/hda1(3:1)" on
+ // the kernel command line.
+ //if ((*mntdev != '/') && ((cmdline_arg = find_arg(mntdev)) != NULL)) {
+ // mntdev = cmdline_arg;
+ // print("<M>ount : using command line device\n");
+ //}
+
+ maj = mntdev; /* handles /dev/xxx(maj:min) */
+ while (*maj && *maj != '(')
+ maj++;
+ if (*maj) {
+ int imaj = 0, imin = 0;
+ dev_t dev;
+
+ *(maj++) = 0;
+ min = end = maj;
+ while (*min && *min != ':')
+ min++;
+
+ if (*min) {
+ *(min++) = 0;
+ end = min;
+ }
+
+ while (*end && *end != ')')
+ end++;
+
+ if (*end)
+ *end = 0;
+ if (*maj)
+ imaj = ATOL(maj);
+ if (*min)
+ imin = ATOL(min);
+ dev = makedev(imaj, imin);
+ if (mknod(mntdev, S_IFBLK|0600, dev) == -1) { /* makes the node as required */
+ error = 1;
+ print("<M>ount : mknod() failed\n");
+ }
+ }
+
+ mntarg = MS_RDONLY;
+ if (cfg_args[4] != NULL && streq(cfg_args[4], CONST_STR("rw"))) {
+ print("<M>ount : 'rw' flag found, mounting read/write\n");
+ mntarg &= ~MS_RDONLY;
+ }
+ else {
+ print("<M>ount : 'rw' flag not found, mounting read only\n");
+ }
+
+ if (token == TOK_RE)
+ mntarg |= MS_REMOUNT;
+
+ if (mount(mntdev, cfg_args[2], cfg_args[3], MS_MGC_VAL | mntarg, cfg_args[5]) == -1) {
+ error = 1;
+ print("<M>ount : error during mount()\n");
+ }
+
+ break;
+ }
+ case TOK_EX:
+ /* E cmd [cfg_args] : execute cmd with cfg_args, chrooted to dir */
+ /* fall through TOK_RX */
+ case TOK_RX: {
+ /* R dir cmd [cfg_args] : execute cmd with cfg_args, chrooted to dir */
+ char **exec_args, *exec_dir;
+ int res;
+
+ exec_args = cfg_args + 1;
+ if (token == TOK_EX) {
+ exec_dir = (char *)root_dir;
+ }
+ else {
+ exec_dir = cfg_args[1];
+ exec_args++;
+ }
+
+ res = fork();
+ if (res == 0) {
+ chroot(exec_dir);
+ execve(exec_args[0], exec_args, envp);
+ print("<E>xec(child) : execve() failed\n");
+ return 1;
+ }
+ else if (res > 0) {
+ int ret;
+ print("<E>xec(parent) : waiting for termination\n");
+ while (((ret = wait(&error)) != -1) && (ret != res))
+ print("<E>xec(parent) : signal received\n");
+
+ error = (ret == -1) || ((WIFEXITED(error) > 0) ? WEXITSTATUS(error) : 1);
+ print("<E>xec(parent) : child exited\n");
+ }
+ else {
+ print("<E>xec : fork() failed\n");
+ error = 1;
+ }
+ break;
+ }
+ case TOK_MA:
+ /* U <umask> : change umask */
+ umask(a2mode(cfg_args[1]));
+ break;
+ case TOK_PR:
+ /* P <new_root> <put_old_relative> : pivot root */
+ if (chdir(cfg_args[1]) == -1) {
+ error = 1;
+ print("<P>ivot : error during chdir(new root)\n");
+ }
+
+ if (pivot_root(/*CONST_STR(".")*/cur_dir, cfg_args[2]) == -1) {
+ error = 1;
+ print("<P>ivot : error during pivot_root()\n");
+ }
+
+ chroot(cur_dir/*CONST_STR(".")*/);
+ if (chdir(root_dir) == -1) {
+ error = 1;
+ print("<P>ivot : error during chdir(/)\n");
+ }
+
+ /* replace stdin/stdout/stderr with newer ones */
+ reopen_console();
+ break;
+ case TOK_MV:
+ /* K | mv <fs_dir> <new_dir> :
+ * initially used to keep directory <old_dir> after a pivot, now used to
+ * move a filesystem to another directory.
+ */
+ if (mount(cfg_args[1], cfg_args[2], cfg_args[1], MS_MGC_VAL | MS_MOVE, NULL) == 0)
+ break;
+ /* if it doesn't work, we'll try to cheat with BIND/UMOUNT */
+ case TOK_BI:
+ /* bi <old_dir> <new_dir> : bind old_dir to new_dir, which means that directory
+ * <new_dir> will show the same contents as <old_dir>.
+ */
+ if (mount(cfg_args[1], cfg_args[2], cfg_args[1], MS_MGC_VAL | MS_BIND, NULL) == -1) {
+ error = 1;
+ print("<bi> : error during mount|bind\n");
+ }
+ if (token == TOK_BI)
+ break;
+ /* fall through umount if we were trying a move */
+ case TOK_UM:
+ /* um <old_dir> : umount <old_dir> after a pivot. */
+ if (umount2(cfg_args[1], MNT_DETACH) == -1) {
+ error = 1;
+ print("<um> : error during umount\n");
+ }
+ break;
+ case TOK_LO: {
+ /* lo </dev/loopX> <file> : losetup /dev/loopX file */
+ struct loop_info loopinfo;
+ int lfd, ffd;
+
+ if ((lfd = open (cfg_args[1], O_RDONLY)) < 0) {
+ error = 1;
+ print("(l)osetup : error opening loop device\n");
+ break;
+ }
+ if ((ffd = open (cfg_args[2], O_RDONLY)) < 0) {
+ error = 1;
+ print("(l)osetup : error opening image\n");
+ goto losetup_close_all;
+ }
+ memset(&loopinfo, 0, sizeof (loopinfo));
+ my_strlcpy(loopinfo.lo_name, cfg_args[2], LO_NAME_SIZE);
+ if (ioctl(lfd, LOOP_SET_FD, ffd) < 0) {
+ error = 1;
+ print("(l)osetup : error during LOOP_SET_FD\n");
+ goto losetup_close_all;
+ }
+ if (ioctl(lfd, LOOP_SET_STATUS, &loopinfo) < 0) {
+ error = 1;
+ ioctl(lfd, LOOP_CLR_FD, 0);
+ print("(l)osetup : error during LOOP_SET_STATUS\n");
+ goto losetup_close_all;
+ }
+ losetup_close_all:
+ close (lfd); close (ffd);
+ break;
+ }
+ default:
+ print("unknown cmd in /.preinit\n");
+ break;
+ }
+ finish_cmd:
+ if (cond & TOK_COND_NEG)
+ error = !error;
+ } /* while (1) */
+ } else if (pid1 && !linuxrc) {
+ print("init/info : error while opening configuration file : ");
+ print(cfg_file); print("\n");
+
+ /* /.preinit was not found. In this case, we take default actions :
+ * - mount /proc
+ * - mount /var as tmpfs if it's empty and /tmp is a symlink
+ */
+ if (mount(proc_dir, proc_dir, proc_fs, MS_MGC_VAL, NULL) == -1)
+ print("init/err: cannot mount /proc.\n");
+ else
+ print("init/info: /proc mounted RW.\n");
+
+ /* we'll see if we want to build /var */
+ if ((stat(var_tmp, &statf) == -1) && /* no /var/tmp */
+ (stat(tmp_name, &statf) == 0) && S_ISLNK(statf.st_mode)) { /* and /tmp is a symlink */
+ print("init/info: building /var.\n");
+ if (mount(var_dir, var_dir, tmpfs_fs, MS_MGC_VAL, NULL) == -1)
+ print("init/err: cannot mount /var.\n");
+ else {
+ print("init/info: /var has been mounted.\n");
+ mkdir(var_dir, 0755);
+ mkdir(var_tmp, 01777);
+ mkdir(var_run, 0755);
+ print("init/info: /var has been built.\n");
+ }
+ }
+ }
+ else {
+ print("init/info : error while opening configuration file : ");
+ print(cfg_file); print("\n");
+ }
+
+ if (rebuild) {
+ print("end of rebuild\n");
+#ifdef SLOW_DEBUG
+ sleep(10);
+#endif
+ /* nothing more to do */
+ return 0;
+ }
+
+
+ /* We undo all that we can to restore a clean context.
+ * In case the init has been specified by the user at the console prompt,
+ * we don't close 0/1/2 nor dismount /dev, else we wouldn't be able to do
+ * anything.
+ */
+
+ if (force_init != NULL) {
+ /* we keep the cmdline args if we take it from the kernel cmdline,
+ * but we flush any args if it comes from the keyboard
+ */
+ argv[0] = force_init;
+ if (cmd_input == INPUT_KBD)
+ argv[1] = NULL;
+ } else {
+ /* standard conf or new linuxrc : !NULL = chained init */
+ /* old linuxrc : NULL = no chained init */
+ argv[0] = conf_init;
+ }
+
+ if (linuxrc && force_init == NULL) {
+ /* normal linuxrc : we close and unmount all what we have done, but not
+ * in case of forced init, because if we force, it should mean that we
+ * want a prompt or something special.
+ */
+ close(2); close(1); close(0);
+ umount2(dev_name, MNT_DETACH);
+ }
+
+#if 0
+
+ if (cmd_input != INPUT_KBD) {
+ if (linuxrc) {
+ close(2); close(1); close(0);
+ umount2(dev_name, MNT_DETACH);
+ print("exit from linuxrc\n");
+#ifdef SLOW_DEBUG
+ sleep(10);
+#endif
+ /* handle the lilo command line "init2=prog" */
+ //cmdline_arg = find_arg(CONST_STR("init2"));
+ //cmdline_arg = my_getenv(envp, CONST_STR("init2="), 1);
+ } else {
+ /* handle the lilo command line "INIT=prog" */
+ //cmdline_arg = find_arg(CONST_STR("INIT"));
+ cmdline_arg = my_getenv(envp, CONST_STR("INIT="), 1);
+ }
+
+ if (cmdline_arg != NULL) {
+ argv[0] = cmdline_arg;
+ argv[1] = NULL;
+ }
+ }
+
+ print("init/debug: *argv = "); print (*argv); print("\n");
+#endif
+
+ umask(old_umask);
+#ifdef SLOW_DEBUG
+ sleep(10);
+#endif
+ /* the old linuxrc behaviour doesn't exec on exit. */
+ if (*argv != NULL) {
+ err = execve(*argv, argv, envp);
+ print("init/error : last execve() failed\n");
+
+ /* we'll get a panic there, so let some time for the user to read messages */
+ if (pid1)
+ sleep(60);
+ return err;
+ }
+ return 0;
+}
diff --git a/scripts/flxextract b/scripts/flxextract
index e4aa4ee..7077fa2 100755
--- a/scripts/flxextract
+++ b/scripts/flxextract
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# flxextract - package extracter - version 0.0.2 - 2003-06-16
+# flxextract - package extracter - version 0.0.3 - 2005-10-31
# This file is part of the Formilux project : http://formilux.ant-computing.com/
#
# Copyright (C) 2001-2003 Benoit Dolez & Willy Tarreau
@@ -19,7 +19,7 @@ function main {
for pack in ${packages//,/ }; do
pkgsrc=$(find $SEARCHPATH -name ${pack}'*'.lst | head -1)
- [ "$pkgsrc" ] && break
+ [ -n "$pkgsrc" ] && break
done
if [ -z "$pkgsrc" ]; then
@@ -27,7 +27,7 @@ function main {
continue
fi
- set -- $( grep "$file" $pkgsrc | awk '{ if ($8=="'$file'") print $0; }' )
+ set -- $(awk "/$file/ { if (\$8==\"$file\") print \$0; }" $pkgsrc)
if [ -z "$*" ]; then
echo "##not found## $file $pkgsrc" >> $LOGFILE
continue
@@ -36,7 +36,7 @@ function main {
# it's a directory
rm -f $ROOTDIR/$8 >/dev/null 2>&1 # just in case it was something else
mkdir -p $ROOTDIR/$8
- touch -t `date -d "Jan 1 00:00:$7 UTC 1970" +"%Y%m%d%H%M.%S" ` $ROOTDIR/$8
+ touch -t $(date -d "Jan 1 00:00:00 UTC 1970 + $7 sec" +"%Y%m%d%H%M.%S" ) $ROOTDIR/$8
chown $3:$4 $ROOTDIR/$8
chmod $2 $ROOTDIR/$8
echo "$8/" >> $LOGFILE
@@ -48,8 +48,7 @@ function main {
echo >&2 ; echo -n "Extracting files ..." >&2
for lst in $( awk '{print $2}' $SFILES | sort -u ) ; do
- tgz="$(dirname $lst)/$(basename $lst .lst).tgz"
- grep -- " $lst$" $SFILES | awk '{print $1}' | tar zUxpvf $tgz -C $ROOTDIR -T - >> $LOGFILE
+ awk "/ $lst\$/ {print \$1}" $SFILES | tar zUxpvf ${lst%.lst}.tgz -C $ROOTDIR -T - >> $LOGFILE
echo -n "." >&2
done
echo "." >&2
diff --git a/scripts/flxfix b/scripts/flxfix
index ef09a90..8952c39 100755
--- a/scripts/flxfix
+++ b/scripts/flxfix
@@ -1,27 +1,83 @@
#!/bin/bash
-# flxfix - 2003/01/31 - Willy Tarreau <willy@ant-computing.com>
+# flxfix 0.2 - 2005/04/17 - Willy Tarreau <willy@ant-computing.com>
# Generates a shell script from a difference between two trees so that the last
-# one becomes as close to the first one as possible.
+# one becomes as close to the first one as possible. Second usage is to rebuild
+# all the meta-data from a signature.
+#
# usage:
# flx check <reference> <tobefixed> | flxfix [ -R ] > fix.sh
-# Use -R to swap the two trees
+# Use -R to swap the two trees
+# flx sign <reference> | flxfix -n > create.sh
+# Generates a shell script which rebuilds the meta-data from the tree's
+# signature.
+#
+# WARNING: this script does not understand flx-0.7's extended encoding of
+# unprintable characters.
+
+
+entryisdiff=1
+restoredate=1
+unset mustswap ignoreuid
# usage : fixperms $perm $uid $gid $date $name
function fixperms {
- echo touch -t \"`date -d "Jan 1 00:00:$4 UTC 1970" +"%Y%m%d%H%M.%S" `\" $5
- echo chown $2:$3 $5
+ echo touch ${restoredate:+-t \"$(date -d "Jan 1 00:00:$4 UTC 1970" +"%Y%m%d%H%M.%S" )\"} $5
+ [ -z "$ignoreuid" ] && echo chown $2:$3 $5
echo chmod $1 $5
}
-mustswap=0
-if [ "x$1" = "x-R" ]; then
- mustswap=1
-fi
+# swap diff direction : -/+, </>
+function swap {
+ local x
+ x=${1/</.}; x=${x/>/<}; x=${x/./>}
+ x=${x/-/.}; x=${x/+/-}; x=${x/./+}
+ echo -n $x
+}
+
+# usage: usage progname exitcode
+function usage {
+ echo "$1: Generates a script to rebuild the meta-data from an flx signature"
+ echo "Usage:"
+ echo " flx check <reference> <tobefixed> | $1 > fix.sh"
+ echo " flx check <tobefixed> <reference> | $1 -R > fix.sh"
+ echo " flx sign <reference> | $1 -n > new.sh"
+ echo " cat old-signature.lst | $1 -n > new.sh"
+ echo ""
+ echo "Options:"
+ echo " -R swap the two trees"
+ echo " -n recreate a new tree from a single signature"
+ echo " -t do not restore timestamp"
+ echo " -u do not restore uid/gid"
+
+ exit $2
+}
+
+
+while [ $# -gt 0 ]; do
+ if [ "x$1" = "x-R" ]; then
+ mustswap=1
+ elif [ "x$1" = "x-n" ]; then
+ unset entryisdiff
+ elif [ "x$1" = "x-u" ]; then
+ ignoreuid=1
+ elif [ "x$1" = "x-t" ]; then
+ unset restoredate
+ elif [ "x$1" = "x-h" ]; then
+ usage "${0##*/}" 0
+ else
+ echo "Warning: ignoring unknown option: $1"
+ usage "${0##*/}" 1
+ fi
+ shift
+done
-while read chg type perm uid gid size sign date name link rest; do
- if [ $mustswap = 1 ]; then
- chg=`echo $chg | tr '<>+\-' '><\-+'`
+# trick: we only reference the 'chg' variable if 'entryisdiff' is set.
+while read ${entryisdiff:+chg} type perm uid gid size sign date name link rest; do
+ if [ -z "$entryisdiff" ]; then
+ chg='-'
+ elif [ -n "$mustswap" ]; then
+ chg=$(swap $chg)
fi
if [ "x$rest" != "x" -o "x$type" != "xl" -a "x$link" != "x" ]; then
@@ -45,7 +101,7 @@ while read chg type perm uid gid size sign date name link rest; do
if [ x$type = xl ]; then
# we'll rebuild a symbolic link
echo ln -s $link $name
- echo chown -h $uid:$gid $name
+ [ -z "$ignoreuid" ] && echo chown -h $uid:$gid $name
elif [ x$type = xd ]; then
# we'll rebuild a directory
echo mkdir -p $name
@@ -70,7 +126,7 @@ while read chg type perm uid gid size sign date name link rest; do
# we'll destroy and rebuild a symbolic link
echo rm -f $name
echo ln -s $link $name
- echo chown -h $uid:$gid $name
+ [ -z "$ignoreuid" ] && echo chown -h $uid:$gid $name
elif [ x$type = xc -o x$type = xb -o x$type = xf ]; then
# we'll destroy and rebuild nodes
echo rm -f $name
diff --git a/scripts/pkg b/scripts/pkg
index e9465ef..9c38b6b 100755
--- a/scripts/pkg
+++ b/scripts/pkg
@@ -1,16 +1,19 @@
#!/bin/bash
-# pkg - Formilux package builder - version 0.5.2 - 2005-03-25
+# pkg - Formilux package builder - version 0.7.1 - 2005-12-17
#
# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
# mailto: benoit@ant-computing.com,willy@ant-computing.com
#
# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+######## Please update this version ########
+PKG_VERSION=0.7.1
+############################################
+
## WARNING ##
# This version is not compatible with pkg scripts written for pre-0.2.0 versions
-
# Usage:
# pkg <action> [ pkg [ pkg2 ] ]
#
@@ -50,7 +53,17 @@ umask og-w
# set some constants
KERNDIR=${KERNDIR:-/usr/src/linux}
-FLXARCH=${FLXARCH:-$(uname -m)}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
DEVROOT=${DEVROOT:-/var/flx-dev}
PKGROOT=${PKGROOT:-/var/flx-pkg}
# use -p1 by default to apply a patch
@@ -66,6 +79,7 @@ INSTNAME=".flxdisk"
LINKNAME=".flxpkg"
FIND_CMD=pkgfilefind
+CURDIR="$(pwd)"
FILE_LIST=
@@ -76,6 +90,46 @@ EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cd
###### here are some undertermined type functions
######
+# check that this utility's version is at least as high as the version
+# specified in $1. Returns 0 if OK, 1 if inferior.
+
+function check_pkg_version {
+ local version="$1"
+ local major minor patch
+ local mymajor myminor mypatch
+
+ major=${version%%.*}
+ minor=${version#$major.}; minor=${minor%%.*}
+ patch=${version##*.}
+
+ mymajor=${PKG_VERSION%%.*}
+ myminor=${PKG_VERSION#$mymajor.}; myminor=${myminor%%.*}
+ mypatch=${PKG_VERSION##*.}
+
+ if [ -n "$major" ]; then
+ [ "$mymajor" -gt "$major" ] && return 0
+ [ "$mymajor" -lt "$major" ] && return 1
+ else
+ return 0
+ fi
+
+ if [ -n "$minor" ]; then
+ [ "$myminor" -gt "$minor" ] && return 0
+ [ "$myminor" -lt "$minor" ] && return 1
+ else
+ return 0
+ fi
+
+ if [ -n "$patch" ]; then
+ [ "$mypatch" -gt "$patch" ] && return 0
+ [ "$mypatch" -lt "$patch" ] && return 1
+ else
+ return 0
+ fi
+ return 0
+}
+
+
# find packageable files (that can't be automaticaly created) and return only
# their relative path to the argument.
@@ -92,6 +146,106 @@ function pkgfilefind {
}
+# resolves a symlink to an absolute location.
+# usage: resolve_link <link_dir> <link_pointer>
+function resolve_link {
+ # prints $1 if $2 is empty, and prints $2 if it starts with a '/'.
+ if [ -z "$2" ]; then
+ dir="$1"
+ elif [ -z "${2##/*}" ]; then
+ dir="$2"
+ else
+ dir="$1/$2"
+ fi
+
+ # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right,
+ # then enclose with '/'
+ while [ -n "$dir" ]; do
+ if [ -z "${dir##./*}" ]; then dir="${dir#./}"
+ elif [ -z "${dir##/*}" ]; then dir="${dir#/}"
+ elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}"
+ elif [ -z "${dir%%*/}" ]; then dir="${dir%/}"
+ elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}"
+ elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}"
+ else
+ dir="/$dir/"
+ break;
+ fi
+ done
+
+ # now resolve '/../' from left to right only.
+ while [ -z "${dir##*/../*}" ]; do
+ # if dir goes past root, we must truncate it
+ if [ -z "${dir##/../*}" ]; then
+ dir="/${dir##/../}"
+ else
+ # turn all '/x/../' into '/'
+ odir="$dir"
+ dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')"
+ [ "$dir" = "$odir" ] && break
+ fi
+ done
+
+ [ "$dir" = "/" ] || dir="${dir#/}"
+ [ "$dir" = "/" ] || dir="${dir%/}"
+ echo "$dir"
+}
+
+# this function analyses an ELF executable and prints its name along with some
+# informations such as :
+# %N:soname : for libraries, their soname
+# %D:libname : library it depends on (their soname)
+# %P:provide : feature provided by a library, in the form soname/version
+# %R:require : required feature, in the for soname/version
+function elf_get_dep {
+ local elf
+ for elf in "$@"; do
+ $OBJDUMP -p "$elf" | (
+ soname_str=""
+ soname=""
+ needed=""
+ provide=""
+ require=""
+ curreq=""
+ section=""
+ while read; do
+ case "$REPLY" in
+ Dynamic\ Section*)
+ section="dynamic" ;;
+ Version\ defin*)
+ section="definitions" ;;
+ Version\ Refer*)
+ section="references" ;;
+ *)
+ set -- $REPLY
+ if [ "$section" = "dynamic" ]; then
+ if [ "$1" = "NEEDED" ]; then
+ needed="${needed:+$needed }%D:$2"
+ elif [ "$1" = "SONAME" ]; then
+ soname="$2"
+ soname_str="${soname_str:+$soname_str }%N:$2"
+ fi
+ elif [ "$section" = "definitions" ]; then
+ if [ "$#" = "4" -a "$2" = "0x00" ]; then
+ provide="${provide:+$provide }%P:$soname/$4"
+ fi
+ elif [ "$section" = "references" ]; then
+ if [ "$#" = "3" -a "$1" = "required" ]; then
+ curreq="${3%:}"
+ elif [ "$#" = "4" ]; then
+ require="${require:+$require }%R:$curreq/$4"
+ fi
+ fi
+ ;;
+ esac
+ done
+ echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}"
+ )
+ done
+ return 0
+}
+
+
######
###### here are some functions for manipulating package names
######
@@ -127,6 +281,7 @@ function get_next_build {
# This function accepts a list of versionned names, and returns them sorted by
# version number. The names must NOT contain any '|' or '~' character, or they
# will be discarded. Names that don't have any version are also discarded.
+# Note: package names can be full path names.
function sortnames {
local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
local base version rest filename i t file flist
@@ -143,10 +298,11 @@ function sortnames {
VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
# make the list appear in the form 'package|version|rest|full_name'
- list=($(echo "$*" | grep -v "|~" | sed -e "s/$VERSION/\1|/" \
- -e "s/^$FIELD|$VERSION/\1|\2|/" \
- -e "s/^$FIELD|$FIELD|$FIELD$/\1|\2|\3~\1\2\3/" \
- -e "s/^[^|]*|[^|]*$//"))
+ list=($(echo "$*" | grep -v "|~" | sed -e "s,$VERSION,\1|," \
+ -e "s,^$FIELD|$VERSION,\1|\2|," \
+ -e "s,^$FIELD|$FIELD|$FIELD$,\1|\2|\3~\1\2\3," \
+ -e "s,^[^|]*|[^|]*$,," \
+ -e 's,^[^|]*/,,'))
# there's a risk that it doesn't complete for all the list, and that some
# elements keep a "rest". But what can we do about it ?
@@ -362,22 +518,31 @@ function do_build {
# %D => use the default package
# If several packages match a given pattern, the user is asked to select the
# desired one.
-# The result is returned in REPLY.
+# The resulting package name is returned in REPLY, and the package directoryy
+# is returned in PKGDIR whenever possible.
function get_name {
local pattern pkg_name
local radix ver build
local -a rel_list dev_list sort_list
- local i
+ local i search_dir
REPLY=
for pattern in $*; do
+ search_dir=
if [ "$pattern" = "%P" ]; then
- pattern=$(basename $(pwd))
+ search_dir="${CURDIR%/*}" ; search_dir="/${search_dir#/}"
+ pattern="$(basename $CURDIR)"
elif [ "$pattern" = "%L" ]; then
- if [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ return
+ elif [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
# the link is always an EXACT name, so we return it as-is.
- pattern=$(readlink ${LINKNAME})
- REPLY=$(basename $pattern)
+ pattern="$(readlink ${LINKNAME})"
+ PKGDIR="$pattern/."
+ REPLY="${pattern##*/}"
return
else
continue
@@ -394,13 +559,18 @@ function get_name {
# we loop until pkg_name is empty, which allows recursive choices.
while [ "$pkg_name" ]; do
# now we'll try to build a list of potentially matching packages for
- # each pattern. We'll reduce the original name until either we have
- # a non-empty list or the package name is void.
+ # each pattern. A valid package needs to host 'build.cfg'. We could
+ # also look for the 'RELEASED' entry for released packages, but there
+ # are still a lot of old ones without this entry. We'll reduce the
+ # original name until either we have a non-empty list or the package
+ # name is void.
rel_list=( ); dev_list=( )
while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
- rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ #rel_list=( $(find ${search_dir:+$search_dir/} $PKGROOT/ -maxdepth 2 -type f -path ${pkg_name}/build.cfg -printf "%h\n" 2>/dev/null) )
+ #rel_list=( ${search_dir:+$CURDIR} $(find $PKGROOT/ -maxdepth 2 -type f -path ${pkg_name}/build.cfg -printf "%h\n" 2>/dev/null) )
+ rel_list=( $(find ${search_dir:+$CURDIR/} $PKGROOT/ -maxdepth 2 -type f -path "*/${pkg_name}/build.cfg" -printf "%h\n" 2>/dev/null | uniq) )
if [ "$release_only" != "1" ]; then
- dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 2 -type f -path "*/${pkg_name}/build.cfg" -printf "%h\n" 2>/dev/null) )
fi
if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
@@ -434,7 +604,9 @@ function get_name {
if [ ${#sort_list[*]} -eq 0 ]; then
continue
elif [ ${#sort_list[*]} -eq 1 ]; then
- REPLY=${sort_list[0]}
+ REPLY="${sort_list[0]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
return
fi
@@ -443,21 +615,24 @@ function get_name {
printf " %5d : - None of the following packages -\n" 0
while [ $i -lt ${#sort_list[*]} ]; do
# we'll display an 'R' in front of released names, or a 'D' for dev.
+ # FIXME : we risk a wrong match here (eg: flx0.1 <-> flx0.10)
if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
- printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/}
else
- printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/}
fi
i=$[$i+1]
done
echo
while : ; do
- echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i
if [ -z "$i" ]; then
# empty string, we use the last choice which is the preferred one.
i=${#sort_list[*]}
- REPLY=${sort_list[$[$i-1]]}
+ REPLY="${sort_list[$[$i-1]]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
return
elif [ "${i//[0-9]/}" ]; then
# not a plain integer, we'll allow to recursively re-select
@@ -472,7 +647,9 @@ function get_name {
# if the user explicitly replied "0", then he wants other choices.
break;
elif [ $i -le ${#sort_list[*]} ]; then
- REPLY=${sort_list[$[$i-1]]}
+ REPLY="${sort_list[$[$i-1]]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
return
fi
done
@@ -480,6 +657,8 @@ function get_name {
# if he refuses these ones.
done
done
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
}
# choose a package and make ${LINKNAME} point to it
@@ -525,7 +704,7 @@ function do_newpkg {
if [ -z "$new_name" ]; then
# the user has not specified any version string, we'll use the directory
# name.
- new_name=$(basename $(pwd))
+ new_name=$(basename $CURDIR)
fi
rel_list=( ); dev_list=( )
@@ -541,13 +720,13 @@ function do_newpkg {
build=$(get_build_num $new_name)
new_name=${radix:-*}-${ver:-*}
- rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
- dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) )
sort_list=(${rel_list[*]} ${dev_list[*]})
if [ "${sort_list[*]}" ]; then
sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
- sort_list=( $(sortnames ${sort_list[*]}) )
+ sort_list=( $(sortnames ${sort_list[*]##*/} | uniq) )
if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
# if the package was properly named, and not already listed, let's
@@ -561,21 +740,13 @@ function do_newpkg {
local i=0
echo; echo ">>> Please select the name of the package to create :";echo
while [ $i -lt ${#sort_list[*]} ]; do
- # we'll display an 'R' in front of released names, 'P'
- # in front of packaged ones, or a 'D' for dev.
- if [ -e "$PKGROOT/${sort_list[$i]}/RELEASED" ]; then
- printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
- elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
- printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]}
- else
- printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
- fi
+ printf " %5d : %s\n" $[$i+1] ${sort_list[$i]##*/}
i=$[$i+1]
done
echo
while : ; do
- echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i
if [ -z "$i" ]; then
new_name=${sort_list[${#sort_list[*]}-1]}
break
@@ -594,8 +765,8 @@ function do_newpkg {
# we'll search for all packages starting with the same name and version
# in both release and dev dirs. Then we'll be able to deduce the latest
# build number used.
-# sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
- sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ #sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%p\n" 2>/dev/null|sort -u) )
if [ ${#sort_list[*]} -eq 0 ]; then
# this can happen with new BUILDSFX/BUILDVER
new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
@@ -648,7 +819,7 @@ function do_newpkg {
rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
--exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
- -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ --exclude='./Version' --one-file-system -cpf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
chmod u+rw $new_name/build.cfg
echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
@@ -680,13 +851,14 @@ function do_cat {
function do_lst {
local FPNAME
- FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
cat $FPNAME.lst
}
function pre_info {
- echo "Information for package '$EXACTPKG' :"
+ echo "Information for package '${EXACTPKG##*/}' (\${EXACTPKG##*/}) :"
+ echo " Package name : $PKGRADIX (\$PKGRADIX)"
echo " Package version : $PKGVER (\$PKGVER)"
echo " Distrib version : $DISTVER (\$DISTVER)"
echo -n " Config. file : "
@@ -695,10 +867,10 @@ function pre_info {
else
echo "none found."
fi
- echo " Package file : $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF"
+ echo " Package file : $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF"
echo -n " Package size : "
- if [ -e $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF ]; then
- echo "$(du -b $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ if [ -e $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF |cut -f1) bytes."
else
echo "does not exist yet."
fi
@@ -752,10 +924,10 @@ function pre_prepack {
fi
# WARNING! here, we don't use $ROOTDIR because we don't want to risk
# erasing a wrong directory as root !
- [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}"
# permissions are important here because we don't want to get an
# inherited setgid or something alike on the root dir
- [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chown 0:0 $ROOTDIR; chmod 0755 $ROOTDIR; }
#mkdir -p "$EXAMPLEDIR"
return 0
}
@@ -783,7 +955,7 @@ function build_opt {
function do_delpack {
# WARNING! here, we don't use $ROOTDIR because we don't want to risk
# erasing a wrong directory as root !
- [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}"
return 0
}
@@ -844,7 +1016,7 @@ function do_unpatch {
# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
function do_unpack {
- local FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF
+ local FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF
mkdir -p $ROOTDIR
cd $ROOTDIR
@@ -881,7 +1053,7 @@ function pre_pack {
function get_perl_depend {
local filename=$1
local dep DEP
- local DEP_FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.dep
+ local DEP_FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.dep
DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
@@ -913,7 +1085,7 @@ function _do_pack_files {
echo "done."
# full path name of different files
- FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
DEP_FILE=$FPNAME.dep
rm -rf $DEP_FILE
@@ -935,7 +1107,7 @@ function _do_pack_files {
bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
flr="$(file $REPLY)"
case "$flr" in
- *\ shell\ *)
+ *\ script\ *)
echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
;;
*perl\ commands*)
@@ -943,13 +1115,13 @@ function _do_pack_files {
get_perl_depend $REPLY
;;
*:\ symbolic\ link*)
- echo "$REPLY $(readlink $REPLY)" >> $DEP_FILE
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
;;
*\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
- echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
+ elf_get_dep $REPLY >> $DEP_FILE
;;
*\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
- echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
+ elf_get_dep $REPLY >> $DEP_FILE
;;
esac
;;
@@ -972,12 +1144,12 @@ function _do_pack_files {
echo -n "Creating $FPNAME.$PKGSUFF ... "
# we want everything, including directories.
- cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
# create shortcuts ".*" for tgz, dep and lst files
for ext in dep lst tgz; do
rm -f $PKGDIR/.$ext
- ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext
done
echo "done."
return 0
@@ -996,7 +1168,7 @@ function do_pack {
if [ -z "${file##/*}" ]; then
FILE_LISTS="$FILE_LISTS $file"
else
- FILE_LISTS="$FILE_LISTS $(pwd)/$file"
+ FILE_LISTS="$FILE_LISTS $CURDIR/$file"
fi
done
# FIXME: is this normal ???
@@ -1025,7 +1197,7 @@ function do_pack {
echo "done."
# full path name of different files
- FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
DEP_FILE=$FPNAME.dep
# rebuild dependencies file, first is a diff file
@@ -1083,7 +1255,7 @@ function do_pack {
bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
flr="$(file $REPLY)"
case "$flr" in
- *\ shell\ *)
+ *\ script\ *)
echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
;;
*perl\ commands*)
@@ -1091,13 +1263,13 @@ function do_pack {
get_perl_depend $REPLY
;;
*:\ symbolic\ link*)
- echo "$REPLY $(readlink $REPLY)" >> $DEP_FILE
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
;;
*\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
- echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
+ elf_get_dep $REPLY >> $DEP_FILE
;;
*\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
- echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
+ elf_get_dep $REPLY >> $DEP_FILE
;;
esac
;;
@@ -1113,32 +1285,20 @@ function do_pack {
# we want everything, and directories only if they're empty.
# All this without './' we shouldn't get an empty line since .
# should contain at least what we want to tar !
- $FIND_CMD . | tar --no-recursion -T - -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+ $FIND_CMD . | tar --no-recursion -T - --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
# create shortcuts ".*" for tgz, dep and lst files
for ext in dep lst tgz; do
rm -f $PKGDIR/.$ext
- ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext
done
echo "done."
return 0
}
-# this function sets all needed compiler options
-function set_compiler_options {
- # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
- case "$FLXARCH" in
- i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
- i586) arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
- i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
- i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
- ev[456]*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
- parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
- sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
- sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
- *) arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
- esac
-
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
# Handling of cross-compilers :
# - setting CC will force both HOSTCC and FLXCROSSCC
# - setting HOSTCC will keep it
@@ -1147,25 +1307,31 @@ function set_compiler_options {
if [ -z "$FLX_CROSS_OPT_SET" ]; then
CC=${CC:-gcc}
+ CXX=${CXX:-g++}
AS=${AS:-as}
LD=${LD:-ld}
AR=${AR:-ar}
+ NM=${NM:-nm}
RANLIB=${RANLIB:-ranlib}
STRIP=${STRIP:-strip}
OBJDUMP=${OBJDUMP:-objdump}
HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
HOSTAS=${HOSTAS:-$AS}
HOSTLD=${HOSTLD:-$LD}
HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
HOSTSTRIP=${HOSTSTRIP:-$STRIP}
HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
if [ -n "$FLXCROSS" ]; then
CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ CXX=${FLXCROSS}${CXX} ; CXX=${FLXCROSSCXX:-$CXX}
AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
@@ -1173,10 +1339,28 @@ function set_compiler_options {
# specify that we don't want to do this again
FLX_CROSS_OPT_SET=1
fi
-
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ esac
+
+ # FIXME: this should go into a per-architecture file
case "$FLXARCH" in
*86)
CC=${CC:-gcc}
+ CXX=${CXX:-g++}
FLX_ARCH_CURRENT="$FLXARCH"
FLX_ARCH_COMMON="i586"
FLX_ARCH_SMALL="$basearch"
@@ -1189,15 +1373,16 @@ function set_compiler_options {
GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
- if [ $TESTGCC -gt 0 ] && $CC -falign-loops=0 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
- GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -falign-jumps=0"
- GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -falign-jumps=0 -falign-loops=0 -falign-functions=0"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
fi
- ;;
-
+ ;;
+
parisc*)
CC=${CC:-gcc}
+ CXX=${CXX:-g++}
FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
FLX_ARCH_COMMON="1.0"
FLX_ARCH_SMALL="1.0"
@@ -1208,12 +1393,13 @@ function set_compiler_options {
GCC_CPU_COMMON="-mschedule=7100"
GCC_CPU_SMALL="-mschedule=7100"
GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
- GCC_OPT_FAST="-O2 -falign-jumps=0"
- GCC_OPT_SMALL="-Os -falign-jumps=0 -falign-loops=0 -falign-functions=0"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
;;
sparc*)
CC=${CC:-gcc}
+ CXX=${CXX:-g++}
FLX_ARCH_CURRENT="$FLXARCH"
FLX_ARCH_COMMON="$FLXARCH"
FLX_ARCH_SMALL="$FLXARCH"
@@ -1224,12 +1410,13 @@ function set_compiler_options {
GCC_CPU_COMMON="-mtune=$cpu"
GCC_CPU_SMALL="-mtune=$cpu"
GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
- GCC_OPT_FAST="-O2 -falign-jumps=0"
- GCC_OPT_SMALL="-Os -falign-jumps=0 -falign-loops=0 -falign-functions=0"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
;;
ev[456]*)
CC=${CC:-gcc}
+ CXX=${CXX:-g++}
FLX_ARCH_CURRENT="$FLXARCH"
FLX_ARCH_COMMON="$FLXARCH"
FLX_ARCH_SMALL="$FLXARCH"
@@ -1240,38 +1427,107 @@ function set_compiler_options {
GCC_CPU_COMMON="-mtune=$cpu"
GCC_CPU_SMALL="-mtune=$cpu"
GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
- GCC_OPT_FAST="-O2 -falign-jumps=0"
- GCC_OPT_SMALL="-Os -falign-jumps=0 -falign-loops=0 -falign-functions=0"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
;;
*)
CC=${CC:-gcc}
+ CXX=${CXX:-g++}
FLX_ARCH_CURRENT="$FLXARCH"
FLX_ARCH_COMMON="$FLXARCH"
FLX_ARCH_SMALL="$FLXARCH"
GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
GCC_OPT_FAST="-O2 -malign-jumps=0"
GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
- if [ $TESTGCC -gt 0 ] && $CC -falign-loops=0 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
- GCC_OPT_FAST="-O2 -falign-jumps=0"
- GCC_OPT_SMALL="-Os -falign-jumps=0 -falign-loops=0 -falign-functions=0"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
fi
;;
esac
+ case "$FLXHOSTARCH" in
+ *86)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ parisc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ sparc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ ev[456]*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ *)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
- export CC AS LD AR STRIP OBJDUMP GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC CXX AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+ export HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL
return 0
}
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC CXX LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ HOSTCC HOSTCXX \
+ HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
function usage {
# this is needed to present current options to the user
+ set_cross_environment
set_compiler_options
+ echo "PKG version $PKG_VERSION - Formilux package build utility."
echo "Usage:"
echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
echo
@@ -1313,6 +1569,8 @@ function usage {
echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
echo "GCC_OPT_FAST=$GCC_OPT_FAST"
echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
# Those two are not user-settable anymore
# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
@@ -1359,11 +1617,11 @@ function do_release {
fi
# first, the destination directory must not exist
- if [ -d "$PKGROOT/$EXACTPKG" ]; then
- if [ -e "$PKGROOT/$EXACTPKG/RELEASED" ]; then
+ if [ -d "$PKGROOT/${EXACTPKG##*/}" ]; then
+ if [ -e "$PKGROOT/${EXACTPKG##*/}/RELEASED" ]; then
echo "Error: This package already exists."
else
- echo "Error: The package directory $PKGROOT/$EXACTPKG already exists."
+ echo "Error: The package directory $PKGROOT/${EXACTPKG##*/} already exists."
fi
exit 1
fi
@@ -1375,11 +1633,11 @@ function do_release {
last_pkg=${last_pkg##*released }
fi
- if [ "$last_pkg" != "$EXACTPKG" ]; then
+ if [ "$last_pkg" != "${EXACTPKG##*/}" ]; then
# Let's create a new changelog entry
touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
(echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
- echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo $'\t'"* released ${EXACTPKG##*/}";
echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
fi
@@ -1394,15 +1652,71 @@ function do_release {
echo "Error: cannot move the package to the released directory. Cancelling."
# the mv here fails atomically, so nothing's lost in PKGDIR, but we have
# to clean a possible partial copy
- rm -rf $PKGROOT/$EXACTPKG
+ rm -rf $PKGROOT/${EXACTPKG##*/}
exit 2
fi
- touch $PKGROOT/$EXACTPKG/RELEASED
+ touch $PKGROOT/${EXACTPKG##*/}/RELEASED
return 0
}
+# usage: install-files <owner> <perm> <dest> file...
+#
+function install-files {
+ local owner="$1" ; shift
+ local perm="$1" ; shift
+ local dst="$1" ; shift
+ local file
+
+ [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}"
+ cp -dpfP "$@" "$ROOTDIR/$dst/" && \
+ ( cd "$ROOTDIR/$dst" && chown -h $owner "${@##*/}" && chmod $perm "${@##*/}" )
+
+ [ -n "$FILE_LIST" ] && for file in "$@"; do echo "$dst/$file $owner $perm"; done >> $FILE_LIST
+}
+
+# usage: install-file <owner> <perm> <file> <dest>
+#
+function install-file {
+ local owner="$1" ; shift
+ local perm="$1" ; shift
+ local src="$1" ; shift
+ local dst="$1" ; shift
+
+ [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}"
+ if cp -dpfP "$src" "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst" \
+ && [ ! -L "$ROOTDIR/$dst" ]; then chmod $perm "$ROOTDIR/$dst"; fi
+
+ [ -n "$FILE_LIST" ] && echo $dst $owner $perm >> $FILE_LIST
+}
+
+# usage: install-dir <owner> <perm> <dir>...
+#
+function install-dir {
+ local owner="$1" ; shift
+ local perm="$1" ; shift
+ local dst
+
+ for dst in "$@"; do
+ mkdir -pm $perm "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst"
+ [ -n "$FILE_LIST" ] && echo $dst $owner $perm >> $FILE_LIST
+ done
+}
+
+# usage: install-ln <owner> <target> <dest>
+#
+function install-ln {
+ local owner="$1" ; shift
+ local target="$1" ; shift
+ local dst="$1" ; shift
+
+ [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}"
+ ln -s "$target" "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst"
+ [ -n "$FILE_LIST" ] && echo $dst $owner 000 >> $FILE_LIST
+}
+
+
######
###### here are some functions used only from main
######
@@ -1425,6 +1739,7 @@ release_only=0
force=0
TESTGCC=0
PRINTUSAGE=0
+PRINTENV=0
ARGLIST=( )
ACTION=
CHAINCMD=1
@@ -1439,6 +1754,10 @@ while [ $# -gt 0 ] ; do
--help|-h)
PRINTUSAGE=1
;;
+ --env|-e)
+ PRINTENV=1
+ TESTGCC=1
+ ;;
--rel|-r*)
release_only=1
;;
@@ -1460,6 +1779,7 @@ done
#echo "arglist=${ARGLIST[*]}"
+[ $PRINTENV -gt 0 ] && print_env
[ $PRINTUSAGE -gt 0 ] && usage
[ ${#ARGLIST[*]} -lt 1 ] && usage
@@ -1488,32 +1808,57 @@ while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
CHAINCMD=0
KNOWNCMD=1
get_name ${ARGLIST[0]} %L %P %D
+ [ -d "$PKGDIR" ] || PKGDIR=
;;
patch|unpatch)
CHAINCMD=0
KNOWNCMD=1
- REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
- PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
# get_name %L
;;
compile_only|config|config_only|compile|build)
KNOWNCMD=1
- REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
- PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
TESTGCC=1
# get_name %L
;;
prepack|strip|pack|delpack|release|clean)
KNOWNCMD=1
- REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
- PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
# get_name %L
;;
*)
CHAINCMD=0
KNOWNCMD=0
- REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
- PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
# get_name %L
;;
esac
@@ -1526,27 +1871,28 @@ while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
echo "Error: package name not found."
exit 1
fi
- EXACTPKG=$REPLY
+ EXACTPKG="$PKGDIR/$REPLY"
if [ -z "$PKGDIR" ]; then
- if [ -e "$PKGROOT/$EXACTPKG/build.cfg" ]; then
- PKGDIR=$PKGROOT/$EXACTPKG
+ if [ -e "$PKGROOT/${EXACTPKG##*/}/build.cfg" ]; then
+ PKGDIR="$PKGROOT/${EXACTPKG##*/}"
else
- PKGDIR=$DEVROOT/$EXACTPKG
+ PKGDIR="$DEVROOT/${EXACTPKG##*/}"
fi
fi
- CFGFILE=$PKGDIR/build.cfg
- PKGRADIX=$(get_pkg_radix $EXACTPKG)
- PKGVER=$(get_pkg_ver $EXACTPKG)
- DISTVER=$(get_build_num $EXACTPKG)
- ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
- EXAMPLEDIR=${ROOTDIR}/usr/share/examples
+ CFGFILE="$PKGDIR/build.cfg"
+ PKGRADIX="$(get_pkg_radix ${EXACTPKG##*/})"
+ PKGVER="$(get_pkg_ver ${EXACTPKG##*/})"
+ DISTVER="$(get_build_num ${EXACTPKG##*/})"
+ ROOTDIR="${ROOTDIR:-$CURDIR/${INSTNAME}}"
+ EXAMPLEDIR="${ROOTDIR}/usr/share/examples"
# for compatibility with old functions. Not used anywhere outside this script.
- packver=$EXACTPKG
- pack=$PKGRADIX
+ packver="${EXACTPKG##*/}"
+ pack="$PKGRADIX"
fi
+ set_cross_environment
set_compiler_options
if [ "$ACTION" != "newpkg" ]; then
@@ -1554,10 +1900,10 @@ while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
fi
# FLXMAKE is used for sequential make and FLXPMAKE for parallel make
- FLXMAKE=${FLXMAKE:-make}
- FLXPMAKE=${FLXPMAKE:-$FLXMAKE}
+ FLXMAKE="${FLXMAKE:-make}"
+ FLXPMAKE="${FLXPMAKE:-$FLXMAKE}"
- export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
# echo "ARGLIST=${ARGLIST[*]}"
@@ -1577,415 +1923,3 @@ done
[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
exit 0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-exit 99
-
-###############################################################################################################
-###############################################################################################################
-###############################################################################################################
-###############################################################################################################
-
-
-DEAD CODE BELOW !!!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-function usage {
- echo "Usage: pkg <action> [new_pkg [old_pkg]]"
- echo " action is one of :"
- echo " help : display this help."
- echo " info : get information on current package."
- echo " newpkg : build a more recent .pkg script from an old one."
- echo " cat : display last .pkg file."
- echo " edit : edit last .pkg file."
- echo " patch : apply a list of patches to the directory prior to compile."
- echo " unpatch : revert a list of patches to the directory."
- echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
- echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
- echo " strip : strip binaries in temporary directory"
- echo " pack : strip binaries, then package into $PKGROOT"
- echo " delpack : remove temporary directory"
- echo " clean : execute 'make clean' and remove temporary directory."
- echo " build : execute clean compile prepack pack."
- echo " unpack : extract package into temporary directory"
- echo "Variables are :"
- echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
- echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
- echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
- echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
- echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
- echo "FLXARCH : architecture for package name, <$FLXARCH>"
- echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
- echo "DISTVER : build version (flx.1)"
- exit 1
-}
-
-
-
-
-
-
-
-
-
-for ACTION in ${ARGLIST[*]}; do
-
-# now we will try to identify two packages names :
-# - the EXACT one, deduced from command line, then version symlink, then the
-# directory name ; this one doesn't have to exist to be correct.
-# - the NEAREST one, deduced from the same criterions, with and without
-# versions, and based on EXISTING files only.
-# The NEAREST one will be used as a source, while the EXACT one will be used as
-# a target. When the EXACT one exists, the NEAREST one must obviously be the
-# same.
-
-# EXACTPKG can be specified as an environment variable if needed
-[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
-[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
-[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
-
-if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
- TEMP=$(sortnames $CFGROOT/$EXACTPKG-[0-9]* | tail -1)
- TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG.* | tail -1)}
- TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG-* | tail -1)}
- TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG* | tail -1)}
-# if [ -z "$TEMP" ]; then
-# echo "Cannot find a suitable package for the current directory. Please specify"
-# echo "a correct name on the command line."
-# usage
-# exit 1
-# fi
- [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
- [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
-fi
-
-if [ -z "$(get_build_num $EXACTPKG)" ]; then
- RADIX=$(get_pkg_radix $EXACTPKG)
- TEMP=$(sortnames $CFGROOT/$EXACTPKG-* $CFGROOT/$EXACTPKG $CFGROOT/$RADIX | tail -1)
-
- VER=$(get_pkg_ver $TEMP)
- BUILD=$(get_build_num $TEMP)
- EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
-fi
-
-NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
-NEWPKGVER=$(get_pkg_ver $EXACTPKG)
-NEWDISTVER=$(get_build_num $EXACTPKG)
-NEWDISTVER=${NEWDISTVER:-flx.1}
-EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
-
-trylist=( )
-[ -d "$CFGROOT/$EXACTPKG" -o -f "$CFGROOT/$EXACTPKG.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
-[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
-[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
-trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
-trylist=( ${trylist[*]} $NEWPKGRADIX )
-trylist=( ${trylist[*]} $(basename $(pwd)))
-trylist=( ${trylist[*]} "default")
-
-echo trylist=${trylist[*]}
-
-for NEARESTPKG in ${trylist[*]}; do
- if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
- TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
- TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
- TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
- #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
- [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
- fi
-
- RADIX=$(get_pkg_radix $NEARESTPKG)
- VER=$(get_pkg_ver $NEARESTPKG)
- BUILD=$(get_build_num $NEARESTPKG)
- NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
-
- #### [ "$(get_build_num $NEARESTPKG)" ] &&
-
- [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
-echo NEARESTPKG=$NEARESTPKG
-
- ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
- ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
-done
-
-RADIX=$(get_pkg_radix $NEARESTPKG)
-VER=$(get_pkg_ver $NEARESTPKG)
-BUILD=$(get_build_num $NEARESTPKG)
-NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
-
-echo "EXACTPKG=$EXACTPKG"
-echo "NEARESTPKG=$NEARESTPKG"
-
-# to be removed ## look if there was an argument, in which case we would treat it as a package
-# to be removed ## name (either source or destination, depending on the action). These variables
-# to be removed ## are set :
-# to be removed ## - ARGPKGFULL : full package name with version
-# to be removed ## - ARGPKGRADIX : package radix name (without version)
-# to be removed ## - ARGPKGVER : package version without -flx*
-# to be removed ## - ARGDISTVER : package build version (flx*)
-# to be removed #
-# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
-# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
-# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
-# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
-# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
-# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
-# to be removed # fi
-# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
-# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
-# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
-# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
-# to be removed #fi
-# to be removed #
-# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
-# to be removed #
-# to be removed #if [ -L .flxver ]; then
-# to be removed # PKGFULL=$(readlink .flxver)
-# to be removed #else
-# to be removed # PKGFULL=$(basename $(pwd))
-# to be removed #fi
-# to be removed #
-# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
-# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
-# to be removed #
-# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
-# to be removed # DISTVER=$(get_build_num $PKGFULL)
-# to be removed #fi
-# to be removed #
-# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
-# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
-# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
-# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
-# to be removed #
-# to be removed #
-# to be removed #
-# to be removed ## now process the destination parameters
-# to be removed #
-# to be removed #if [ -L .flxver ]; then
-# to be removed # NEWPKGFULL=$(readlink .flxver)
-# to be removed #else
-# to be removed # NEWPKGFULL=$(basename $(pwd))
-# to be removed #fi
-# to be removed #
-# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
-# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
-# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
-# to be removed #
-# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
-# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
-# to be removed #fi
-# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
-# to be removed #
-# to be removed ## recompute the new package version
-# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
-# to be removed #
-
-
-# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
-# directory name for the new package. If it cannot be found, all actions except
-# info and newpkg will fail. So we have to do a newpkg before using a new dir.
-
-if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
- echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
- exit 1
-fi
-
-# source configuration
-ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
-
-
-CURPKG=$NEARESTPKG
-PKGRADIX=$(get_pkg_radix $NEARESTPKG)
-PKGVER=$(get_pkg_ver $NEARESTPKG)
-if echo $NEARESTPKG | grep -q -- "-flx\." ; then
- DISTVER=$(get_build_num $NEARESTPKG)
- NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
-else
- DISTVER=
- NEARESTPKG=$PKGRADIX-$PKGVER
-fi
-
-CFGDIR=$CFGROOT/$CURPKG
-CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
-
-echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
-
-exit 0
-
-
-
-if [ -n "$CFGFILE" ]; then
- CFGDIR=$NEWCFGROOT/$NEWBASECFG
- . $CFGFILE
-else
- #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
- #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
- #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
- #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
- CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
- CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
- CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
- CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
-
- # to be completed
-
- if [ -z "$CFGFILE" ]; then
- echo "CFGFILE not found. Cannot continue." >&2
- exit 1
- fi
-
- if [ -d $CFGFILE ]; then
- CFGROOT=`dirname $CFGFILE`
- CFGDIR=`basename $CFGFILE`-pkg
- CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
- else
- CFGROOT=`dirname $CFGFILE`
- CFGDIR=`basename $CFGFILE`-pkg
- CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
- if [ ! -e $CFGROOT/$CFGDIR ]; then
- echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
- mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
- if [ $? != 0 ]; then
- echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
- exit 1
- else
- echo "Done !"
- fi
- fi
- fi
-
- if [ -e "$CFGFILE" ]; then
- . $CFGFILE
- else
- echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
- exit 1
- fi
- fi
-
- if [ -z "$DISTVER" ]; then
- if echo $CFGFILE | grep -q -- "-flx\." ; then
- DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
- else
- DISTVER='flx.1'
- fi
- fi
-
- echo $packver | grep -q -- "-flx\."
- if [ $? != 0 ] ; then
- packver=$packver-$DISTVER
- fi
-
- echo $packver | grep -q -- "-$FLXARCH\$"
- if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
-
- prefix=${packver%%[._-][0-9]*}
- suffix=${packver#$prefix[._-]}
- PKGVER=${suffix%-flx*}
- PKGRADIX=$prefix
- #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
- if [ -z "$DISTVER" ]; then
- DISTVER=${suffix#$PKGVER-}
- if [ "$DISTVER" = "$PKGVER" ]; then
- DISTVER="flx.1"
- else
- DISTVER=${DISTVER%-*}
- fi
- fi
-
- case "$FLXARCH" in
- i686) arch=i686 cpu=i686 basearch=i386 ;;
- i486) arch=i486 cpu=i486 basearch=i386 ;;
- i386) arch=i386 cpu=i386 basearch=i386 ;;
- *) arch=i586 cpu=i686 basearch=i386 ;;
- esac
-
- if [ -z "$FLXMAKE" ]; then
- FLXMAKE=make
- fi
-
-
- if [ -z "${PATCH_LIST}" ]; then
- PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
- if [ ! -e ${PATCH_LIST} ]; then
- unset PATCH_LIST
- fi
- fi
-
- export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
-
- declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
- [ $? != 0 ] && exit $?
- declare -f do_$ACTION > /dev/null && ( do_$ACTION )
- [ $? != 0 ] && exit $?
- declare -f post_$ACTION > /dev/null && ( post_$ACTION )
- [ $? != 0 ] && exit $?
- fi
-fi
-
diff --git a/scripts/pkg-0.5.3 b/scripts/pkg-0.5.3
new file mode 100755
index 0000000..7eb096a
--- /dev/null
+++ b/scripts/pkg-0.5.3
@@ -0,0 +1,1994 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.5.3 - 2005-05-21
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXARCH=${FLXARCH:-$(uname -m)}
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s/$VERSION/\1|/" \
+ -e "s/^$FIELD|$VERSION/\1|\2|/" \
+ -e "s/^$FIELD|$FIELD|$FIELD$/\1|\2|\3~\1\2\3/" \
+ -e "s/^[^|]*|[^|]*$//"))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The result is returned in REPLY.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i
+
+ REPLY=
+ for pattern in $*; do
+ if [ "$pattern" = "%P" ]; then
+ pattern=$(basename $(pwd))
+ elif [ "$pattern" = "%L" ]; then
+ if [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern=$(readlink ${LINKNAME})
+ REPLY=$(basename $pattern)
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY=${sort_list[0]}
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $(pwd))
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "$PKGROOT/${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+# sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '$EXACTPKG' :"
+
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY $(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $(pwd)/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY $(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ echo "$REPLY $(ldd $REPLY 2>/dev/null | grep -v 'statically linked' | awk '{print $1}' | tr '\012' ' ')" >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i586) arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ ev[456]*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ *) arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ esac
+
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export CC AS LD AR STRIP OBJDUMP GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+
+ return 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_compiler_options
+
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/$EXACTPKG" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/$EXACTPKG already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/$EXACTPKG
+ exit 2
+ fi
+
+ touch $PKGROOT/$EXACTPKG/RELEASED
+
+ return 0
+}
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG=$REPLY
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/build.cfg" ]; then
+ PKGDIR=$PKGROOT/$EXACTPKG
+ else
+ PKGDIR=$DEVROOT/$EXACTPKG
+ fi
+ fi
+ CFGFILE=$PKGDIR/build.cfg
+ PKGRADIX=$(get_pkg_radix $EXACTPKG)
+ PKGVER=$(get_pkg_ver $EXACTPKG)
+ DISTVER=$(get_build_num $EXACTPKG)
+ ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+ EXAMPLEDIR=${ROOTDIR}/usr/share/examples
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver=$EXACTPKG
+ pack=$PKGRADIX
+ fi
+
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE=${FLXMAKE:-make}
+ FLXPMAKE=${FLXPMAKE:-$FLXMAKE}
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+exit 99
+
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+
+
+DEAD CODE BELOW !!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function usage {
+ echo "Usage: pkg <action> [new_pkg [old_pkg]]"
+ echo " action is one of :"
+ echo " help : display this help."
+ echo " info : get information on current package."
+ echo " newpkg : build a more recent .pkg script from an old one."
+ echo " cat : display last .pkg file."
+ echo " edit : edit last .pkg file."
+ echo " patch : apply a list of patches to the directory prior to compile."
+ echo " unpatch : revert a list of patches to the directory."
+ echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " strip : strip binaries in temporary directory"
+ echo " pack : strip binaries, then package into $PKGROOT"
+ echo " delpack : remove temporary directory"
+ echo " clean : execute 'make clean' and remove temporary directory."
+ echo " build : execute clean compile prepack pack."
+ echo " unpack : extract package into temporary directory"
+ echo "Variables are :"
+ echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
+ echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+ echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
+ echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
+ echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
+ echo "FLXARCH : architecture for package name, <$FLXARCH>"
+ echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
+ echo "DISTVER : build version (flx.1)"
+ exit 1
+}
+
+
+
+
+
+
+
+
+
+for ACTION in ${ARGLIST[*]}; do
+
+# now we will try to identify two packages names :
+# - the EXACT one, deduced from command line, then version symlink, then the
+# directory name ; this one doesn't have to exist to be correct.
+# - the NEAREST one, deduced from the same criterions, with and without
+# versions, and based on EXISTING files only.
+# The NEAREST one will be used as a source, while the EXACT one will be used as
+# a target. When the EXACT one exists, the NEAREST one must obviously be the
+# same.
+
+# EXACTPKG can be specified as an environment variable if needed
+[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
+[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
+[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
+
+if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG-* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG* | tail -1)}
+# if [ -z "$TEMP" ]; then
+# echo "Cannot find a suitable package for the current directory. Please specify"
+# echo "a correct name on the command line."
+# usage
+# exit 1
+# fi
+ [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
+ [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
+fi
+
+if [ -z "$(get_build_num $EXACTPKG)" ]; then
+ RADIX=$(get_pkg_radix $EXACTPKG)
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-* $CFGROOT/$EXACTPKG $CFGROOT/$RADIX | tail -1)
+
+ VER=$(get_pkg_ver $TEMP)
+ BUILD=$(get_build_num $TEMP)
+ EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
+fi
+
+NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
+NEWPKGVER=$(get_pkg_ver $EXACTPKG)
+NEWDISTVER=$(get_build_num $EXACTPKG)
+NEWDISTVER=${NEWDISTVER:-flx.1}
+EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
+
+trylist=( )
+[ -d "$CFGROOT/$EXACTPKG" -o -f "$CFGROOT/$EXACTPKG.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
+[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
+[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
+trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
+trylist=( ${trylist[*]} $NEWPKGRADIX )
+trylist=( ${trylist[*]} $(basename $(pwd)))
+trylist=( ${trylist[*]} "default")
+
+echo trylist=${trylist[*]}
+
+for NEARESTPKG in ${trylist[*]}; do
+ if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
+ #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
+ [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
+ fi
+
+ RADIX=$(get_pkg_radix $NEARESTPKG)
+ VER=$(get_pkg_ver $NEARESTPKG)
+ BUILD=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+ #### [ "$(get_build_num $NEARESTPKG)" ] &&
+
+ [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
+echo NEARESTPKG=$NEARESTPKG
+
+ ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
+ ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
+done
+
+RADIX=$(get_pkg_radix $NEARESTPKG)
+VER=$(get_pkg_ver $NEARESTPKG)
+BUILD=$(get_build_num $NEARESTPKG)
+NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+echo "EXACTPKG=$EXACTPKG"
+echo "NEARESTPKG=$NEARESTPKG"
+
+# to be removed ## look if there was an argument, in which case we would treat it as a package
+# to be removed ## name (either source or destination, depending on the action). These variables
+# to be removed ## are set :
+# to be removed ## - ARGPKGFULL : full package name with version
+# to be removed ## - ARGPKGRADIX : package radix name (without version)
+# to be removed ## - ARGPKGVER : package version without -flx*
+# to be removed ## - ARGDISTVER : package build version (flx*)
+# to be removed #
+# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
+# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
+# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
+# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
+# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
+# to be removed # fi
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
+# to be removed #fi
+# to be removed #
+# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # PKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # PKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
+# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
+# to be removed #
+# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
+# to be removed # DISTVER=$(get_build_num $PKGFULL)
+# to be removed #fi
+# to be removed #
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
+# to be removed #
+# to be removed #
+# to be removed #
+# to be removed ## now process the destination parameters
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # NEWPKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # NEWPKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
+# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
+# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
+# to be removed #
+# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
+# to be removed #fi
+# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
+# to be removed #
+# to be removed ## recompute the new package version
+# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
+# to be removed #
+
+
+# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
+# directory name for the new package. If it cannot be found, all actions except
+# info and newpkg will fail. So we have to do a newpkg before using a new dir.
+
+if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
+ echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
+ exit 1
+fi
+
+# source configuration
+ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+
+
+CURPKG=$NEARESTPKG
+PKGRADIX=$(get_pkg_radix $NEARESTPKG)
+PKGVER=$(get_pkg_ver $NEARESTPKG)
+if echo $NEARESTPKG | grep -q -- "-flx\." ; then
+ DISTVER=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
+else
+ DISTVER=
+ NEARESTPKG=$PKGRADIX-$PKGVER
+fi
+
+CFGDIR=$CFGROOT/$CURPKG
+CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
+
+echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
+
+exit 0
+
+
+
+if [ -n "$CFGFILE" ]; then
+ CFGDIR=$NEWCFGROOT/$NEWBASECFG
+ . $CFGFILE
+else
+ #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+
+ # to be completed
+
+ if [ -z "$CFGFILE" ]; then
+ echo "CFGFILE not found. Cannot continue." >&2
+ exit 1
+ fi
+
+ if [ -d $CFGFILE ]; then
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ else
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ if [ ! -e $CFGROOT/$CFGDIR ]; then
+ echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
+ mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
+ if [ $? != 0 ]; then
+ echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
+ exit 1
+ else
+ echo "Done !"
+ fi
+ fi
+ fi
+
+ if [ -e "$CFGFILE" ]; then
+ . $CFGFILE
+ else
+ echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
+ exit 1
+ fi
+ fi
+
+ if [ -z "$DISTVER" ]; then
+ if echo $CFGFILE | grep -q -- "-flx\." ; then
+ DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
+ else
+ DISTVER='flx.1'
+ fi
+ fi
+
+ echo $packver | grep -q -- "-flx\."
+ if [ $? != 0 ] ; then
+ packver=$packver-$DISTVER
+ fi
+
+ echo $packver | grep -q -- "-$FLXARCH\$"
+ if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
+
+ prefix=${packver%%[._-][0-9]*}
+ suffix=${packver#$prefix[._-]}
+ PKGVER=${suffix%-flx*}
+ PKGRADIX=$prefix
+ #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
+ if [ -z "$DISTVER" ]; then
+ DISTVER=${suffix#$PKGVER-}
+ if [ "$DISTVER" = "$PKGVER" ]; then
+ DISTVER="flx.1"
+ else
+ DISTVER=${DISTVER%-*}
+ fi
+ fi
+
+ case "$FLXARCH" in
+ i686) arch=i686 cpu=i686 basearch=i386 ;;
+ i486) arch=i486 cpu=i486 basearch=i386 ;;
+ i386) arch=i386 cpu=i386 basearch=i386 ;;
+ *) arch=i586 cpu=i686 basearch=i386 ;;
+ esac
+
+ if [ -z "$FLXMAKE" ]; then
+ FLXMAKE=make
+ fi
+
+
+ if [ -z "${PATCH_LIST}" ]; then
+ PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
+ if [ ! -e ${PATCH_LIST} ]; then
+ unset PATCH_LIST
+ fi
+ fi
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+ declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f do_$ACTION > /dev/null && ( do_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f post_$ACTION > /dev/null && ( post_$ACTION )
+ [ $? != 0 ] && exit $?
+ fi
+fi
+
diff --git a/scripts/pkg-0.5.4 b/scripts/pkg-0.5.4
new file mode 100755
index 0000000..ec13c3d
--- /dev/null
+++ b/scripts/pkg-0.5.4
@@ -0,0 +1,2035 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.5.4 - 2005-08-12
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s/$VERSION/\1|/" \
+ -e "s/^$FIELD|$VERSION/\1|\2|/" \
+ -e "s/^$FIELD|$FIELD|$FIELD$/\1|\2|\3~\1\2\3/" \
+ -e "s/^[^|]*|[^|]*$//"))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The result is returned in REPLY.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i
+
+ REPLY=
+ for pattern in $*; do
+ if [ "$pattern" = "%P" ]; then
+ pattern=$(basename $(pwd))
+ elif [ "$pattern" = "%L" ]; then
+ if [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern=$(readlink ${LINKNAME})
+ REPLY=$(basename $pattern)
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY=${sort_list[0]}
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $(pwd))
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "$PKGROOT/${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+# sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '$EXACTPKG' :"
+
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY $(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ echo "$REPLY $(objdump -p $REPLY 2>/dev/null | grep ' NEEDED ' | awk '{print $2}' | tr '\012' ' ')" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ echo "$REPLY $(objdump -p $REPLY 2>/dev/null | grep ' NEEDED ' | awk '{print $2}' | tr '\012' ' ')" >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $(pwd)/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY $(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ echo "$REPLY $(objdump -p $REPLY 2>/dev/null | grep ' NEEDED ' | awk '{print $2}' | tr '\012' ' ')" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ echo "$REPLY $(objdump -p $REPLY 2>/dev/null | grep ' NEEDED ' | awk '{print $2}' | tr '\012' ' ')" >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i586) arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ ev[456]*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ *) arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ esac
+
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+
+ return 0
+}
+
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_cross_environment
+ set_compiler_options
+
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/$EXACTPKG" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/$EXACTPKG already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/$EXACTPKG
+ exit 2
+ fi
+
+ touch $PKGROOT/$EXACTPKG/RELEASED
+
+ return 0
+}
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+PRINTENV=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --env|-e)
+ PRINTENV=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTENV -gt 0 ] && print_env
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG=$REPLY
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/build.cfg" ]; then
+ PKGDIR=$PKGROOT/$EXACTPKG
+ else
+ PKGDIR=$DEVROOT/$EXACTPKG
+ fi
+ fi
+ CFGFILE=$PKGDIR/build.cfg
+ PKGRADIX=$(get_pkg_radix $EXACTPKG)
+ PKGVER=$(get_pkg_ver $EXACTPKG)
+ DISTVER=$(get_build_num $EXACTPKG)
+ ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+ EXAMPLEDIR=${ROOTDIR}/usr/share/examples
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver=$EXACTPKG
+ pack=$PKGRADIX
+ fi
+
+ set_cross_environment
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE=${FLXMAKE:-make}
+ FLXPMAKE=${FLXPMAKE:-$FLXMAKE}
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+exit 99
+
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+
+
+DEAD CODE BELOW !!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function usage {
+ echo "Usage: pkg <action> [new_pkg [old_pkg]]"
+ echo " action is one of :"
+ echo " help : display this help."
+ echo " info : get information on current package."
+ echo " newpkg : build a more recent .pkg script from an old one."
+ echo " cat : display last .pkg file."
+ echo " edit : edit last .pkg file."
+ echo " patch : apply a list of patches to the directory prior to compile."
+ echo " unpatch : revert a list of patches to the directory."
+ echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " strip : strip binaries in temporary directory"
+ echo " pack : strip binaries, then package into $PKGROOT"
+ echo " delpack : remove temporary directory"
+ echo " clean : execute 'make clean' and remove temporary directory."
+ echo " build : execute clean compile prepack pack."
+ echo " unpack : extract package into temporary directory"
+ echo "Variables are :"
+ echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
+ echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+ echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
+ echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
+ echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
+ echo "FLXARCH : architecture for package name, <$FLXARCH>"
+ echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
+ echo "DISTVER : build version (flx.1)"
+ exit 1
+}
+
+
+
+
+
+
+
+
+
+for ACTION in ${ARGLIST[*]}; do
+
+# now we will try to identify two packages names :
+# - the EXACT one, deduced from command line, then version symlink, then the
+# directory name ; this one doesn't have to exist to be correct.
+# - the NEAREST one, deduced from the same criterions, with and without
+# versions, and based on EXISTING files only.
+# The NEAREST one will be used as a source, while the EXACT one will be used as
+# a target. When the EXACT one exists, the NEAREST one must obviously be the
+# same.
+
+# EXACTPKG can be specified as an environment variable if needed
+[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
+[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
+[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
+
+if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG-* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG* | tail -1)}
+# if [ -z "$TEMP" ]; then
+# echo "Cannot find a suitable package for the current directory. Please specify"
+# echo "a correct name on the command line."
+# usage
+# exit 1
+# fi
+ [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
+ [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
+fi
+
+if [ -z "$(get_build_num $EXACTPKG)" ]; then
+ RADIX=$(get_pkg_radix $EXACTPKG)
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-* $CFGROOT/$EXACTPKG $CFGROOT/$RADIX | tail -1)
+
+ VER=$(get_pkg_ver $TEMP)
+ BUILD=$(get_build_num $TEMP)
+ EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
+fi
+
+NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
+NEWPKGVER=$(get_pkg_ver $EXACTPKG)
+NEWDISTVER=$(get_build_num $EXACTPKG)
+NEWDISTVER=${NEWDISTVER:-flx.1}
+EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
+
+trylist=( )
+[ -d "$CFGROOT/$EXACTPKG" -o -f "$CFGROOT/$EXACTPKG.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
+[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
+[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
+trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
+trylist=( ${trylist[*]} $NEWPKGRADIX )
+trylist=( ${trylist[*]} $(basename $(pwd)))
+trylist=( ${trylist[*]} "default")
+
+echo trylist=${trylist[*]}
+
+for NEARESTPKG in ${trylist[*]}; do
+ if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
+ #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
+ [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
+ fi
+
+ RADIX=$(get_pkg_radix $NEARESTPKG)
+ VER=$(get_pkg_ver $NEARESTPKG)
+ BUILD=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+ #### [ "$(get_build_num $NEARESTPKG)" ] &&
+
+ [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
+echo NEARESTPKG=$NEARESTPKG
+
+ ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
+ ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
+done
+
+RADIX=$(get_pkg_radix $NEARESTPKG)
+VER=$(get_pkg_ver $NEARESTPKG)
+BUILD=$(get_build_num $NEARESTPKG)
+NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+echo "EXACTPKG=$EXACTPKG"
+echo "NEARESTPKG=$NEARESTPKG"
+
+# to be removed ## look if there was an argument, in which case we would treat it as a package
+# to be removed ## name (either source or destination, depending on the action). These variables
+# to be removed ## are set :
+# to be removed ## - ARGPKGFULL : full package name with version
+# to be removed ## - ARGPKGRADIX : package radix name (without version)
+# to be removed ## - ARGPKGVER : package version without -flx*
+# to be removed ## - ARGDISTVER : package build version (flx*)
+# to be removed #
+# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
+# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
+# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
+# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
+# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
+# to be removed # fi
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
+# to be removed #fi
+# to be removed #
+# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # PKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # PKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
+# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
+# to be removed #
+# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
+# to be removed # DISTVER=$(get_build_num $PKGFULL)
+# to be removed #fi
+# to be removed #
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
+# to be removed #
+# to be removed #
+# to be removed #
+# to be removed ## now process the destination parameters
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # NEWPKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # NEWPKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
+# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
+# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
+# to be removed #
+# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
+# to be removed #fi
+# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
+# to be removed #
+# to be removed ## recompute the new package version
+# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
+# to be removed #
+
+
+# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
+# directory name for the new package. If it cannot be found, all actions except
+# info and newpkg will fail. So we have to do a newpkg before using a new dir.
+
+if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
+ echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
+ exit 1
+fi
+
+# source configuration
+ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+
+
+CURPKG=$NEARESTPKG
+PKGRADIX=$(get_pkg_radix $NEARESTPKG)
+PKGVER=$(get_pkg_ver $NEARESTPKG)
+if echo $NEARESTPKG | grep -q -- "-flx\." ; then
+ DISTVER=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
+else
+ DISTVER=
+ NEARESTPKG=$PKGRADIX-$PKGVER
+fi
+
+CFGDIR=$CFGROOT/$CURPKG
+CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
+
+echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
+
+exit 0
+
+
+
+if [ -n "$CFGFILE" ]; then
+ CFGDIR=$NEWCFGROOT/$NEWBASECFG
+ . $CFGFILE
+else
+ #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+
+ # to be completed
+
+ if [ -z "$CFGFILE" ]; then
+ echo "CFGFILE not found. Cannot continue." >&2
+ exit 1
+ fi
+
+ if [ -d $CFGFILE ]; then
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ else
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ if [ ! -e $CFGROOT/$CFGDIR ]; then
+ echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
+ mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
+ if [ $? != 0 ]; then
+ echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
+ exit 1
+ else
+ echo "Done !"
+ fi
+ fi
+ fi
+
+ if [ -e "$CFGFILE" ]; then
+ . $CFGFILE
+ else
+ echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
+ exit 1
+ fi
+ fi
+
+ if [ -z "$DISTVER" ]; then
+ if echo $CFGFILE | grep -q -- "-flx\." ; then
+ DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
+ else
+ DISTVER='flx.1'
+ fi
+ fi
+
+ echo $packver | grep -q -- "-flx\."
+ if [ $? != 0 ] ; then
+ packver=$packver-$DISTVER
+ fi
+
+ echo $packver | grep -q -- "-$FLXARCH\$"
+ if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
+
+ prefix=${packver%%[._-][0-9]*}
+ suffix=${packver#$prefix[._-]}
+ PKGVER=${suffix%-flx*}
+ PKGRADIX=$prefix
+ #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
+ if [ -z "$DISTVER" ]; then
+ DISTVER=${suffix#$PKGVER-}
+ if [ "$DISTVER" = "$PKGVER" ]; then
+ DISTVER="flx.1"
+ else
+ DISTVER=${DISTVER%-*}
+ fi
+ fi
+
+ case "$FLXARCH" in
+ i686) arch=i686 cpu=i686 basearch=i386 ;;
+ i486) arch=i486 cpu=i486 basearch=i386 ;;
+ i386) arch=i386 cpu=i386 basearch=i386 ;;
+ *) arch=i586 cpu=i686 basearch=i386 ;;
+ esac
+
+ if [ -z "$FLXMAKE" ]; then
+ FLXMAKE=make
+ fi
+
+
+ if [ -z "${PATCH_LIST}" ]; then
+ PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
+ if [ ! -e ${PATCH_LIST} ]; then
+ unset PATCH_LIST
+ fi
+ fi
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+ declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f do_$ACTION > /dev/null && ( do_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f post_$ACTION > /dev/null && ( post_$ACTION )
+ [ $? != 0 ] && exit $?
+ fi
+fi
+
diff --git a/scripts/pkg-0.5.5 b/scripts/pkg-0.5.5
new file mode 100755
index 0000000..6fab71c
--- /dev/null
+++ b/scripts/pkg-0.5.5
@@ -0,0 +1,2135 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.5.5 - 2005-08-12
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+# resolves a symlink to an absolute location.
+# usage: resolve_link <link_dir> <link_pointer>
+function resolve_link {
+ # prints $1 if $2 is empty, and prints $2 if it starts with a '/'.
+ if [ -z "$2" ]; then
+ dir="$1"
+ elif [ -z "${2##/*}" ]; then
+ dir="$2"
+ else
+ dir="$1/$2"
+ fi
+
+ # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right,
+ # then enclose with '/'
+ while [ -n "$dir" ]; do
+ if [ -z "${dir##./*}" ]; then dir="${dir#./}"
+ elif [ -z "${dir##/*}" ]; then dir="${dir#/}"
+ elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}"
+ elif [ -z "${dir%%*/}" ]; then dir="${dir%/}"
+ elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}"
+ elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}"
+ else
+ dir="/$dir/"
+ break;
+ fi
+ done
+
+ # now resolve '/../' from left to right only.
+ while [ -z "${dir##*/../*}" ]; do
+ # if dir goes past root, we must truncate it
+ if [ -z "${dir##/../*}" ]; then
+ dir="/${dir##/../}"
+ else
+ # turn all '/x/../' into '/'
+ odir="$dir"
+ dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')"
+ [ "$dir" = "$odir" ] && break
+ fi
+ done
+
+ [ "$dir" = "/" ] || dir="${dir#/}"
+ [ "$dir" = "/" ] || dir="${dir%/}"
+ echo "$dir"
+}
+
+# this function analyses an ELF executable and prints its name along with some
+# informations such as :
+# %N:soname : for libraries, their soname
+# %D:libname : library it depends on (their soname)
+# %P:provide : feature provided by a library, in the form soname/version
+# %R:require : required feature, in the for soname/version
+function elf_get_dep {
+ local elf
+ for elf in "$@"; do
+ $OBJDUMP -p "$elf" | (
+ soname_str=""
+ soname=""
+ needed=""
+ provide=""
+ require=""
+ curreq=""
+ section=""
+ while read; do
+ case "$REPLY" in
+ Dynamic\ Section*)
+ section="dynamic" ;;
+ Version\ defin*)
+ section="definitions" ;;
+ Version\ Refer*)
+ section="references" ;;
+ *)
+ set -- $REPLY
+ if [ "$section" = "dynamic" ]; then
+ if [ "$1" = "NEEDED" ]; then
+ needed="${needed:+$needed }%D:$2"
+ elif [ "$1" = "SONAME" ]; then
+ soname="$2"
+ soname_str="${soname_str:+$soname_str }%N:$2"
+ fi
+ elif [ "$section" = "definitions" ]; then
+ if [ "$#" = "4" -a "$2" = "0x00" ]; then
+ provide="${provide:+$provide }%P:$soname/$4"
+ fi
+ elif [ "$section" = "references" ]; then
+ if [ "$#" = "3" -a "$1" = "required" ]; then
+ curreq="${3%:}"
+ elif [ "$#" = "4" ]; then
+ require="${require:+$require }%R:$curreq/$4"
+ fi
+ fi
+ ;;
+ esac
+ done
+ echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}"
+ )
+ done
+ return 0
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s/$VERSION/\1|/" \
+ -e "s/^$FIELD|$VERSION/\1|\2|/" \
+ -e "s/^$FIELD|$FIELD|$FIELD$/\1|\2|\3~\1\2\3/" \
+ -e "s/^[^|]*|[^|]*$//"))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The result is returned in REPLY.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i
+
+ REPLY=
+ for pattern in $*; do
+ if [ "$pattern" = "%P" ]; then
+ pattern=$(basename $(pwd))
+ elif [ "$pattern" = "%L" ]; then
+ if [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern=$(readlink ${LINKNAME})
+ REPLY=$(basename $pattern)
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY=${sort_list[0]}
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $(pwd))
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "$PKGROOT/${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+# sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '$EXACTPKG' :"
+
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $(pwd)/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ esac
+
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+
+ return 0
+}
+
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_cross_environment
+ set_compiler_options
+
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/$EXACTPKG" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/$EXACTPKG already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/$EXACTPKG
+ exit 2
+ fi
+
+ touch $PKGROOT/$EXACTPKG/RELEASED
+
+ return 0
+}
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+PRINTENV=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --env|-e)
+ PRINTENV=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTENV -gt 0 ] && print_env
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG=$REPLY
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/build.cfg" ]; then
+ PKGDIR=$PKGROOT/$EXACTPKG
+ else
+ PKGDIR=$DEVROOT/$EXACTPKG
+ fi
+ fi
+ CFGFILE=$PKGDIR/build.cfg
+ PKGRADIX=$(get_pkg_radix $EXACTPKG)
+ PKGVER=$(get_pkg_ver $EXACTPKG)
+ DISTVER=$(get_build_num $EXACTPKG)
+ ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+ EXAMPLEDIR=${ROOTDIR}/usr/share/examples
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver=$EXACTPKG
+ pack=$PKGRADIX
+ fi
+
+ set_cross_environment
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE=${FLXMAKE:-make}
+ FLXPMAKE=${FLXPMAKE:-$FLXMAKE}
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+exit 99
+
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+
+
+DEAD CODE BELOW !!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function usage {
+ echo "Usage: pkg <action> [new_pkg [old_pkg]]"
+ echo " action is one of :"
+ echo " help : display this help."
+ echo " info : get information on current package."
+ echo " newpkg : build a more recent .pkg script from an old one."
+ echo " cat : display last .pkg file."
+ echo " edit : edit last .pkg file."
+ echo " patch : apply a list of patches to the directory prior to compile."
+ echo " unpatch : revert a list of patches to the directory."
+ echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " strip : strip binaries in temporary directory"
+ echo " pack : strip binaries, then package into $PKGROOT"
+ echo " delpack : remove temporary directory"
+ echo " clean : execute 'make clean' and remove temporary directory."
+ echo " build : execute clean compile prepack pack."
+ echo " unpack : extract package into temporary directory"
+ echo "Variables are :"
+ echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
+ echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+ echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
+ echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
+ echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
+ echo "FLXARCH : architecture for package name, <$FLXARCH>"
+ echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
+ echo "DISTVER : build version (flx.1)"
+ exit 1
+}
+
+
+
+
+
+
+
+
+
+for ACTION in ${ARGLIST[*]}; do
+
+# now we will try to identify two packages names :
+# - the EXACT one, deduced from command line, then version symlink, then the
+# directory name ; this one doesn't have to exist to be correct.
+# - the NEAREST one, deduced from the same criterions, with and without
+# versions, and based on EXISTING files only.
+# The NEAREST one will be used as a source, while the EXACT one will be used as
+# a target. When the EXACT one exists, the NEAREST one must obviously be the
+# same.
+
+# EXACTPKG can be specified as an environment variable if needed
+[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
+[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
+[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
+
+if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG-* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG* | tail -1)}
+# if [ -z "$TEMP" ]; then
+# echo "Cannot find a suitable package for the current directory. Please specify"
+# echo "a correct name on the command line."
+# usage
+# exit 1
+# fi
+ [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
+ [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
+fi
+
+if [ -z "$(get_build_num $EXACTPKG)" ]; then
+ RADIX=$(get_pkg_radix $EXACTPKG)
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-* $CFGROOT/$EXACTPKG $CFGROOT/$RADIX | tail -1)
+
+ VER=$(get_pkg_ver $TEMP)
+ BUILD=$(get_build_num $TEMP)
+ EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
+fi
+
+NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
+NEWPKGVER=$(get_pkg_ver $EXACTPKG)
+NEWDISTVER=$(get_build_num $EXACTPKG)
+NEWDISTVER=${NEWDISTVER:-flx.1}
+EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
+
+trylist=( )
+[ -d "$CFGROOT/$EXACTPKG" -o -f "$CFGROOT/$EXACTPKG.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
+[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
+[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
+trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
+trylist=( ${trylist[*]} $NEWPKGRADIX )
+trylist=( ${trylist[*]} $(basename $(pwd)))
+trylist=( ${trylist[*]} "default")
+
+echo trylist=${trylist[*]}
+
+for NEARESTPKG in ${trylist[*]}; do
+ if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
+ #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
+ [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
+ fi
+
+ RADIX=$(get_pkg_radix $NEARESTPKG)
+ VER=$(get_pkg_ver $NEARESTPKG)
+ BUILD=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+ #### [ "$(get_build_num $NEARESTPKG)" ] &&
+
+ [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
+echo NEARESTPKG=$NEARESTPKG
+
+ ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
+ ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
+done
+
+RADIX=$(get_pkg_radix $NEARESTPKG)
+VER=$(get_pkg_ver $NEARESTPKG)
+BUILD=$(get_build_num $NEARESTPKG)
+NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+echo "EXACTPKG=$EXACTPKG"
+echo "NEARESTPKG=$NEARESTPKG"
+
+# to be removed ## look if there was an argument, in which case we would treat it as a package
+# to be removed ## name (either source or destination, depending on the action). These variables
+# to be removed ## are set :
+# to be removed ## - ARGPKGFULL : full package name with version
+# to be removed ## - ARGPKGRADIX : package radix name (without version)
+# to be removed ## - ARGPKGVER : package version without -flx*
+# to be removed ## - ARGDISTVER : package build version (flx*)
+# to be removed #
+# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
+# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
+# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
+# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
+# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
+# to be removed # fi
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
+# to be removed #fi
+# to be removed #
+# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # PKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # PKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
+# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
+# to be removed #
+# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
+# to be removed # DISTVER=$(get_build_num $PKGFULL)
+# to be removed #fi
+# to be removed #
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
+# to be removed #
+# to be removed #
+# to be removed #
+# to be removed ## now process the destination parameters
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # NEWPKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # NEWPKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
+# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
+# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
+# to be removed #
+# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
+# to be removed #fi
+# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
+# to be removed #
+# to be removed ## recompute the new package version
+# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
+# to be removed #
+
+
+# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
+# directory name for the new package. If it cannot be found, all actions except
+# info and newpkg will fail. So we have to do a newpkg before using a new dir.
+
+if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
+ echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
+ exit 1
+fi
+
+# source configuration
+ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+
+
+CURPKG=$NEARESTPKG
+PKGRADIX=$(get_pkg_radix $NEARESTPKG)
+PKGVER=$(get_pkg_ver $NEARESTPKG)
+if echo $NEARESTPKG | grep -q -- "-flx\." ; then
+ DISTVER=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
+else
+ DISTVER=
+ NEARESTPKG=$PKGRADIX-$PKGVER
+fi
+
+CFGDIR=$CFGROOT/$CURPKG
+CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
+
+echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
+
+exit 0
+
+
+
+if [ -n "$CFGFILE" ]; then
+ CFGDIR=$NEWCFGROOT/$NEWBASECFG
+ . $CFGFILE
+else
+ #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+
+ # to be completed
+
+ if [ -z "$CFGFILE" ]; then
+ echo "CFGFILE not found. Cannot continue." >&2
+ exit 1
+ fi
+
+ if [ -d $CFGFILE ]; then
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ else
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ if [ ! -e $CFGROOT/$CFGDIR ]; then
+ echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
+ mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
+ if [ $? != 0 ]; then
+ echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
+ exit 1
+ else
+ echo "Done !"
+ fi
+ fi
+ fi
+
+ if [ -e "$CFGFILE" ]; then
+ . $CFGFILE
+ else
+ echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
+ exit 1
+ fi
+ fi
+
+ if [ -z "$DISTVER" ]; then
+ if echo $CFGFILE | grep -q -- "-flx\." ; then
+ DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
+ else
+ DISTVER='flx.1'
+ fi
+ fi
+
+ echo $packver | grep -q -- "-flx\."
+ if [ $? != 0 ] ; then
+ packver=$packver-$DISTVER
+ fi
+
+ echo $packver | grep -q -- "-$FLXARCH\$"
+ if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
+
+ prefix=${packver%%[._-][0-9]*}
+ suffix=${packver#$prefix[._-]}
+ PKGVER=${suffix%-flx*}
+ PKGRADIX=$prefix
+ #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
+ if [ -z "$DISTVER" ]; then
+ DISTVER=${suffix#$PKGVER-}
+ if [ "$DISTVER" = "$PKGVER" ]; then
+ DISTVER="flx.1"
+ else
+ DISTVER=${DISTVER%-*}
+ fi
+ fi
+
+ case "$FLXARCH" in
+ i686) arch=i686 cpu=i686 basearch=i386 ;;
+ i486) arch=i486 cpu=i486 basearch=i386 ;;
+ i386) arch=i386 cpu=i386 basearch=i386 ;;
+ *) arch=i586 cpu=i686 basearch=i386 ;;
+ esac
+
+ if [ -z "$FLXMAKE" ]; then
+ FLXMAKE=make
+ fi
+
+
+ if [ -z "${PATCH_LIST}" ]; then
+ PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
+ if [ ! -e ${PATCH_LIST} ]; then
+ unset PATCH_LIST
+ fi
+ fi
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+ declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f do_$ACTION > /dev/null && ( do_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f post_$ACTION > /dev/null && ( post_$ACTION )
+ [ $? != 0 ] && exit $?
+ fi
+fi
+
diff --git a/scripts/pkg-0.5.6 b/scripts/pkg-0.5.6
new file mode 100755
index 0000000..297ee6d
--- /dev/null
+++ b/scripts/pkg-0.5.6
@@ -0,0 +1,2183 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.5.6 - 2005-08-17
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+# resolves a symlink to an absolute location.
+# usage: resolve_link <link_dir> <link_pointer>
+function resolve_link {
+ # prints $1 if $2 is empty, and prints $2 if it starts with a '/'.
+ if [ -z "$2" ]; then
+ dir="$1"
+ elif [ -z "${2##/*}" ]; then
+ dir="$2"
+ else
+ dir="$1/$2"
+ fi
+
+ # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right,
+ # then enclose with '/'
+ while [ -n "$dir" ]; do
+ if [ -z "${dir##./*}" ]; then dir="${dir#./}"
+ elif [ -z "${dir##/*}" ]; then dir="${dir#/}"
+ elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}"
+ elif [ -z "${dir%%*/}" ]; then dir="${dir%/}"
+ elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}"
+ elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}"
+ else
+ dir="/$dir/"
+ break;
+ fi
+ done
+
+ # now resolve '/../' from left to right only.
+ while [ -z "${dir##*/../*}" ]; do
+ # if dir goes past root, we must truncate it
+ if [ -z "${dir##/../*}" ]; then
+ dir="/${dir##/../}"
+ else
+ # turn all '/x/../' into '/'
+ odir="$dir"
+ dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')"
+ [ "$dir" = "$odir" ] && break
+ fi
+ done
+
+ [ "$dir" = "/" ] || dir="${dir#/}"
+ [ "$dir" = "/" ] || dir="${dir%/}"
+ echo "$dir"
+}
+
+# this function analyses an ELF executable and prints its name along with some
+# informations such as :
+# %N:soname : for libraries, their soname
+# %D:libname : library it depends on (their soname)
+# %P:provide : feature provided by a library, in the form soname/version
+# %R:require : required feature, in the for soname/version
+function elf_get_dep {
+ local elf
+ for elf in "$@"; do
+ $OBJDUMP -p "$elf" | (
+ soname_str=""
+ soname=""
+ needed=""
+ provide=""
+ require=""
+ curreq=""
+ section=""
+ while read; do
+ case "$REPLY" in
+ Dynamic\ Section*)
+ section="dynamic" ;;
+ Version\ defin*)
+ section="definitions" ;;
+ Version\ Refer*)
+ section="references" ;;
+ *)
+ set -- $REPLY
+ if [ "$section" = "dynamic" ]; then
+ if [ "$1" = "NEEDED" ]; then
+ needed="${needed:+$needed }%D:$2"
+ elif [ "$1" = "SONAME" ]; then
+ soname="$2"
+ soname_str="${soname_str:+$soname_str }%N:$2"
+ fi
+ elif [ "$section" = "definitions" ]; then
+ if [ "$#" = "4" -a "$2" = "0x00" ]; then
+ provide="${provide:+$provide }%P:$soname/$4"
+ fi
+ elif [ "$section" = "references" ]; then
+ if [ "$#" = "3" -a "$1" = "required" ]; then
+ curreq="${3%:}"
+ elif [ "$#" = "4" ]; then
+ require="${require:+$require }%R:$curreq/$4"
+ fi
+ fi
+ ;;
+ esac
+ done
+ echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}"
+ )
+ done
+ return 0
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s/$VERSION/\1|/" \
+ -e "s/^$FIELD|$VERSION/\1|\2|/" \
+ -e "s/^$FIELD|$FIELD|$FIELD$/\1|\2|\3~\1\2\3/" \
+ -e "s/^[^|]*|[^|]*$//"))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The result is returned in REPLY.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i
+
+ REPLY=
+ for pattern in $*; do
+ if [ "$pattern" = "%P" ]; then
+ pattern=$(basename $(pwd))
+ elif [ "$pattern" = "%L" ]; then
+ if [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern=$(readlink ${LINKNAME})
+ REPLY=$(basename $pattern)
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY=${sort_list[0]}
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $(pwd))
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "$PKGROOT/${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+# sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '$EXACTPKG' :"
+
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $(pwd)/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ esac
+
+ # FIXME: this should go into a per-architecture file
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ case "$FLXHOSTARCH" in
+ *86)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ parisc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ sparc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ ev[456]*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ *)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+ export HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL
+
+ return 0
+}
+
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ HOSTCC \
+ HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_cross_environment
+ set_compiler_options
+
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/$EXACTPKG" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/$EXACTPKG already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/$EXACTPKG
+ exit 2
+ fi
+
+ touch $PKGROOT/$EXACTPKG/RELEASED
+
+ return 0
+}
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+PRINTENV=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --env|-e)
+ PRINTENV=1
+ TESTGCC=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTENV -gt 0 ] && print_env
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG=$REPLY
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/build.cfg" ]; then
+ PKGDIR=$PKGROOT/$EXACTPKG
+ else
+ PKGDIR=$DEVROOT/$EXACTPKG
+ fi
+ fi
+ CFGFILE=$PKGDIR/build.cfg
+ PKGRADIX=$(get_pkg_radix $EXACTPKG)
+ PKGVER=$(get_pkg_ver $EXACTPKG)
+ DISTVER=$(get_build_num $EXACTPKG)
+ ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+ EXAMPLEDIR=${ROOTDIR}/usr/share/examples
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver=$EXACTPKG
+ pack=$PKGRADIX
+ fi
+
+ set_cross_environment
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE=${FLXMAKE:-make}
+ FLXPMAKE=${FLXPMAKE:-$FLXMAKE}
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+exit 99
+
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+
+
+DEAD CODE BELOW !!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function usage {
+ echo "Usage: pkg <action> [new_pkg [old_pkg]]"
+ echo " action is one of :"
+ echo " help : display this help."
+ echo " info : get information on current package."
+ echo " newpkg : build a more recent .pkg script from an old one."
+ echo " cat : display last .pkg file."
+ echo " edit : edit last .pkg file."
+ echo " patch : apply a list of patches to the directory prior to compile."
+ echo " unpatch : revert a list of patches to the directory."
+ echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " strip : strip binaries in temporary directory"
+ echo " pack : strip binaries, then package into $PKGROOT"
+ echo " delpack : remove temporary directory"
+ echo " clean : execute 'make clean' and remove temporary directory."
+ echo " build : execute clean compile prepack pack."
+ echo " unpack : extract package into temporary directory"
+ echo "Variables are :"
+ echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
+ echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+ echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
+ echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
+ echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
+ echo "FLXARCH : architecture for package name, <$FLXARCH>"
+ echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
+ echo "DISTVER : build version (flx.1)"
+ exit 1
+}
+
+
+
+
+
+
+
+
+
+for ACTION in ${ARGLIST[*]}; do
+
+# now we will try to identify two packages names :
+# - the EXACT one, deduced from command line, then version symlink, then the
+# directory name ; this one doesn't have to exist to be correct.
+# - the NEAREST one, deduced from the same criterions, with and without
+# versions, and based on EXISTING files only.
+# The NEAREST one will be used as a source, while the EXACT one will be used as
+# a target. When the EXACT one exists, the NEAREST one must obviously be the
+# same.
+
+# EXACTPKG can be specified as an environment variable if needed
+[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
+[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
+[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
+
+if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG-* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG* | tail -1)}
+# if [ -z "$TEMP" ]; then
+# echo "Cannot find a suitable package for the current directory. Please specify"
+# echo "a correct name on the command line."
+# usage
+# exit 1
+# fi
+ [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
+ [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
+fi
+
+if [ -z "$(get_build_num $EXACTPKG)" ]; then
+ RADIX=$(get_pkg_radix $EXACTPKG)
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-* $CFGROOT/$EXACTPKG $CFGROOT/$RADIX | tail -1)
+
+ VER=$(get_pkg_ver $TEMP)
+ BUILD=$(get_build_num $TEMP)
+ EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
+fi
+
+NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
+NEWPKGVER=$(get_pkg_ver $EXACTPKG)
+NEWDISTVER=$(get_build_num $EXACTPKG)
+NEWDISTVER=${NEWDISTVER:-flx.1}
+EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
+
+trylist=( )
+[ -d "$CFGROOT/$EXACTPKG" -o -f "$CFGROOT/$EXACTPKG.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
+[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
+[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
+trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
+trylist=( ${trylist[*]} $NEWPKGRADIX )
+trylist=( ${trylist[*]} $(basename $(pwd)))
+trylist=( ${trylist[*]} "default")
+
+echo trylist=${trylist[*]}
+
+for NEARESTPKG in ${trylist[*]}; do
+ if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
+ #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
+ [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
+ fi
+
+ RADIX=$(get_pkg_radix $NEARESTPKG)
+ VER=$(get_pkg_ver $NEARESTPKG)
+ BUILD=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+ #### [ "$(get_build_num $NEARESTPKG)" ] &&
+
+ [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
+echo NEARESTPKG=$NEARESTPKG
+
+ ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
+ ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
+done
+
+RADIX=$(get_pkg_radix $NEARESTPKG)
+VER=$(get_pkg_ver $NEARESTPKG)
+BUILD=$(get_build_num $NEARESTPKG)
+NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+echo "EXACTPKG=$EXACTPKG"
+echo "NEARESTPKG=$NEARESTPKG"
+
+# to be removed ## look if there was an argument, in which case we would treat it as a package
+# to be removed ## name (either source or destination, depending on the action). These variables
+# to be removed ## are set :
+# to be removed ## - ARGPKGFULL : full package name with version
+# to be removed ## - ARGPKGRADIX : package radix name (without version)
+# to be removed ## - ARGPKGVER : package version without -flx*
+# to be removed ## - ARGDISTVER : package build version (flx*)
+# to be removed #
+# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
+# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
+# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
+# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
+# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
+# to be removed # fi
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
+# to be removed #fi
+# to be removed #
+# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # PKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # PKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
+# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
+# to be removed #
+# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
+# to be removed # DISTVER=$(get_build_num $PKGFULL)
+# to be removed #fi
+# to be removed #
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
+# to be removed #
+# to be removed #
+# to be removed #
+# to be removed ## now process the destination parameters
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # NEWPKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # NEWPKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
+# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
+# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
+# to be removed #
+# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
+# to be removed #fi
+# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
+# to be removed #
+# to be removed ## recompute the new package version
+# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
+# to be removed #
+
+
+# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
+# directory name for the new package. If it cannot be found, all actions except
+# info and newpkg will fail. So we have to do a newpkg before using a new dir.
+
+if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
+ echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
+ exit 1
+fi
+
+# source configuration
+ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+
+
+CURPKG=$NEARESTPKG
+PKGRADIX=$(get_pkg_radix $NEARESTPKG)
+PKGVER=$(get_pkg_ver $NEARESTPKG)
+if echo $NEARESTPKG | grep -q -- "-flx\." ; then
+ DISTVER=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
+else
+ DISTVER=
+ NEARESTPKG=$PKGRADIX-$PKGVER
+fi
+
+CFGDIR=$CFGROOT/$CURPKG
+CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
+
+echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
+
+exit 0
+
+
+
+if [ -n "$CFGFILE" ]; then
+ CFGDIR=$NEWCFGROOT/$NEWBASECFG
+ . $CFGFILE
+else
+ #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+
+ # to be completed
+
+ if [ -z "$CFGFILE" ]; then
+ echo "CFGFILE not found. Cannot continue." >&2
+ exit 1
+ fi
+
+ if [ -d $CFGFILE ]; then
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ else
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ if [ ! -e $CFGROOT/$CFGDIR ]; then
+ echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
+ mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
+ if [ $? != 0 ]; then
+ echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
+ exit 1
+ else
+ echo "Done !"
+ fi
+ fi
+ fi
+
+ if [ -e "$CFGFILE" ]; then
+ . $CFGFILE
+ else
+ echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
+ exit 1
+ fi
+ fi
+
+ if [ -z "$DISTVER" ]; then
+ if echo $CFGFILE | grep -q -- "-flx\." ; then
+ DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
+ else
+ DISTVER='flx.1'
+ fi
+ fi
+
+ echo $packver | grep -q -- "-flx\."
+ if [ $? != 0 ] ; then
+ packver=$packver-$DISTVER
+ fi
+
+ echo $packver | grep -q -- "-$FLXARCH\$"
+ if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
+
+ prefix=${packver%%[._-][0-9]*}
+ suffix=${packver#$prefix[._-]}
+ PKGVER=${suffix%-flx*}
+ PKGRADIX=$prefix
+ #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
+ if [ -z "$DISTVER" ]; then
+ DISTVER=${suffix#$PKGVER-}
+ if [ "$DISTVER" = "$PKGVER" ]; then
+ DISTVER="flx.1"
+ else
+ DISTVER=${DISTVER%-*}
+ fi
+ fi
+
+ case "$FLXARCH" in
+ i686) arch=i686 cpu=i686 basearch=i386 ;;
+ i486) arch=i486 cpu=i486 basearch=i386 ;;
+ i386) arch=i386 cpu=i386 basearch=i386 ;;
+ *) arch=i586 cpu=i686 basearch=i386 ;;
+ esac
+
+ if [ -z "$FLXMAKE" ]; then
+ FLXMAKE=make
+ fi
+
+
+ if [ -z "${PATCH_LIST}" ]; then
+ PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
+ if [ ! -e ${PATCH_LIST} ]; then
+ unset PATCH_LIST
+ fi
+ fi
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+ declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f do_$ACTION > /dev/null && ( do_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f post_$ACTION > /dev/null && ( post_$ACTION )
+ [ $? != 0 ] && exit $?
+ fi
+fi
+
diff --git a/scripts/pkg-0.5.7 b/scripts/pkg-0.5.7
new file mode 100755
index 0000000..7e12878
--- /dev/null
+++ b/scripts/pkg-0.5.7
@@ -0,0 +1,2193 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.5.7 - 2005-08-21
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+# resolves a symlink to an absolute location.
+# usage: resolve_link <link_dir> <link_pointer>
+function resolve_link {
+ # prints $1 if $2 is empty, and prints $2 if it starts with a '/'.
+ if [ -z "$2" ]; then
+ dir="$1"
+ elif [ -z "${2##/*}" ]; then
+ dir="$2"
+ else
+ dir="$1/$2"
+ fi
+
+ # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right,
+ # then enclose with '/'
+ while [ -n "$dir" ]; do
+ if [ -z "${dir##./*}" ]; then dir="${dir#./}"
+ elif [ -z "${dir##/*}" ]; then dir="${dir#/}"
+ elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}"
+ elif [ -z "${dir%%*/}" ]; then dir="${dir%/}"
+ elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}"
+ elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}"
+ else
+ dir="/$dir/"
+ break;
+ fi
+ done
+
+ # now resolve '/../' from left to right only.
+ while [ -z "${dir##*/../*}" ]; do
+ # if dir goes past root, we must truncate it
+ if [ -z "${dir##/../*}" ]; then
+ dir="/${dir##/../}"
+ else
+ # turn all '/x/../' into '/'
+ odir="$dir"
+ dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')"
+ [ "$dir" = "$odir" ] && break
+ fi
+ done
+
+ [ "$dir" = "/" ] || dir="${dir#/}"
+ [ "$dir" = "/" ] || dir="${dir%/}"
+ echo "$dir"
+}
+
+# this function analyses an ELF executable and prints its name along with some
+# informations such as :
+# %N:soname : for libraries, their soname
+# %D:libname : library it depends on (their soname)
+# %P:provide : feature provided by a library, in the form soname/version
+# %R:require : required feature, in the for soname/version
+function elf_get_dep {
+ local elf
+ for elf in "$@"; do
+ $OBJDUMP -p "$elf" | (
+ soname_str=""
+ soname=""
+ needed=""
+ provide=""
+ require=""
+ curreq=""
+ section=""
+ while read; do
+ case "$REPLY" in
+ Dynamic\ Section*)
+ section="dynamic" ;;
+ Version\ defin*)
+ section="definitions" ;;
+ Version\ Refer*)
+ section="references" ;;
+ *)
+ set -- $REPLY
+ if [ "$section" = "dynamic" ]; then
+ if [ "$1" = "NEEDED" ]; then
+ needed="${needed:+$needed }%D:$2"
+ elif [ "$1" = "SONAME" ]; then
+ soname="$2"
+ soname_str="${soname_str:+$soname_str }%N:$2"
+ fi
+ elif [ "$section" = "definitions" ]; then
+ if [ "$#" = "4" -a "$2" = "0x00" ]; then
+ provide="${provide:+$provide }%P:$soname/$4"
+ fi
+ elif [ "$section" = "references" ]; then
+ if [ "$#" = "3" -a "$1" = "required" ]; then
+ curreq="${3%:}"
+ elif [ "$#" = "4" ]; then
+ require="${require:+$require }%R:$curreq/$4"
+ fi
+ fi
+ ;;
+ esac
+ done
+ echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}"
+ )
+ done
+ return 0
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s/$VERSION/\1|/" \
+ -e "s/^$FIELD|$VERSION/\1|\2|/" \
+ -e "s/^$FIELD|$FIELD|$FIELD$/\1|\2|\3~\1\2\3/" \
+ -e "s/^[^|]*|[^|]*$//"))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The result is returned in REPLY.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i
+
+ REPLY=
+ for pattern in $*; do
+ if [ "$pattern" = "%P" ]; then
+ pattern=$(basename $(pwd))
+ elif [ "$pattern" = "%L" ]; then
+ if [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern=$(readlink ${LINKNAME})
+ REPLY=$(basename $pattern)
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY=${sort_list[0]}
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $(pwd))
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "$PKGROOT/${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+# sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '$EXACTPKG' :"
+
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $(pwd)/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ CXX=${FLXCROSS}${CXX} ; CXX=${FLXCROSSCXX:-$CXX}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ esac
+
+ # FIXME: this should go into a per-architecture file
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ case "$FLXHOSTARCH" in
+ *86)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ parisc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ sparc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ ev[456]*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ *)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC CXX AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+ export HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL
+
+ return 0
+}
+
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC CXX LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ HOSTCC HOSTCXX \
+ HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_cross_environment
+ set_compiler_options
+
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/$EXACTPKG" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/$EXACTPKG already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/$EXACTPKG
+ exit 2
+ fi
+
+ touch $PKGROOT/$EXACTPKG/RELEASED
+
+ return 0
+}
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+PRINTENV=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --env|-e)
+ PRINTENV=1
+ TESTGCC=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTENV -gt 0 ] && print_env
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG=$REPLY
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/build.cfg" ]; then
+ PKGDIR=$PKGROOT/$EXACTPKG
+ else
+ PKGDIR=$DEVROOT/$EXACTPKG
+ fi
+ fi
+ CFGFILE=$PKGDIR/build.cfg
+ PKGRADIX=$(get_pkg_radix $EXACTPKG)
+ PKGVER=$(get_pkg_ver $EXACTPKG)
+ DISTVER=$(get_build_num $EXACTPKG)
+ ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+ EXAMPLEDIR=${ROOTDIR}/usr/share/examples
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver=$EXACTPKG
+ pack=$PKGRADIX
+ fi
+
+ set_cross_environment
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE=${FLXMAKE:-make}
+ FLXPMAKE=${FLXPMAKE:-$FLXMAKE}
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+exit 99
+
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+
+
+DEAD CODE BELOW !!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function usage {
+ echo "Usage: pkg <action> [new_pkg [old_pkg]]"
+ echo " action is one of :"
+ echo " help : display this help."
+ echo " info : get information on current package."
+ echo " newpkg : build a more recent .pkg script from an old one."
+ echo " cat : display last .pkg file."
+ echo " edit : edit last .pkg file."
+ echo " patch : apply a list of patches to the directory prior to compile."
+ echo " unpatch : revert a list of patches to the directory."
+ echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " strip : strip binaries in temporary directory"
+ echo " pack : strip binaries, then package into $PKGROOT"
+ echo " delpack : remove temporary directory"
+ echo " clean : execute 'make clean' and remove temporary directory."
+ echo " build : execute clean compile prepack pack."
+ echo " unpack : extract package into temporary directory"
+ echo "Variables are :"
+ echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
+ echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+ echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
+ echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
+ echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
+ echo "FLXARCH : architecture for package name, <$FLXARCH>"
+ echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
+ echo "DISTVER : build version (flx.1)"
+ exit 1
+}
+
+
+
+
+
+
+
+
+
+for ACTION in ${ARGLIST[*]}; do
+
+# now we will try to identify two packages names :
+# - the EXACT one, deduced from command line, then version symlink, then the
+# directory name ; this one doesn't have to exist to be correct.
+# - the NEAREST one, deduced from the same criterions, with and without
+# versions, and based on EXISTING files only.
+# The NEAREST one will be used as a source, while the EXACT one will be used as
+# a target. When the EXACT one exists, the NEAREST one must obviously be the
+# same.
+
+# EXACTPKG can be specified as an environment variable if needed
+[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
+[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
+[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
+
+if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG-* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG* | tail -1)}
+# if [ -z "$TEMP" ]; then
+# echo "Cannot find a suitable package for the current directory. Please specify"
+# echo "a correct name on the command line."
+# usage
+# exit 1
+# fi
+ [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
+ [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
+fi
+
+if [ -z "$(get_build_num $EXACTPKG)" ]; then
+ RADIX=$(get_pkg_radix $EXACTPKG)
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-* $CFGROOT/$EXACTPKG $CFGROOT/$RADIX | tail -1)
+
+ VER=$(get_pkg_ver $TEMP)
+ BUILD=$(get_build_num $TEMP)
+ EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
+fi
+
+NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
+NEWPKGVER=$(get_pkg_ver $EXACTPKG)
+NEWDISTVER=$(get_build_num $EXACTPKG)
+NEWDISTVER=${NEWDISTVER:-flx.1}
+EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
+
+trylist=( )
+[ -d "$CFGROOT/$EXACTPKG" -o -f "$CFGROOT/$EXACTPKG.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
+[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
+[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
+trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
+trylist=( ${trylist[*]} $NEWPKGRADIX )
+trylist=( ${trylist[*]} $(basename $(pwd)))
+trylist=( ${trylist[*]} "default")
+
+echo trylist=${trylist[*]}
+
+for NEARESTPKG in ${trylist[*]}; do
+ if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
+ #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
+ [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
+ fi
+
+ RADIX=$(get_pkg_radix $NEARESTPKG)
+ VER=$(get_pkg_ver $NEARESTPKG)
+ BUILD=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+ #### [ "$(get_build_num $NEARESTPKG)" ] &&
+
+ [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
+echo NEARESTPKG=$NEARESTPKG
+
+ ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
+ ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
+done
+
+RADIX=$(get_pkg_radix $NEARESTPKG)
+VER=$(get_pkg_ver $NEARESTPKG)
+BUILD=$(get_build_num $NEARESTPKG)
+NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+echo "EXACTPKG=$EXACTPKG"
+echo "NEARESTPKG=$NEARESTPKG"
+
+# to be removed ## look if there was an argument, in which case we would treat it as a package
+# to be removed ## name (either source or destination, depending on the action). These variables
+# to be removed ## are set :
+# to be removed ## - ARGPKGFULL : full package name with version
+# to be removed ## - ARGPKGRADIX : package radix name (without version)
+# to be removed ## - ARGPKGVER : package version without -flx*
+# to be removed ## - ARGDISTVER : package build version (flx*)
+# to be removed #
+# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
+# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
+# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
+# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
+# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
+# to be removed # fi
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
+# to be removed #fi
+# to be removed #
+# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # PKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # PKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
+# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
+# to be removed #
+# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
+# to be removed # DISTVER=$(get_build_num $PKGFULL)
+# to be removed #fi
+# to be removed #
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
+# to be removed #
+# to be removed #
+# to be removed #
+# to be removed ## now process the destination parameters
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # NEWPKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # NEWPKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
+# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
+# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
+# to be removed #
+# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
+# to be removed #fi
+# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
+# to be removed #
+# to be removed ## recompute the new package version
+# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
+# to be removed #
+
+
+# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
+# directory name for the new package. If it cannot be found, all actions except
+# info and newpkg will fail. So we have to do a newpkg before using a new dir.
+
+if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
+ echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
+ exit 1
+fi
+
+# source configuration
+ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+
+
+CURPKG=$NEARESTPKG
+PKGRADIX=$(get_pkg_radix $NEARESTPKG)
+PKGVER=$(get_pkg_ver $NEARESTPKG)
+if echo $NEARESTPKG | grep -q -- "-flx\." ; then
+ DISTVER=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
+else
+ DISTVER=
+ NEARESTPKG=$PKGRADIX-$PKGVER
+fi
+
+CFGDIR=$CFGROOT/$CURPKG
+CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
+
+echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
+
+exit 0
+
+
+
+if [ -n "$CFGFILE" ]; then
+ CFGDIR=$NEWCFGROOT/$NEWBASECFG
+ . $CFGFILE
+else
+ #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+
+ # to be completed
+
+ if [ -z "$CFGFILE" ]; then
+ echo "CFGFILE not found. Cannot continue." >&2
+ exit 1
+ fi
+
+ if [ -d $CFGFILE ]; then
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ else
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ if [ ! -e $CFGROOT/$CFGDIR ]; then
+ echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
+ mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
+ if [ $? != 0 ]; then
+ echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
+ exit 1
+ else
+ echo "Done !"
+ fi
+ fi
+ fi
+
+ if [ -e "$CFGFILE" ]; then
+ . $CFGFILE
+ else
+ echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
+ exit 1
+ fi
+ fi
+
+ if [ -z "$DISTVER" ]; then
+ if echo $CFGFILE | grep -q -- "-flx\." ; then
+ DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
+ else
+ DISTVER='flx.1'
+ fi
+ fi
+
+ echo $packver | grep -q -- "-flx\."
+ if [ $? != 0 ] ; then
+ packver=$packver-$DISTVER
+ fi
+
+ echo $packver | grep -q -- "-$FLXARCH\$"
+ if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
+
+ prefix=${packver%%[._-][0-9]*}
+ suffix=${packver#$prefix[._-]}
+ PKGVER=${suffix%-flx*}
+ PKGRADIX=$prefix
+ #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
+ if [ -z "$DISTVER" ]; then
+ DISTVER=${suffix#$PKGVER-}
+ if [ "$DISTVER" = "$PKGVER" ]; then
+ DISTVER="flx.1"
+ else
+ DISTVER=${DISTVER%-*}
+ fi
+ fi
+
+ case "$FLXARCH" in
+ i686) arch=i686 cpu=i686 basearch=i386 ;;
+ i486) arch=i486 cpu=i486 basearch=i386 ;;
+ i386) arch=i386 cpu=i386 basearch=i386 ;;
+ *) arch=i586 cpu=i686 basearch=i386 ;;
+ esac
+
+ if [ -z "$FLXMAKE" ]; then
+ FLXMAKE=make
+ fi
+
+
+ if [ -z "${PATCH_LIST}" ]; then
+ PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
+ if [ ! -e ${PATCH_LIST} ]; then
+ unset PATCH_LIST
+ fi
+ fi
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+ declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f do_$ACTION > /dev/null && ( do_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f post_$ACTION > /dev/null && ( post_$ACTION )
+ [ $? != 0 ] && exit $?
+ fi
+fi
+
diff --git a/scripts/pkg-0.5.8 b/scripts/pkg-0.5.8
new file mode 100755
index 0000000..5056766
--- /dev/null
+++ b/scripts/pkg-0.5.8
@@ -0,0 +1,2195 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.5.8 - 2005-08-21
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+# resolves a symlink to an absolute location.
+# usage: resolve_link <link_dir> <link_pointer>
+function resolve_link {
+ # prints $1 if $2 is empty, and prints $2 if it starts with a '/'.
+ if [ -z "$2" ]; then
+ dir="$1"
+ elif [ -z "${2##/*}" ]; then
+ dir="$2"
+ else
+ dir="$1/$2"
+ fi
+
+ # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right,
+ # then enclose with '/'
+ while [ -n "$dir" ]; do
+ if [ -z "${dir##./*}" ]; then dir="${dir#./}"
+ elif [ -z "${dir##/*}" ]; then dir="${dir#/}"
+ elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}"
+ elif [ -z "${dir%%*/}" ]; then dir="${dir%/}"
+ elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}"
+ elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}"
+ else
+ dir="/$dir/"
+ break;
+ fi
+ done
+
+ # now resolve '/../' from left to right only.
+ while [ -z "${dir##*/../*}" ]; do
+ # if dir goes past root, we must truncate it
+ if [ -z "${dir##/../*}" ]; then
+ dir="/${dir##/../}"
+ else
+ # turn all '/x/../' into '/'
+ odir="$dir"
+ dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')"
+ [ "$dir" = "$odir" ] && break
+ fi
+ done
+
+ [ "$dir" = "/" ] || dir="${dir#/}"
+ [ "$dir" = "/" ] || dir="${dir%/}"
+ echo "$dir"
+}
+
+# this function analyses an ELF executable and prints its name along with some
+# informations such as :
+# %N:soname : for libraries, their soname
+# %D:libname : library it depends on (their soname)
+# %P:provide : feature provided by a library, in the form soname/version
+# %R:require : required feature, in the for soname/version
+function elf_get_dep {
+ local elf
+ for elf in "$@"; do
+ $OBJDUMP -p "$elf" | (
+ soname_str=""
+ soname=""
+ needed=""
+ provide=""
+ require=""
+ curreq=""
+ section=""
+ while read; do
+ case "$REPLY" in
+ Dynamic\ Section*)
+ section="dynamic" ;;
+ Version\ defin*)
+ section="definitions" ;;
+ Version\ Refer*)
+ section="references" ;;
+ *)
+ set -- $REPLY
+ if [ "$section" = "dynamic" ]; then
+ if [ "$1" = "NEEDED" ]; then
+ needed="${needed:+$needed }%D:$2"
+ elif [ "$1" = "SONAME" ]; then
+ soname="$2"
+ soname_str="${soname_str:+$soname_str }%N:$2"
+ fi
+ elif [ "$section" = "definitions" ]; then
+ if [ "$#" = "4" -a "$2" = "0x00" ]; then
+ provide="${provide:+$provide }%P:$soname/$4"
+ fi
+ elif [ "$section" = "references" ]; then
+ if [ "$#" = "3" -a "$1" = "required" ]; then
+ curreq="${3%:}"
+ elif [ "$#" = "4" ]; then
+ require="${require:+$require }%R:$curreq/$4"
+ fi
+ fi
+ ;;
+ esac
+ done
+ echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}"
+ )
+ done
+ return 0
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s/$VERSION/\1|/" \
+ -e "s/^$FIELD|$VERSION/\1|\2|/" \
+ -e "s/^$FIELD|$FIELD|$FIELD$/\1|\2|\3~\1\2\3/" \
+ -e "s/^[^|]*|[^|]*$//"))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The result is returned in REPLY.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i
+
+ REPLY=
+ for pattern in $*; do
+ if [ "$pattern" = "%P" ]; then
+ pattern=$(basename $(pwd))
+ elif [ "$pattern" = "%L" ]; then
+ if [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern=$(readlink ${LINKNAME})
+ REPLY=$(basename $pattern)
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%f\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY=${sort_list[0]}
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY=${sort_list[$[$i-1]]}
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $(pwd))
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%f\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "$PKGROOT/${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+# sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '$EXACTPKG' :"
+
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d $(pwd)/${INSTNAME} ] && rm -rf $(pwd)/${INSTNAME}
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/$EXACTPKG-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $(pwd)/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/$EXACTPKG-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/$EXACTPKG-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ CXX=${FLXCROSS}${CXX} ; CXX=${FLXCROSSCXX:-$CXX}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ esac
+
+ # FIXME: this should go into a per-architecture file
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ case "$FLXHOSTARCH" in
+ *86)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ parisc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ sparc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ ev[456]*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ *)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC CXX AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+ export HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL
+
+ return 0
+}
+
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC CXX LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ HOSTCC HOSTCXX \
+ HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_cross_environment
+ set_compiler_options
+
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/$EXACTPKG" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/$EXACTPKG already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/$EXACTPKG
+ exit 2
+ fi
+
+ touch $PKGROOT/$EXACTPKG/RELEASED
+
+ return 0
+}
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+PRINTENV=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --env|-e)
+ PRINTENV=1
+ TESTGCC=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTENV -gt 0 ] && print_env
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ [ -d "$PKGDIR" ] || PKGDIR=
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ REPLY=$(basename $(readlink ${LINKNAME}) 2>/dev/null)
+ PKGDIR=$(readlink ${LINKNAME} 2>/dev/null)
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG=$REPLY
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/$EXACTPKG/build.cfg" ]; then
+ PKGDIR=$PKGROOT/$EXACTPKG
+ else
+ PKGDIR=$DEVROOT/$EXACTPKG
+ fi
+ fi
+ CFGFILE=$PKGDIR/build.cfg
+ PKGRADIX=$(get_pkg_radix $EXACTPKG)
+ PKGVER=$(get_pkg_ver $EXACTPKG)
+ DISTVER=$(get_build_num $EXACTPKG)
+ ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+ EXAMPLEDIR=${ROOTDIR}/usr/share/examples
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver=$EXACTPKG
+ pack=$PKGRADIX
+ fi
+
+ set_cross_environment
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE=${FLXMAKE:-make}
+ FLXPMAKE=${FLXPMAKE:-$FLXMAKE}
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+exit 99
+
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+
+
+DEAD CODE BELOW !!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function usage {
+ echo "Usage: pkg <action> [new_pkg [old_pkg]]"
+ echo " action is one of :"
+ echo " help : display this help."
+ echo " info : get information on current package."
+ echo " newpkg : build a more recent .pkg script from an old one."
+ echo " cat : display last .pkg file."
+ echo " edit : edit last .pkg file."
+ echo " patch : apply a list of patches to the directory prior to compile."
+ echo " unpatch : revert a list of patches to the directory."
+ echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " strip : strip binaries in temporary directory"
+ echo " pack : strip binaries, then package into $PKGROOT"
+ echo " delpack : remove temporary directory"
+ echo " clean : execute 'make clean' and remove temporary directory."
+ echo " build : execute clean compile prepack pack."
+ echo " unpack : extract package into temporary directory"
+ echo "Variables are :"
+ echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
+ echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+ echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
+ echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
+ echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
+ echo "FLXARCH : architecture for package name, <$FLXARCH>"
+ echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
+ echo "DISTVER : build version (flx.1)"
+ exit 1
+}
+
+
+
+
+
+
+
+
+
+for ACTION in ${ARGLIST[*]}; do
+
+# now we will try to identify two packages names :
+# - the EXACT one, deduced from command line, then version symlink, then the
+# directory name ; this one doesn't have to exist to be correct.
+# - the NEAREST one, deduced from the same criterions, with and without
+# versions, and based on EXISTING files only.
+# The NEAREST one will be used as a source, while the EXACT one will be used as
+# a target. When the EXACT one exists, the NEAREST one must obviously be the
+# same.
+
+# EXACTPKG can be specified as an environment variable if needed
+[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
+[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
+[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
+
+if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG-* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$EXACTPKG* | tail -1)}
+# if [ -z "$TEMP" ]; then
+# echo "Cannot find a suitable package for the current directory. Please specify"
+# echo "a correct name on the command line."
+# usage
+# exit 1
+# fi
+ [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
+ [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
+fi
+
+if [ -z "$(get_build_num $EXACTPKG)" ]; then
+ RADIX=$(get_pkg_radix $EXACTPKG)
+ TEMP=$(sortnames $CFGROOT/$EXACTPKG-* $CFGROOT/$EXACTPKG $CFGROOT/$RADIX | tail -1)
+
+ VER=$(get_pkg_ver $TEMP)
+ BUILD=$(get_build_num $TEMP)
+ EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
+fi
+
+NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
+NEWPKGVER=$(get_pkg_ver $EXACTPKG)
+NEWDISTVER=$(get_build_num $EXACTPKG)
+NEWDISTVER=${NEWDISTVER:-flx.1}
+EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
+
+trylist=( )
+[ -d "$CFGROOT/$EXACTPKG" -o -f "$CFGROOT/$EXACTPKG.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
+[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
+[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
+trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
+trylist=( ${trylist[*]} $NEWPKGRADIX )
+trylist=( ${trylist[*]} $(basename $(pwd)))
+trylist=( ${trylist[*]} "default")
+
+echo trylist=${trylist[*]}
+
+for NEARESTPKG in ${trylist[*]}; do
+ if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
+ #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
+ [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
+ fi
+
+ RADIX=$(get_pkg_radix $NEARESTPKG)
+ VER=$(get_pkg_ver $NEARESTPKG)
+ BUILD=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+ #### [ "$(get_build_num $NEARESTPKG)" ] &&
+
+ [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
+echo NEARESTPKG=$NEARESTPKG
+
+ ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
+ ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
+done
+
+RADIX=$(get_pkg_radix $NEARESTPKG)
+VER=$(get_pkg_ver $NEARESTPKG)
+BUILD=$(get_build_num $NEARESTPKG)
+NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+echo "EXACTPKG=$EXACTPKG"
+echo "NEARESTPKG=$NEARESTPKG"
+
+# to be removed ## look if there was an argument, in which case we would treat it as a package
+# to be removed ## name (either source or destination, depending on the action). These variables
+# to be removed ## are set :
+# to be removed ## - ARGPKGFULL : full package name with version
+# to be removed ## - ARGPKGRADIX : package radix name (without version)
+# to be removed ## - ARGPKGVER : package version without -flx*
+# to be removed ## - ARGDISTVER : package build version (flx*)
+# to be removed #
+# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
+# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
+# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
+# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
+# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
+# to be removed # fi
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
+# to be removed #fi
+# to be removed #
+# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # PKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # PKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
+# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
+# to be removed #
+# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
+# to be removed # DISTVER=$(get_build_num $PKGFULL)
+# to be removed #fi
+# to be removed #
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
+# to be removed #
+# to be removed #
+# to be removed #
+# to be removed ## now process the destination parameters
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # NEWPKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # NEWPKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
+# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
+# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
+# to be removed #
+# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
+# to be removed #fi
+# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
+# to be removed #
+# to be removed ## recompute the new package version
+# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
+# to be removed #
+
+
+# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
+# directory name for the new package. If it cannot be found, all actions except
+# info and newpkg will fail. So we have to do a newpkg before using a new dir.
+
+if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
+ echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
+ exit 1
+fi
+
+# source configuration
+ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+
+
+CURPKG=$NEARESTPKG
+PKGRADIX=$(get_pkg_radix $NEARESTPKG)
+PKGVER=$(get_pkg_ver $NEARESTPKG)
+if echo $NEARESTPKG | grep -q -- "-flx\." ; then
+ DISTVER=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
+else
+ DISTVER=
+ NEARESTPKG=$PKGRADIX-$PKGVER
+fi
+
+CFGDIR=$CFGROOT/$CURPKG
+CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
+
+echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
+
+exit 0
+
+
+
+if [ -n "$CFGFILE" ]; then
+ CFGDIR=$NEWCFGROOT/$NEWBASECFG
+ . $CFGFILE
+else
+ #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+
+ # to be completed
+
+ if [ -z "$CFGFILE" ]; then
+ echo "CFGFILE not found. Cannot continue." >&2
+ exit 1
+ fi
+
+ if [ -d $CFGFILE ]; then
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ else
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ if [ ! -e $CFGROOT/$CFGDIR ]; then
+ echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
+ mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
+ if [ $? != 0 ]; then
+ echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
+ exit 1
+ else
+ echo "Done !"
+ fi
+ fi
+ fi
+
+ if [ -e "$CFGFILE" ]; then
+ . $CFGFILE
+ else
+ echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
+ exit 1
+ fi
+ fi
+
+ if [ -z "$DISTVER" ]; then
+ if echo $CFGFILE | grep -q -- "-flx\." ; then
+ DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
+ else
+ DISTVER='flx.1'
+ fi
+ fi
+
+ echo $packver | grep -q -- "-flx\."
+ if [ $? != 0 ] ; then
+ packver=$packver-$DISTVER
+ fi
+
+ echo $packver | grep -q -- "-$FLXARCH\$"
+ if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
+
+ prefix=${packver%%[._-][0-9]*}
+ suffix=${packver#$prefix[._-]}
+ PKGVER=${suffix%-flx*}
+ PKGRADIX=$prefix
+ #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
+ if [ -z "$DISTVER" ]; then
+ DISTVER=${suffix#$PKGVER-}
+ if [ "$DISTVER" = "$PKGVER" ]; then
+ DISTVER="flx.1"
+ else
+ DISTVER=${DISTVER%-*}
+ fi
+ fi
+
+ case "$FLXARCH" in
+ i686) arch=i686 cpu=i686 basearch=i386 ;;
+ i486) arch=i486 cpu=i486 basearch=i386 ;;
+ i386) arch=i386 cpu=i386 basearch=i386 ;;
+ *) arch=i586 cpu=i686 basearch=i386 ;;
+ esac
+
+ if [ -z "$FLXMAKE" ]; then
+ FLXMAKE=make
+ fi
+
+
+ if [ -z "${PATCH_LIST}" ]; then
+ PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
+ if [ ! -e ${PATCH_LIST} ]; then
+ unset PATCH_LIST
+ fi
+ fi
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+ declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f do_$ACTION > /dev/null && ( do_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f post_$ACTION > /dev/null && ( post_$ACTION )
+ [ $? != 0 ] && exit $?
+ fi
+fi
+
diff --git a/scripts/pkg-0.6.0 b/scripts/pkg-0.6.0
new file mode 100755
index 0000000..3c0e3cb
--- /dev/null
+++ b/scripts/pkg-0.6.0
@@ -0,0 +1,2239 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.6.0 - 2005-08-27
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+CURDIR="$(pwd)"
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+# resolves a symlink to an absolute location.
+# usage: resolve_link <link_dir> <link_pointer>
+function resolve_link {
+ # prints $1 if $2 is empty, and prints $2 if it starts with a '/'.
+ if [ -z "$2" ]; then
+ dir="$1"
+ elif [ -z "${2##/*}" ]; then
+ dir="$2"
+ else
+ dir="$1/$2"
+ fi
+
+ # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right,
+ # then enclose with '/'
+ while [ -n "$dir" ]; do
+ if [ -z "${dir##./*}" ]; then dir="${dir#./}"
+ elif [ -z "${dir##/*}" ]; then dir="${dir#/}"
+ elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}"
+ elif [ -z "${dir%%*/}" ]; then dir="${dir%/}"
+ elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}"
+ elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}"
+ else
+ dir="/$dir/"
+ break;
+ fi
+ done
+
+ # now resolve '/../' from left to right only.
+ while [ -z "${dir##*/../*}" ]; do
+ # if dir goes past root, we must truncate it
+ if [ -z "${dir##/../*}" ]; then
+ dir="/${dir##/../}"
+ else
+ # turn all '/x/../' into '/'
+ odir="$dir"
+ dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')"
+ [ "$dir" = "$odir" ] && break
+ fi
+ done
+
+ [ "$dir" = "/" ] || dir="${dir#/}"
+ [ "$dir" = "/" ] || dir="${dir%/}"
+ echo "$dir"
+}
+
+# this function analyses an ELF executable and prints its name along with some
+# informations such as :
+# %N:soname : for libraries, their soname
+# %D:libname : library it depends on (their soname)
+# %P:provide : feature provided by a library, in the form soname/version
+# %R:require : required feature, in the for soname/version
+function elf_get_dep {
+ local elf
+ for elf in "$@"; do
+ $OBJDUMP -p "$elf" | (
+ soname_str=""
+ soname=""
+ needed=""
+ provide=""
+ require=""
+ curreq=""
+ section=""
+ while read; do
+ case "$REPLY" in
+ Dynamic\ Section*)
+ section="dynamic" ;;
+ Version\ defin*)
+ section="definitions" ;;
+ Version\ Refer*)
+ section="references" ;;
+ *)
+ set -- $REPLY
+ if [ "$section" = "dynamic" ]; then
+ if [ "$1" = "NEEDED" ]; then
+ needed="${needed:+$needed }%D:$2"
+ elif [ "$1" = "SONAME" ]; then
+ soname="$2"
+ soname_str="${soname_str:+$soname_str }%N:$2"
+ fi
+ elif [ "$section" = "definitions" ]; then
+ if [ "$#" = "4" -a "$2" = "0x00" ]; then
+ provide="${provide:+$provide }%P:$soname/$4"
+ fi
+ elif [ "$section" = "references" ]; then
+ if [ "$#" = "3" -a "$1" = "required" ]; then
+ curreq="${3%:}"
+ elif [ "$#" = "4" ]; then
+ require="${require:+$require }%R:$curreq/$4"
+ fi
+ fi
+ ;;
+ esac
+ done
+ echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}"
+ )
+ done
+ return 0
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+# Note: package names can be full path names.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s,$VERSION,\1|," \
+ -e "s,^$FIELD|$VERSION,\1|\2|," \
+ -e "s,^$FIELD|$FIELD|$FIELD$,\1|\2|\3~\1\2\3," \
+ -e "s,^[^|]*|[^|]*$,," \
+ -e 's,^[^|]*/,,'))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The resulting package name is returned in REPLY, and the package directoryy
+# is returned in PKGDIR whenever possible.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i search_dir
+
+ REPLY=
+ for pattern in $*; do
+ search_dir=
+ if [ "$pattern" = "%P" ]; then
+ search_dir="${CURDIR%/*}" ; search_dir="/${search_dir#/}"
+ pattern="$(basename $CURDIR)"
+ elif [ "$pattern" = "%L" ]; then
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ return
+ elif [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern="$(readlink ${LINKNAME})"
+ PKGDIR="$pattern/."
+ REPLY="${pattern##*/}"
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find ${search_dir:+$search_dir/} $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%p\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%p\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY="${sort_list[0]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ # FIXME : we risk a wrong match here (eg: flx0.1 <-> flx0.10)
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY="${sort_list[$[$i-1]]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY="${sort_list[$[$i-1]]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $CURDIR)
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+ #sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%p\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ --exclude='./Version' -cplf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '$EXACTPKG' :"
+
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}"
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}"
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $CURDIR/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ CXX=${FLXCROSS}${CXX} ; CXX=${FLXCROSSCXX:-$CXX}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ esac
+
+ # FIXME: this should go into a per-architecture file
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ case "$FLXHOSTARCH" in
+ *86)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ parisc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ sparc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ ev[456]*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ *)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC CXX AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+ export HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL
+
+ return 0
+}
+
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC CXX LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ HOSTCC HOSTCXX \
+ HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_cross_environment
+ set_compiler_options
+
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/${EXACTPKG##*/}" ]; then
+ if [ -e "$PKGROOT/${EXACTPKG##*/}/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/${EXACTPKG##*/} already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/${EXACTPKG##*/}
+ exit 2
+ fi
+
+ touch $PKGROOT/${EXACTPKG##*/}/RELEASED
+
+ return 0
+}
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+PRINTENV=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --env|-e)
+ PRINTENV=1
+ TESTGCC=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTENV -gt 0 ] && print_env
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ [ -d "$PKGDIR" ] || PKGDIR=
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG="$PKGDIR/$REPLY"
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/${EXACTPKG##*/}/build.cfg" ]; then
+ PKGDIR="$PKGROOT/${EXACTPKG##*/}"
+ else
+ PKGDIR="$DEVROOT/${EXACTPKG##*/}"
+ fi
+ fi
+ CFGFILE="$PKGDIR/build.cfg"
+ PKGRADIX="$(get_pkg_radix $EXACTPKG)"
+ PKGVER="$(get_pkg_ver $EXACTPKG)"
+ DISTVER="$(get_build_num $EXACTPKG)"
+ ROOTDIR="${ROOTDIR:-$CURDIR/${INSTNAME}}"
+ EXAMPLEDIR="${ROOTDIR}/usr/share/examples"
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver="$EXACTPKG"
+ pack="$PKGRADIX"
+ fi
+
+ set_cross_environment
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE="${FLXMAKE:-make}"
+ FLXPMAKE="${FLXPMAKE:-$FLXMAKE}"
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+exit 99
+
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+
+
+DEAD CODE BELOW !!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function usage {
+ echo "Usage: pkg <action> [new_pkg [old_pkg]]"
+ echo " action is one of :"
+ echo " help : display this help."
+ echo " info : get information on current package."
+ echo " newpkg : build a more recent .pkg script from an old one."
+ echo " cat : display last .pkg file."
+ echo " edit : edit last .pkg file."
+ echo " patch : apply a list of patches to the directory prior to compile."
+ echo " unpatch : revert a list of patches to the directory."
+ echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " strip : strip binaries in temporary directory"
+ echo " pack : strip binaries, then package into $PKGROOT"
+ echo " delpack : remove temporary directory"
+ echo " clean : execute 'make clean' and remove temporary directory."
+ echo " build : execute clean compile prepack pack."
+ echo " unpack : extract package into temporary directory"
+ echo "Variables are :"
+ echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
+ echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+ echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
+ echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
+ echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
+ echo "FLXARCH : architecture for package name, <$FLXARCH>"
+ echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
+ echo "DISTVER : build version (flx.1)"
+ exit 1
+}
+
+
+
+
+
+
+
+
+
+for ACTION in ${ARGLIST[*]}; do
+
+# now we will try to identify two packages names :
+# - the EXACT one, deduced from command line, then version symlink, then the
+# directory name ; this one doesn't have to exist to be correct.
+# - the NEAREST one, deduced from the same criterions, with and without
+# versions, and based on EXISTING files only.
+# The NEAREST one will be used as a source, while the EXACT one will be used as
+# a target. When the EXACT one exists, the NEAREST one must obviously be the
+# same.
+
+# EXACTPKG can be specified as an environment variable if needed
+[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
+[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
+[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
+
+if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/${EXACTPKG##*/}-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/${EXACTPKG##*/}.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/${EXACTPKG##*/}-* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/${EXACTPKG##*/}* | tail -1)}
+# if [ -z "$TEMP" ]; then
+# echo "Cannot find a suitable package for the current directory. Please specify"
+# echo "a correct name on the command line."
+# usage
+# exit 1
+# fi
+ [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
+ [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
+fi
+
+if [ -z "$(get_build_num $EXACTPKG)" ]; then
+ RADIX=$(get_pkg_radix $EXACTPKG)
+ TEMP=$(sortnames $CFGROOT/${EXACTPKG##*/}-* $CFGROOT/${EXACTPKG##*/} $CFGROOT/$RADIX | tail -1)
+
+ VER=$(get_pkg_ver $TEMP)
+ BUILD=$(get_build_num $TEMP)
+ EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
+fi
+
+NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
+NEWPKGVER=$(get_pkg_ver $EXACTPKG)
+NEWDISTVER=$(get_build_num $EXACTPKG)
+NEWDISTVER=${NEWDISTVER:-flx.1}
+EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
+
+trylist=( )
+[ -d "$CFGROOT/${EXACTPKG##*/}" -o -f "$CFGROOT/${EXACTPKG##*/}.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
+[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
+[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
+trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
+trylist=( ${trylist[*]} $NEWPKGRADIX )
+trylist=( ${trylist[*]} $(basename $(pwd)))
+trylist=( ${trylist[*]} "default")
+
+echo trylist=${trylist[*]}
+
+for NEARESTPKG in ${trylist[*]}; do
+ if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
+ #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
+ [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
+ fi
+
+ RADIX=$(get_pkg_radix $NEARESTPKG)
+ VER=$(get_pkg_ver $NEARESTPKG)
+ BUILD=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+ #### [ "$(get_build_num $NEARESTPKG)" ] &&
+
+ [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
+echo NEARESTPKG=$NEARESTPKG
+
+ ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
+ ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
+done
+
+RADIX=$(get_pkg_radix $NEARESTPKG)
+VER=$(get_pkg_ver $NEARESTPKG)
+BUILD=$(get_build_num $NEARESTPKG)
+NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+echo "EXACTPKG=$EXACTPKG"
+echo "NEARESTPKG=$NEARESTPKG"
+
+# to be removed ## look if there was an argument, in which case we would treat it as a package
+# to be removed ## name (either source or destination, depending on the action). These variables
+# to be removed ## are set :
+# to be removed ## - ARGPKGFULL : full package name with version
+# to be removed ## - ARGPKGRADIX : package radix name (without version)
+# to be removed ## - ARGPKGVER : package version without -flx*
+# to be removed ## - ARGDISTVER : package build version (flx*)
+# to be removed #
+# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
+# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
+# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
+# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
+# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
+# to be removed # fi
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
+# to be removed #fi
+# to be removed #
+# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # PKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # PKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
+# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
+# to be removed #
+# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
+# to be removed # DISTVER=$(get_build_num $PKGFULL)
+# to be removed #fi
+# to be removed #
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
+# to be removed #
+# to be removed #
+# to be removed #
+# to be removed ## now process the destination parameters
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # NEWPKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # NEWPKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
+# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
+# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
+# to be removed #
+# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
+# to be removed #fi
+# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
+# to be removed #
+# to be removed ## recompute the new package version
+# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
+# to be removed #
+
+
+# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
+# directory name for the new package. If it cannot be found, all actions except
+# info and newpkg will fail. So we have to do a newpkg before using a new dir.
+
+if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
+ echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
+ exit 1
+fi
+
+# source configuration
+ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+
+
+CURPKG=$NEARESTPKG
+PKGRADIX=$(get_pkg_radix $NEARESTPKG)
+PKGVER=$(get_pkg_ver $NEARESTPKG)
+if echo $NEARESTPKG | grep -q -- "-flx\." ; then
+ DISTVER=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
+else
+ DISTVER=
+ NEARESTPKG=$PKGRADIX-$PKGVER
+fi
+
+CFGDIR=$CFGROOT/$CURPKG
+CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
+
+echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
+
+exit 0
+
+
+
+if [ -n "$CFGFILE" ]; then
+ CFGDIR=$NEWCFGROOT/$NEWBASECFG
+ . $CFGFILE
+else
+ #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+
+ # to be completed
+
+ if [ -z "$CFGFILE" ]; then
+ echo "CFGFILE not found. Cannot continue." >&2
+ exit 1
+ fi
+
+ if [ -d $CFGFILE ]; then
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ else
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ if [ ! -e $CFGROOT/$CFGDIR ]; then
+ echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
+ mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
+ if [ $? != 0 ]; then
+ echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
+ exit 1
+ else
+ echo "Done !"
+ fi
+ fi
+ fi
+
+ if [ -e "$CFGFILE" ]; then
+ . $CFGFILE
+ else
+ echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
+ exit 1
+ fi
+ fi
+
+ if [ -z "$DISTVER" ]; then
+ if echo $CFGFILE | grep -q -- "-flx\." ; then
+ DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
+ else
+ DISTVER='flx.1'
+ fi
+ fi
+
+ echo $packver | grep -q -- "-flx\."
+ if [ $? != 0 ] ; then
+ packver=$packver-$DISTVER
+ fi
+
+ echo $packver | grep -q -- "-$FLXARCH\$"
+ if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
+
+ prefix=${packver%%[._-][0-9]*}
+ suffix=${packver#$prefix[._-]}
+ PKGVER=${suffix%-flx*}
+ PKGRADIX=$prefix
+ #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
+ if [ -z "$DISTVER" ]; then
+ DISTVER=${suffix#$PKGVER-}
+ if [ "$DISTVER" = "$PKGVER" ]; then
+ DISTVER="flx.1"
+ else
+ DISTVER=${DISTVER%-*}
+ fi
+ fi
+
+ case "$FLXARCH" in
+ i686) arch=i686 cpu=i686 basearch=i386 ;;
+ i486) arch=i486 cpu=i486 basearch=i386 ;;
+ i386) arch=i386 cpu=i386 basearch=i386 ;;
+ *) arch=i586 cpu=i686 basearch=i386 ;;
+ esac
+
+ if [ -z "$FLXMAKE" ]; then
+ FLXMAKE=make
+ fi
+
+
+ if [ -z "${PATCH_LIST}" ]; then
+ PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
+ if [ ! -e ${PATCH_LIST} ]; then
+ unset PATCH_LIST
+ fi
+ fi
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+ declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f do_$ACTION > /dev/null && ( do_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f post_$ACTION > /dev/null && ( post_$ACTION )
+ [ $? != 0 ] && exit $?
+ fi
+fi
+
diff --git a/scripts/pkg-0.6.1 b/scripts/pkg-0.6.1
new file mode 100755
index 0000000..5ee7c0a
--- /dev/null
+++ b/scripts/pkg-0.6.1
@@ -0,0 +1,2239 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.6.1 - 2005-09-17
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+CURDIR="$(pwd)"
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+# resolves a symlink to an absolute location.
+# usage: resolve_link <link_dir> <link_pointer>
+function resolve_link {
+ # prints $1 if $2 is empty, and prints $2 if it starts with a '/'.
+ if [ -z "$2" ]; then
+ dir="$1"
+ elif [ -z "${2##/*}" ]; then
+ dir="$2"
+ else
+ dir="$1/$2"
+ fi
+
+ # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right,
+ # then enclose with '/'
+ while [ -n "$dir" ]; do
+ if [ -z "${dir##./*}" ]; then dir="${dir#./}"
+ elif [ -z "${dir##/*}" ]; then dir="${dir#/}"
+ elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}"
+ elif [ -z "${dir%%*/}" ]; then dir="${dir%/}"
+ elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}"
+ elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}"
+ else
+ dir="/$dir/"
+ break;
+ fi
+ done
+
+ # now resolve '/../' from left to right only.
+ while [ -z "${dir##*/../*}" ]; do
+ # if dir goes past root, we must truncate it
+ if [ -z "${dir##/../*}" ]; then
+ dir="/${dir##/../}"
+ else
+ # turn all '/x/../' into '/'
+ odir="$dir"
+ dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')"
+ [ "$dir" = "$odir" ] && break
+ fi
+ done
+
+ [ "$dir" = "/" ] || dir="${dir#/}"
+ [ "$dir" = "/" ] || dir="${dir%/}"
+ echo "$dir"
+}
+
+# this function analyses an ELF executable and prints its name along with some
+# informations such as :
+# %N:soname : for libraries, their soname
+# %D:libname : library it depends on (their soname)
+# %P:provide : feature provided by a library, in the form soname/version
+# %R:require : required feature, in the for soname/version
+function elf_get_dep {
+ local elf
+ for elf in "$@"; do
+ $OBJDUMP -p "$elf" | (
+ soname_str=""
+ soname=""
+ needed=""
+ provide=""
+ require=""
+ curreq=""
+ section=""
+ while read; do
+ case "$REPLY" in
+ Dynamic\ Section*)
+ section="dynamic" ;;
+ Version\ defin*)
+ section="definitions" ;;
+ Version\ Refer*)
+ section="references" ;;
+ *)
+ set -- $REPLY
+ if [ "$section" = "dynamic" ]; then
+ if [ "$1" = "NEEDED" ]; then
+ needed="${needed:+$needed }%D:$2"
+ elif [ "$1" = "SONAME" ]; then
+ soname="$2"
+ soname_str="${soname_str:+$soname_str }%N:$2"
+ fi
+ elif [ "$section" = "definitions" ]; then
+ if [ "$#" = "4" -a "$2" = "0x00" ]; then
+ provide="${provide:+$provide }%P:$soname/$4"
+ fi
+ elif [ "$section" = "references" ]; then
+ if [ "$#" = "3" -a "$1" = "required" ]; then
+ curreq="${3%:}"
+ elif [ "$#" = "4" ]; then
+ require="${require:+$require }%R:$curreq/$4"
+ fi
+ fi
+ ;;
+ esac
+ done
+ echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}"
+ )
+ done
+ return 0
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+# Note: package names can be full path names.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s,$VERSION,\1|," \
+ -e "s,^$FIELD|$VERSION,\1|\2|," \
+ -e "s,^$FIELD|$FIELD|$FIELD$,\1|\2|\3~\1\2\3," \
+ -e "s,^[^|]*|[^|]*$,," \
+ -e 's,^[^|]*/,,'))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The resulting package name is returned in REPLY, and the package directoryy
+# is returned in PKGDIR whenever possible.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i search_dir
+
+ REPLY=
+ for pattern in $*; do
+ search_dir=
+ if [ "$pattern" = "%P" ]; then
+ search_dir="${CURDIR%/*}" ; search_dir="/${search_dir#/}"
+ pattern="$(basename $CURDIR)"
+ elif [ "$pattern" = "%L" ]; then
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ return
+ elif [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern="$(readlink ${LINKNAME})"
+ PKGDIR="$pattern/."
+ REPLY="${pattern##*/}"
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find ${search_dir:+$search_dir/} $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%p\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%p\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY="${sort_list[0]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ # FIXME : we risk a wrong match here (eg: flx0.1 <-> flx0.10)
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY="${sort_list[$[$i-1]]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY="${sort_list[$[$i-1]]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $CURDIR)
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+ #sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%p\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ --exclude='./Version' --one-file-system -cpf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '$EXACTPKG' :"
+
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}"
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}"
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $CURDIR/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ CXX=${FLXCROSS}${CXX} ; CXX=${FLXCROSSCXX:-$CXX}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ esac
+
+ # FIXME: this should go into a per-architecture file
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ case "$FLXHOSTARCH" in
+ *86)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ parisc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ sparc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ ev[456]*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ *)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC CXX AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+ export HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL
+
+ return 0
+}
+
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC CXX LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ HOSTCC HOSTCXX \
+ HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_cross_environment
+ set_compiler_options
+
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/${EXACTPKG##*/}" ]; then
+ if [ -e "$PKGROOT/${EXACTPKG##*/}/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/${EXACTPKG##*/} already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/${EXACTPKG##*/}
+ exit 2
+ fi
+
+ touch $PKGROOT/${EXACTPKG##*/}/RELEASED
+
+ return 0
+}
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+PRINTENV=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --env|-e)
+ PRINTENV=1
+ TESTGCC=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTENV -gt 0 ] && print_env
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ [ -d "$PKGDIR" ] || PKGDIR=
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG="$PKGDIR/$REPLY"
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/${EXACTPKG##*/}/build.cfg" ]; then
+ PKGDIR="$PKGROOT/${EXACTPKG##*/}"
+ else
+ PKGDIR="$DEVROOT/${EXACTPKG##*/}"
+ fi
+ fi
+ CFGFILE="$PKGDIR/build.cfg"
+ PKGRADIX="$(get_pkg_radix $EXACTPKG)"
+ PKGVER="$(get_pkg_ver $EXACTPKG)"
+ DISTVER="$(get_build_num $EXACTPKG)"
+ ROOTDIR="${ROOTDIR:-$CURDIR/${INSTNAME}}"
+ EXAMPLEDIR="${ROOTDIR}/usr/share/examples"
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver="$EXACTPKG"
+ pack="$PKGRADIX"
+ fi
+
+ set_cross_environment
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE="${FLXMAKE:-make}"
+ FLXPMAKE="${FLXPMAKE:-$FLXMAKE}"
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+exit 99
+
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+###############################################################################################################
+
+
+DEAD CODE BELOW !!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+function usage {
+ echo "Usage: pkg <action> [new_pkg [old_pkg]]"
+ echo " action is one of :"
+ echo " help : display this help."
+ echo " info : get information on current package."
+ echo " newpkg : build a more recent .pkg script from an old one."
+ echo " cat : display last .pkg file."
+ echo " edit : edit last .pkg file."
+ echo " patch : apply a list of patches to the directory prior to compile."
+ echo " unpatch : revert a list of patches to the directory."
+ echo " compile : do_compile=do_config_only+do_compile_only in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " prepack : execute do_prepack in .pkg script ($CFGROOT/$CFGDIR)"
+ echo " strip : strip binaries in temporary directory"
+ echo " pack : strip binaries, then package into $PKGROOT"
+ echo " delpack : remove temporary directory"
+ echo " clean : execute 'make clean' and remove temporary directory."
+ echo " build : execute clean compile prepack pack."
+ echo " unpack : extract package into temporary directory"
+ echo "Variables are :"
+ echo "CFGROOT : directory for .pkg and patches, <$CFGROOT>"
+ echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+ echo "PKGROOT : directory for .lst, .tgz and .dep, <$PKGROOT>"
+ echo "ROOTDIR : base directory for package (not source), <$ROOTDIR>"
+ echo "EXAMPLEDIR : base directory for sample config , <$EXAMPLEDIR>"
+ echo "FLXARCH : architecture for package name, <$FLXARCH>"
+ echo "KERNDIR : base directory for package (not source), <$KERNDIR>"
+ echo "DISTVER : build version (flx.1)"
+ exit 1
+}
+
+
+
+
+
+
+
+
+
+for ACTION in ${ARGLIST[*]}; do
+
+# now we will try to identify two packages names :
+# - the EXACT one, deduced from command line, then version symlink, then the
+# directory name ; this one doesn't have to exist to be correct.
+# - the NEAREST one, deduced from the same criterions, with and without
+# versions, and based on EXISTING files only.
+# The NEAREST one will be used as a source, while the EXACT one will be used as
+# a target. When the EXACT one exists, the NEAREST one must obviously be the
+# same.
+
+# EXACTPKG can be specified as an environment variable if needed
+[ $NEAREST_IS_SRC -eq 0 ] && [ -z "$EXACTPKG" -a ${#ARGLIST[*]} -gt 0 ] && EXACTPKG=$(basename ${ARGLIST[0]})
+[ -z "$EXACTPKG" -a -L .flxver ] && EXACTPKG=$(readlink .flxver)
+[ -z "$EXACTPKG" ] && EXACTPKG=$(basename $(pwd))
+
+if [ -z "$(get_pkg_ver $EXACTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/${EXACTPKG##*/}-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/${EXACTPKG##*/}.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/${EXACTPKG##*/}-* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/${EXACTPKG##*/}* | tail -1)}
+# if [ -z "$TEMP" ]; then
+# echo "Cannot find a suitable package for the current directory. Please specify"
+# echo "a correct name on the command line."
+# usage
+# exit 1
+# fi
+ [ "$TEMP" ] && EXACTPKG=$(basename $TEMP)
+ [ -z "$(get_pkg_ver $EXACTPKG)" ] && EXACTPKG=$EXACTPKG-0
+fi
+
+if [ -z "$(get_build_num $EXACTPKG)" ]; then
+ RADIX=$(get_pkg_radix $EXACTPKG)
+ TEMP=$(sortnames $CFGROOT/${EXACTPKG##*/}-* $CFGROOT/${EXACTPKG##*/} $CFGROOT/$RADIX | tail -1)
+
+ VER=$(get_pkg_ver $TEMP)
+ BUILD=$(get_build_num $TEMP)
+ EXACTPKG=${RADIX}-${VER:-0}-${BUILD:-flx.1}
+fi
+
+NEWPKGRADIX=$(get_pkg_radix $EXACTPKG)
+NEWPKGVER=$(get_pkg_ver $EXACTPKG)
+NEWDISTVER=$(get_build_num $EXACTPKG)
+NEWDISTVER=${NEWDISTVER:-flx.1}
+EXACTPKG=$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER
+
+trylist=( )
+[ -d "$CFGROOT/${EXACTPKG##*/}" -o -f "$CFGROOT/${EXACTPKG##*/}.$PKGSUFF" ] && trylist=( ${trylist[*]} $EXACTPKG)
+[ ${#ARGLIST[*]} -gt 0 ] && trylist=( ${trylist[*]} $(basename ${ARGLIST[0]}))
+[ -L .flxver ] && trylist=( ${trylist[*]} $(readlink .flxver))
+trylist=( ${trylist[*]} $NEWPKGRADIX-$NEWPKGVER )
+trylist=( ${trylist[*]} $NEWPKGRADIX )
+trylist=( ${trylist[*]} $(basename $(pwd)))
+trylist=( ${trylist[*]} "default")
+
+echo trylist=${trylist[*]}
+
+for NEARESTPKG in ${trylist[*]}; do
+ if [ -z "$(get_pkg_ver $NEARESTPKG)" ]; then
+ TEMP=$(sortnames $CFGROOT/$NEARESTPKG-[0-9]* | tail -1)
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG.* | tail -1)}
+ TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)}
+ #TEMP=${TEMP:-$(sortnames $CFGROOT/$NEARESTPKG | tail -1)}
+ [ "$TEMP" ] && NEARESTPKG=$(basename $TEMP) || continue
+ fi
+
+ RADIX=$(get_pkg_radix $NEARESTPKG)
+ VER=$(get_pkg_ver $NEARESTPKG)
+ BUILD=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+ #### [ "$(get_build_num $NEARESTPKG)" ] &&
+
+ [ -d "$CFGROOT/$NEARESTPKG" -o -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ] && break
+echo NEARESTPKG=$NEARESTPKG
+
+ ###TEMP=$(sortnames $CFGROOT/$NEARESTPKG-* | tail -1)
+ ###[ "$(get_build_num $TEMP)" ] && NEARESTPKG=$(basename $TEMP) && break
+done
+
+RADIX=$(get_pkg_radix $NEARESTPKG)
+VER=$(get_pkg_ver $NEARESTPKG)
+BUILD=$(get_build_num $NEARESTPKG)
+NEARESTPKG=${RADIX}${VER:+-$VER}${BUILD:+-$BUILD}
+
+echo "EXACTPKG=$EXACTPKG"
+echo "NEARESTPKG=$NEARESTPKG"
+
+# to be removed ## look if there was an argument, in which case we would treat it as a package
+# to be removed ## name (either source or destination, depending on the action). These variables
+# to be removed ## are set :
+# to be removed ## - ARGPKGFULL : full package name with version
+# to be removed ## - ARGPKGRADIX : package radix name (without version)
+# to be removed ## - ARGPKGVER : package version without -flx*
+# to be removed ## - ARGDISTVER : package build version (flx*)
+# to be removed #
+# to be removed #if [ ${#ARGLIST[*]} -gt 0 ]; then
+# to be removed # ARGPKGFULL=$(basename ${ARGLIST[0]})
+# to be removed # ARGPKGRADIX=$(get_pkg_radix $ARGPKGFULL)
+# to be removed # ARGPKGVER=$(get_pkg_ver $ARGPKGFULL)
+# to be removed # if echo $ARGPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # ARGDISTVER=$(get_build_num $ARGPKGFULL)
+# to be removed # fi
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGFULL* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER-* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-$ARGPKGVER* |tail -1)}
+# to be removed # ARGBASECFG=${ARGBASECFG:-$(sortnames $CFGROOT/$ARGPKGRADIX-* |tail -1)}
+# to be removed #fi
+# to be removed #
+# to be removed ## look for package name from the '.flxver' link in current dir, then dir name
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # PKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # PKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #PKGRADIX=$(get_pkg_radix $PKGFULL)
+# to be removed #PKGVER=$(get_pkg_ver $PKGFULL)
+# to be removed #
+# to be removed #if [ -z "$DISTVER" ] && echo $PKGFULL | grep -q -- "-flx\." ; then
+# to be removed # DISTVER=$(get_build_num $PKGFULL)
+# to be removed #fi
+# to be removed #
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGFULL* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER-* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-$PKGVER* |tail -1)}
+# to be removed #BASECFG=${BASECFG:-$(sortnames $CFGROOT/$PKGRADIX-* |tail -1)}
+# to be removed #
+# to be removed #
+# to be removed #
+# to be removed ## now process the destination parameters
+# to be removed #
+# to be removed #if [ -L .flxver ]; then
+# to be removed # NEWPKGFULL=$(readlink .flxver)
+# to be removed #else
+# to be removed # NEWPKGFULL=$(basename $(pwd))
+# to be removed #fi
+# to be removed #
+# to be removed #NEWPKGRADIX=$(get_pkg_radix $NEWPKGFULL)
+# to be removed #NEWPKGVER=$(get_pkg_ver $NEWPKGFULL)
+# to be removed #NEWPKGVER=${NEWPKGVER:-$PKGVER}
+# to be removed #
+# to be removed #if [ -z "$NEWDISTVER" ] && echo $NEWPKGFULL | grep -q -- "-flx\." ; then
+# to be removed # NEWDISTVER=$(get_build_num $NEWPKGFULL)
+# to be removed #fi
+# to be removed #NEWDISTVER=${NEWDISTVER:-$DISTVER}
+# to be removed #
+# to be removed ## recompute the new package version
+# to be removed #NEWBASECFG=${NEWBASECFG:-$NEWPKGRADIX-$NEWPKGVER-$NEWDISTVER}
+# to be removed #
+
+
+# now this is rather simple : for nearly all actions, NEWPKGFULL is used as the
+# directory name for the new package. If it cannot be found, all actions except
+# info and newpkg will fail. So we have to do a newpkg before using a new dir.
+
+if [ ! -d "$CFGROOT/$NEARESTPKG" -a ! -f "$CFGROOT/$NEARESTPKG.$PKGSUFF" ]; then
+ echo "Config directory <$NEARESTPKG> (NEARESTPKG) does not exist, use 'newpkg' first."
+ exit 1
+fi
+
+# source configuration
+ROOTDIR=${ROOTDIR:-$(pwd)/${INSTNAME}}
+
+
+CURPKG=$NEARESTPKG
+PKGRADIX=$(get_pkg_radix $NEARESTPKG)
+PKGVER=$(get_pkg_ver $NEARESTPKG)
+if echo $NEARESTPKG | grep -q -- "-flx\." ; then
+ DISTVER=$(get_build_num $NEARESTPKG)
+ NEARESTPKG=$PKGRADIX-$PKGVER-$DISTVER
+else
+ DISTVER=
+ NEARESTPKG=$PKGRADIX-$PKGVER
+fi
+
+CFGDIR=$CFGROOT/$CURPKG
+CFGFILE=$CFGDIR/$PKGRADIX.$CFGSUFF
+
+echo "CFGFILE=$CFGFILE, PKGVER=$PKGVER, CFGDIR=$CFGDIR"
+
+exit 0
+
+
+
+if [ -n "$CFGFILE" ]; then
+ CFGDIR=$NEWCFGROOT/$NEWBASECFG
+ . $CFGFILE
+else
+ #CFGFILE=`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-$FLXARCH.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*-${DISTVER:-*}-*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack[-_]*.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ #CFGFILE=${CFGFILE:-`find $CFGROOT/ -name "$pack.$CFGSUFF"|sed -e "s/\.$CFGSUFF\$//"|sort|tail -1`}
+ CFGFILE=`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-${DISTVER:-*}-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type d -name "$pack[-_]*-pkg"|sed -e "s/-pkg\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-${DISTVER:-*}-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+ CFGFILE=${CFGFILE:-`find $CFGROOT/ -maxdepth 1 -type f -name "$pack[-_]*-pkg.$PKGSUFF"|sed -e "s/-pkg\.$PKGSUFF\$//"|sort|tail -1`}
+
+ # to be completed
+
+ if [ -z "$CFGFILE" ]; then
+ echo "CFGFILE not found. Cannot continue." >&2
+ exit 1
+ fi
+
+ if [ -d $CFGFILE ]; then
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ else
+ CFGROOT=`dirname $CFGFILE`
+ CFGDIR=`basename $CFGFILE`-pkg
+ CFGFILE=$CFGROOT/$CFGDIR/$pack.$CFGSUFF
+ if [ ! -e $CFGROOT/$CFGDIR ]; then
+ echo "Opening package $CFGROOT/$CFGDIR.$PKGSUFF into $CFGROOT/$CFGDIR..."
+ mkdir -p $CFGROOT/$CFGDIR && tar -C $CFGROOT/$CFGDIR -Uxpf $CFGROOT/$CFGDIR.$PKGSUFF
+ if [ $? != 0 ]; then
+ echo "There was an error during this operation. You may have to manually clean $CFGROOT/$CFGDIR. Cannot continue !"
+ exit 1
+ else
+ echo "Done !"
+ fi
+ fi
+ fi
+
+ if [ -e "$CFGFILE" ]; then
+ . $CFGFILE
+ else
+ echo "CFGFILE ($CFGFILE) not found. Cannot continue." >&2
+ exit 1
+ fi
+ fi
+
+ if [ -z "$DISTVER" ]; then
+ if echo $CFGFILE | grep -q -- "-flx\." ; then
+ DISTVER=`echo $CFGFILE|sed 's/\(.*-\)\(flx.[0-9]\+\)\(.*\)/\2/'`
+ else
+ DISTVER='flx.1'
+ fi
+ fi
+
+ echo $packver | grep -q -- "-flx\."
+ if [ $? != 0 ] ; then
+ packver=$packver-$DISTVER
+ fi
+
+ echo $packver | grep -q -- "-$FLXARCH\$"
+ if [ $? != 0 ] ; then packver=$packver-$FLXARCH ; fi
+
+ prefix=${packver%%[._-][0-9]*}
+ suffix=${packver#$prefix[._-]}
+ PKGVER=${suffix%-flx*}
+ PKGRADIX=$prefix
+ #echo "packver=$packver suffix=$suffix PKGVER=$PKGVER"
+ if [ -z "$DISTVER" ]; then
+ DISTVER=${suffix#$PKGVER-}
+ if [ "$DISTVER" = "$PKGVER" ]; then
+ DISTVER="flx.1"
+ else
+ DISTVER=${DISTVER%-*}
+ fi
+ fi
+
+ case "$FLXARCH" in
+ i686) arch=i686 cpu=i686 basearch=i386 ;;
+ i486) arch=i486 cpu=i486 basearch=i386 ;;
+ i386) arch=i386 cpu=i386 basearch=i386 ;;
+ *) arch=i586 cpu=i686 basearch=i386 ;;
+ esac
+
+ if [ -z "$FLXMAKE" ]; then
+ FLXMAKE=make
+ fi
+
+
+ if [ -z "${PATCH_LIST}" ]; then
+ PATCH_LIST=${CFGFILE%%.$CFGSUFF}.diff
+ if [ ! -e ${PATCH_LIST} ]; then
+ unset PATCH_LIST
+ fi
+ fi
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE PATCH_LIST FILE_LIST
+
+ declare -f pre_$ACTION > /dev/null && ( pre_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f do_$ACTION > /dev/null && ( do_$ACTION )
+ [ $? != 0 ] && exit $?
+ declare -f post_$ACTION > /dev/null && ( post_$ACTION )
+ [ $? != 0 ] && exit $?
+ fi
+fi
+
diff --git a/scripts/pkg-0.7.0 b/scripts/pkg-0.7.0
new file mode 100755
index 0000000..889a034
--- /dev/null
+++ b/scripts/pkg-0.7.0
@@ -0,0 +1,1928 @@
+#!/bin/bash
+
+# pkg - Formilux package builder - version 0.7.0 - 2005-10-04
+#
+# Copyright (C) 2001-2005 Benoit Dolez & Willy Tarreau
+# mailto: benoit@ant-computing.com,willy@ant-computing.com
+#
+# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt )
+
+######## Please update this version ########
+PKG_VERSION=0.7.0
+############################################
+
+## WARNING ##
+# This version is not compatible with pkg scripts written for pre-0.2.0 versions
+
+# Usage:
+# pkg <action> [ pkg [ pkg2 ] ]
+#
+# pkg newpkg [ new_pkg [ old_pkg ] ]
+# [new_pkg]=[old_pkg]
+# ex: pkg newpkg openssl-0.9.6g-flx0.1 openssl-0.9.6d-flx0.1
+# pkg newpkg apache apache-1.3
+# pkg newpkg bash
+# pkg newpkg gcc gcc-3*flx*.1
+#
+# pkg setpkg [ new_pkg ]
+# ex: pkg setpkg openssl-0.9.6g-flx0.1
+#
+# pkg { info | cat | edit | unpack } [ pkg ]
+# ex: pkg info
+# pkg info bash
+# pkg edit modutils-2.4
+# pkg cat gzip-1.3
+#
+# pkg { compile,build,prepack,strip,pack,delpack,release,clean }*
+#
+# pkg { patch | unpatch } [ patch_name ]
+#
+# pkg { any_command } [ any_args ]
+#
+
+# don't return stupid names, and we also want dotfiles and use extended globbing
+shopt -s nullglob
+shopt -s dotglob
+shopt -s extglob
+
+# disable pathnames expansion
+set -o noglob
+
+# change the default mask to avoid common security problems
+umask og-w
+
+# set some constants
+KERNDIR=${KERNDIR:-/usr/src/linux}
+FLXHOSTOS=${FLXHOSTOS:-$(uname -s|tr 'A-Z' 'a-z')}
+FLXHOSTARCH=${FLXHOSTARCH:-$(uname -m)}
+FLXHOST=${FLXHOST:-$FLXHOSTARCH-$FLXHOSTOS}
+
+# FLXTARGARCH can be influenced by FLXARCH if defined
+FLXTARGOS=${FLXTARGOS:-$FLXHOSTOS}
+FLXTARGARCH=${FLXTARGARCH:-$FLXARCH}
+FLXTARGARCH=${FLXTARGARCH:-$FLXHOSTARCH}
+FLXTARG=${FLXTARG:-$FLXTARGARCH-$FLXTARGOS}
+FLXARCH=${FLXARCH:-$FLXTARGARCH}
+
+DEVROOT=${DEVROOT:-/var/flx-dev}
+PKGROOT=${PKGROOT:-/var/flx-pkg}
+# use -p1 by default to apply a patch
+PATCH_LEVEL=${PATCH_LEVEL:-1}
+# the suffix that we use to name different builds. It also matches build
+# versions with this name followed by a number (BUILDVER)
+BUILDSFX=${BUILDSFX:-flx}
+BUILDVER=${BUILDVER:-0}
+
+PKGSUFF="tgz"
+CFGSUFF="cfg"
+INSTNAME=".flxdisk"
+LINKNAME=".flxpkg"
+
+FIND_CMD=pkgfilefind
+CURDIR="$(pwd)"
+
+FILE_LIST=
+
+# all the directories that should be ignored by do_pack
+EXCLUDE_LIST=( bin boot dev etc etc/opt home lib lib/modules mnt mnt/disk mnt/cdrom mnt/usb mnt/nfs mnt/floppy opt opt/bin opt/lib opt/sbin proc root root/bin sbin sbin/init.d usr usr/bin usr/lib usr/sbin usr/share usr/share/examples var var/tmp var/run var/cache var/empty var/lib var/log var/spool var/adm )
+
+######
+###### here are some undertermined type functions
+######
+
+# check that this utility's version is at least as high as the version
+# specified in $1. Returns 0 if OK, 1 if inferior.
+
+function check_pkg_version {
+ local version="$1"
+ local major minor patch
+ local mymajor myminor mypatch
+
+ major=${version%%.*}
+ minor=${version#$major.}; minor=${minor%%.*}
+ patch=${version##*.}
+
+ mymajor=${PKG_VERSION%%.*}
+ myminor=${PKG_VERSION#$mymajor.}; myminor=${myminor%%.*}
+ mypatch=${PKG_VERSION##*.}
+
+ if [ -n "$major" ]; then
+ [ "$mymajor" -gt "$major" ] && return 0
+ [ "$mymajor" -lt "$major" ] && return 1
+ else
+ return 0
+ fi
+
+ if [ -n "$minor" ]; then
+ [ "$myminor" -gt "$minor" ] && return 0
+ [ "$myminor" -lt "$minor" ] && return 1
+ else
+ return 0
+ fi
+
+ if [ -n "$patch" ]; then
+ [ "$mypatch" -gt "$patch" ] && return 0
+ [ "$mypatch" -lt "$patch" ] && return 1
+ else
+ return 0
+ fi
+ return 0
+}
+
+
+# find packageable files (that can't be automaticaly created) and return only
+# their relative path to the argument.
+
+function pkgfilefind {
+ local start=${1%%/}
+ local dir
+ local -a exclude_args=( )
+
+ for dir in "${EXCLUDE_LIST[@]}"; do
+ exclude_args=( "${exclude_args[@]}" -and -not -path "${start}/${dir}" )
+ done
+
+ find ${start} -not -path ${start} \( -empty -o \! -type d -o \! -uid 0 -o \! -gid 0 -o \! -perm 0755 \) "${exclude_args[@]}" -printf "%P\n"
+}
+
+
+# resolves a symlink to an absolute location.
+# usage: resolve_link <link_dir> <link_pointer>
+function resolve_link {
+ # prints $1 if $2 is empty, and prints $2 if it starts with a '/'.
+ if [ -z "$2" ]; then
+ dir="$1"
+ elif [ -z "${2##/*}" ]; then
+ dir="$2"
+ else
+ dir="$1/$2"
+ fi
+
+ # resolve '//', '/./', '/.$', '^./' always one at a time, from left to right,
+ # then enclose with '/'
+ while [ -n "$dir" ]; do
+ if [ -z "${dir##./*}" ]; then dir="${dir#./}"
+ elif [ -z "${dir##/*}" ]; then dir="${dir#/}"
+ elif [ -z "${dir%%*/.}" ]; then dir="${dir%/.}"
+ elif [ -z "${dir%%*/}" ]; then dir="${dir%/}"
+ elif [ -z "${dir##*//*}" ]; then dir="${dir/\/\//\/}"
+ elif [ -z "${dir##*/./*}" ]; then dir="${dir/\/.\//\/}"
+ else
+ dir="/$dir/"
+ break;
+ fi
+ done
+
+ # now resolve '/../' from left to right only.
+ while [ -z "${dir##*/../*}" ]; do
+ # if dir goes past root, we must truncate it
+ if [ -z "${dir##/../*}" ]; then
+ dir="/${dir##/../}"
+ else
+ # turn all '/x/../' into '/'
+ odir="$dir"
+ dir="$(echo "$dir" | sed -e 's,/[^/]*/\.\./,/,')"
+ [ "$dir" = "$odir" ] && break
+ fi
+ done
+
+ [ "$dir" = "/" ] || dir="${dir#/}"
+ [ "$dir" = "/" ] || dir="${dir%/}"
+ echo "$dir"
+}
+
+# this function analyses an ELF executable and prints its name along with some
+# informations such as :
+# %N:soname : for libraries, their soname
+# %D:libname : library it depends on (their soname)
+# %P:provide : feature provided by a library, in the form soname/version
+# %R:require : required feature, in the for soname/version
+function elf_get_dep {
+ local elf
+ for elf in "$@"; do
+ $OBJDUMP -p "$elf" | (
+ soname_str=""
+ soname=""
+ needed=""
+ provide=""
+ require=""
+ curreq=""
+ section=""
+ while read; do
+ case "$REPLY" in
+ Dynamic\ Section*)
+ section="dynamic" ;;
+ Version\ defin*)
+ section="definitions" ;;
+ Version\ Refer*)
+ section="references" ;;
+ *)
+ set -- $REPLY
+ if [ "$section" = "dynamic" ]; then
+ if [ "$1" = "NEEDED" ]; then
+ needed="${needed:+$needed }%D:$2"
+ elif [ "$1" = "SONAME" ]; then
+ soname="$2"
+ soname_str="${soname_str:+$soname_str }%N:$2"
+ fi
+ elif [ "$section" = "definitions" ]; then
+ if [ "$#" = "4" -a "$2" = "0x00" ]; then
+ provide="${provide:+$provide }%P:$soname/$4"
+ fi
+ elif [ "$section" = "references" ]; then
+ if [ "$#" = "3" -a "$1" = "required" ]; then
+ curreq="${3%:}"
+ elif [ "$#" = "4" ]; then
+ require="${require:+$require }%R:$curreq/$4"
+ fi
+ fi
+ ;;
+ esac
+ done
+ echo "${elf:+$elf }${soname_str:+$soname_str }${needed:+$needed }${provide:+$provide }${require}"
+ )
+ done
+ return 0
+}
+
+
+######
+###### here are some functions for manipulating package names
+######
+
+# returns the radix from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns 'pkg'
+function get_pkg_radix {
+ echo ${1%%[-_][0-9]*}
+}
+
+# returns the version from a package name. Eg: 'pkg-1.2.3a-flx0.12' returns '1.2.3a'
+function get_pkg_ver {
+ local ver=${1#${1%%[_-][0-9]*}[._-]}
+ ver=${ver%-${BUILDSFX}*}
+ [ "$ver" = "$1" ] || echo $ver
+}
+
+# returns the build number from a package name when appropriate, or empty when
+# there's nothing. Eg: 'pkg-1.2.3a-flx0.12-pkg' returns 'flx0.12'
+function get_build_num {
+ local build=${1##${1%%-${BUILDSFX}*([0-9]).+([0-9])*}} # -flx0.12-pkg
+ build=${build%%${build##-${BUILDSFX}*([0-9]).+([0-9])}} # -flx0.12
+ build=${build#-} # flx0.12
+ [ "$build" != "$1" ] && echo $build
+}
+
+# returns the build number following a known build. Eg: 'flx0.12' returns 'flx0.13'
+function get_next_build {
+ local prefix=${1%%.*}
+ local suffix=${1##*.}
+ echo $prefix.$[$suffix + 1]
+}
+
+# This function accepts a list of versionned names, and returns them sorted by
+# version number. The names must NOT contain any '|' or '~' character, or they
+# will be discarded. Names that don't have any version are also discarded.
+# Note: package names can be full path names.
+function sortnames {
+ local IFS FIELD NUMERIC_VERSION ALPHA_VERSION VERSION
+ local base version rest filename i t file flist
+ local -a list
+
+ # a numeric versions consists in a series of numbers delimited by dots, and
+ # optionnally ending with one or several dots, so that strange namings are
+ # correctly processed. An alphanumeric version consists in everything that
+ # cannot match a numeric version, optionnaly ending with one or more dots.
+ IFS=$'\n'
+ FIELD='\([^|]*\)'
+ NUMERIC_VERSION='\([0-9]\+\(\.[0-9]\+[.]*\)*\)'
+ ALPHA_VERSION='\([^0-9~|.]\+[.]*\)'
+ VERSION="\($NUMERIC_VERSION\|$ALPHA_VERSION\)"
+
+ # make the list appear in the form 'package|version|rest|full_name'
+ list=($(echo "$*" | grep -v "|~" | sed -e "s,$VERSION,\1|," \
+ -e "s,^$FIELD|$VERSION,\1|\2|," \
+ -e "s,^$FIELD|$FIELD|$FIELD$,\1|\2|\3~\1\2\3," \
+ -e "s,^[^|]*|[^|]*$,," \
+ -e 's,^[^|]*/,,'))
+
+ # there's a risk that it doesn't complete for all the list, and that some
+ # elements keep a "rest". But what can we do about it ?
+
+ # we loop on the list if there's at least one element
+ # this will build alternating series of numeric-only and non-numeric
+ # substrings, packed by six.
+ while [ "${list[0]}" ] ; do
+ # now we add sub-version delimiters ','
+ list=( $(for file in ${list[*]} ; do
+ IFS="|~" ; set -- $file
+ base=$1 ; version=$2 ; rest=$3 ; filename=$4
+ if [ -z "$rest" ] ; then
+ IFS="." ; set -- $version
+ # we append a dot to the version for sed below.
+ echo "$base,$1,$2,$3,$4,$5,$6|.~$filename"
+ continue
+ fi
+ IFS="." ; set -- $version
+ echo "$base,$1,$2,$3,$4,$5,$6|$rest~$filename"
+ done | sed -e "s/^$FIELD|\($VERSION\|\.\)/\1|\2|/"))
+ IFS=$'\n'
+ # and we stop once everyone has "|\.|~" (no rest)
+ if echo "${list[*]}" | grep -vq "|\.|~" ; then : ; else break ; fi
+ done
+
+ # now construct a field separator list for 'sort'. Since it's full of bugs,
+ # the only way for it to work is -k1,1 -k2,2n -k3,3n ...
+ # To match most cases, we'll assume that most of our packages will be
+ # numbered NNNNNNAAAAAANNN... (6 numbers, 6 alpha, repeating).
+ IFS=',' ; i=1 ; flist=
+ for t in ${list[0]%%|*} ; do
+ if [ $i -eq 1 -o $[(($i-2)/6)&1] -eq 1 ]; then
+ flist="$flist${flist:+ }-k$i,$i"
+ else
+ flist="$flist${flist:+ }-k$i,$i"n
+ fi
+ i=$[$i+1];
+ done
+
+ IFS=$'\n'$'\t'' '
+ # Do not use '-u' since sort is stupid enough to remove nearly identical
+ # lines !
+ #echo "${list[*]}" | sort -t , -u $flist | cut -f2 -d~
+ echo "${list[*]}" | sort -t , $flist | cut -f2 -d~
+}
+
+
+######
+###### here are some "exported" functions used to ease file manipulation
+######
+
+#
+# usage: set_perm uid:gid mode file...
+function set_perm {
+ local own mode
+ [ $# -gt 2 ] || return 1
+ own=$1 ; shift
+ mode=$1 ; shift
+ chown $own "$@"
+ chmod $mode "$@"
+ return 0
+}
+
+#
+# usage: set_default_perm $ROOTDIR/start_dir
+function set_default_perm {
+ local start_dir=$1
+ local strip_dir=${ROOTDIR%%/}
+ local type executable script
+
+ if [ -z "$1" ]; then
+ echo; echo "### ERROR! set_default_perm called without arguments !!!"
+ echo "### You must specify the root directory to fix."
+ return 1
+ fi
+
+ echo
+ echo "PKG : Fixing permissions in $1 ... "
+ echo " Please wait..."
+ echo " Fixing directories..."
+
+ # first pass : check directories
+ find $start_dir -type d | while read; do
+ case "${REPLY##$strip_dir}" in
+ /|/.)
+ set_perm root:root 755 "$REPLY"
+ ;;
+ /sbin|/sbin/init.d|/usr/sbin)
+ set_perm root:adm 751 "$REPLY"
+ ;;
+ /root)
+ set_perm root:root 700 "$REPLY"
+ ;;
+ /etc/formilux|/var/core)
+ set_perm root:adm 750 "$REPLY"
+ ;;
+ *)
+ if [ ! -u "$REPLY" -a ! -g "$REPLY" -a ! -k "$REPLY" ]; then
+ set_perm root:root 755 "$REPLY"
+ fi
+ ;;
+ esac
+ done
+
+ echo " Fixing special files..."
+ # second pass : check special files (block, char, fifo)
+ find $start_dir -not -xtype d -a -not -xtype f | while read; do
+ if [ -b "$REPLY" -o -c "$REPLY" -o -p "$REPLY" ]; then
+ set_perm root:root 600 "$REPLY"
+ fi
+ done
+
+ echo " Fixing regular files..."
+ # third pass : check regular files
+ find $start_dir -type f | while read; do
+ if [ -u "$REPLY" -o -g "$REPLY" ]; then
+ # remove other r/w on setuid/setgid
+ chmod o-rw "$REPLY"
+ else
+ type=$(file -z "$REPLY")
+ executable=0
+ script=0
+
+ if [ -z "${type//*ELF [0-9][0-9]-bit */}" -o \
+ -z "${type//*ERROR: Corrupt*/}" ]; then
+ executable=1
+ elif [ -z "${type//*script*/}" ]; then
+ script=1
+ fi
+
+ #echo "processing ${REPLY##$strip_dir}"
+ case "${REPLY##$strip_dir}" in
+ /bin/*|/usr/bin/*|/opt/bin/*|/opt/*/bin/*|/sbin/init.d/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm ug-w,o-rw "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm ugo-w "$REPLY"
+ else
+ set_perm root:adm ugo-w "$REPLY"
+ fi
+ ;;
+ /sbin/*|/usr/sbin/*|/opt/sbin/*|/opt/*/sbin/*)
+ if [ $executable -gt 0 ]; then
+ set_perm root:adm u-sw,g-wx,o-rwx "$REPLY"
+ elif [ $script -gt 0 ]; then
+ set_perm root:adm u-sw,g-swx,o-rwx "$REPLY"
+ else
+ # neither an exec nor a script, no need to execute it !
+ set_perm root:adm ug-swx,o-wx "$REPLY"
+ fi
+ ;;
+ /lib/*.so|/lib/*.so.*|/usr/lib/*.so|/usr/lib/*.so.*|\
+ /opt/lib/*.so|/opt/lib/*.so.*|/opt/*/lib/*.so|/opt/*/lib/*.so.*)
+ set_perm root:adm ug-sw,o-w,+x "$REPLY"
+ ;;
+ /lib/*.[ao]|/usr/lib/*.[ao]|/opt/lib/*.[ao]|/opt/*/lib/*.[ao])
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /etc/profile.d/*.var)
+ set_perm root:adm 0644 "$REPLY"
+ ;;
+ /etc/profile.d/*)
+ set_perm root:adm 0755 "$REPLY"
+ ;;
+ /boot/*/*|/boot/*|/etc/*/*)
+ set_perm root:adm ug-swx,o-rwx "$REPLY"
+ ;;
+ /etc/*)
+ set_perm root:adm ugo-swx "$REPLY"
+ ;;
+ /*/man/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/doc/*|/usr/share/*/doc/*|/usr/info/*|/usr/share/*/info/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ /usr/share/examples/*|/usr/share/examples/*/*)
+ set_perm root:man ugo-swx "$REPLY"
+ ;;
+ *)
+ # chgrp adm if not setgid and group==root
+ # chmod ugo-w if user==root
+ ;;
+ esac
+ fi
+ done
+ echo "PKG : done fixing permissions."
+}
+
+######
+###### here are "exported" functions, which can be used and redefined by build.cfg
+######
+
+# builds everything from a clean start
+function do_build {
+ local ACTION
+ # ACTION will be inherited by other functions
+ for ACTION in clean compile prepack strip pack ; do
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ done
+ return 0
+}
+
+# this function returns one exact package name from a list of potentially
+# interesting ones, classed from higher preference to lower. They are all
+# passed as strings, constituting packages names, or some of the following
+# special names :
+# %P => use current directory as the source for the name
+# %L => use the package pointed to by the ${LINKNAME} link
+# %D => use the default package
+# If several packages match a given pattern, the user is asked to select the
+# desired one.
+# The resulting package name is returned in REPLY, and the package directoryy
+# is returned in PKGDIR whenever possible.
+function get_name {
+ local pattern pkg_name
+ local radix ver build
+ local -a rel_list dev_list sort_list
+ local i search_dir
+
+ REPLY=
+ for pattern in $*; do
+ search_dir=
+ if [ "$pattern" = "%P" ]; then
+ search_dir="${CURDIR%/*}" ; search_dir="/${search_dir#/}"
+ pattern="$(basename $CURDIR)"
+ elif [ "$pattern" = "%L" ]; then
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ return
+ elif [ -L ${LINKNAME} -a -d ${LINKNAME}/. ]; then
+ # the link is always an EXACT name, so we return it as-is.
+ pattern="$(readlink ${LINKNAME})"
+ PKGDIR="$pattern/."
+ REPLY="${pattern##*/}"
+ return
+ else
+ continue
+ fi
+ elif [ "$pattern" = "%D" ]; then
+ pattern=default
+ fi
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+
+ REPLY=
+ # we loop until pkg_name is empty, which allows recursive choices.
+ while [ "$pkg_name" ]; do
+ # now we'll try to build a list of potentially matching packages for
+ # each pattern. We'll reduce the original name until either we have
+ # a non-empty list or the package name is void.
+ rel_list=( ); dev_list=( )
+ while [ "$pkg_name" -a -z "$rel_list" -a -z "$dev_list" ]; do
+ rel_list=( $(find ${search_dir:+$search_dir/} $PKGROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%p\n" 2>/dev/null) )
+ if [ "$release_only" != "1" ]; then
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${pkg_name} -printf "%p\n" 2>/dev/null) )
+ fi
+
+ if [ -z "${rel_list[*]}" -a -z "${dev_list[*]}" ]; then
+ radix=$(get_pkg_radix $pkg_name)
+ ver=$(get_pkg_ver $pkg_name)
+ build=$(get_build_num $pkg_name)
+
+ if [ "$ver" -a "$ver" != "*" -a "$radix" != "$pkg_name" ]; then
+ if [ "$build" -a "$build" != "*" ]; then
+ pkg_name=${radix}-${ver}-*
+ elif [ "${ver%.*}" != "$ver" ]; then
+ # let's reduce the version precision
+ pkg_name=${radix}-${ver%.*}-*
+ else
+ pkg_name=${radix}-*
+ fi
+ else
+ break
+ fi
+ else
+ break
+ fi
+ done
+
+ # we're prepared to break the big loop, unless someone sets pkg_name again.
+ pkg_name=
+ sort_list=( $(sortnames ${dev_list[*]} ${rel_list[*]}) )
+
+ # if we matched nothing, we jump to the next pattern, and if we matched
+ # exactly one result, we return it immediately.
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ continue
+ elif [ ${#sort_list[*]} -eq 1 ]; then
+ REPLY="${sort_list[0]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ fi
+
+ # now, we'll present the possible names to the user.
+ i=0
+ printf " %5d : - None of the following packages -\n" 0
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, or a 'D' for dev.
+ # FIXME : we risk a wrong match here (eg: flx0.1 <-> flx0.10)
+ if [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ fi
+ i=$[$i+1]
+ done
+ echo
+
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i
+ if [ -z "$i" ]; then
+ # empty string, we use the last choice which is the preferred one.
+ i=${#sort_list[*]}
+ REPLY="${sort_list[$[$i-1]]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll allow to recursively re-select
+ #pattern=${pattern}*${i}
+ pattern=${i}
+ radix=$(get_pkg_radix $pattern)
+ ver=$(get_pkg_ver $pattern)
+ build=$(get_build_num $pattern)
+ pkg_name=${radix:-*}-${ver:-*}-${build:-*}
+ break;
+ elif [ $i -le 0 ]; then
+ # if the user explicitly replied "0", then he wants other choices.
+ break;
+ elif [ $i -le ${#sort_list[*]} ]; then
+ REPLY="${sort_list[$[$i-1]]}"
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+ return
+ fi
+ done
+ # we get here only either if someone tries to refine the package name or
+ # if he refuses these ones.
+ done
+ done
+ PKGDIR="${REPLY/*}"
+ REPLY="${REPLY##*/}"
+}
+
+# choose a package and make ${LINKNAME} point to it
+function do_setpkg {
+ rm -f ${LINKNAME}
+ ln -s $PKGDIR ${LINKNAME}
+}
+
+
+# look for existing packages, and propose a new version for the current one
+function do_newpkg {
+ local -a rel_list dev_list sort_list
+ local pkg_name new_name
+ local radix ver build
+
+ set -o noglob
+ if [ -e ${LINKNAME} ]; then
+ if [ -L ${LINKNAME} ]; then
+ if [ -d ${LINKNAME}/. ]; then
+ echo "Error! the link '${LINKNAME}' already exists. Please remove it by manually."
+ exit 1
+ else
+ rm -f ${LINKNAME}
+ fi
+ else
+ echo "Error! '${LINKNAME}' already exists and is not a link. Please remove it by manually."
+ exit 1
+ fi
+ fi
+
+ if [ $# -gt 0 ]; then
+ # the user has specified an explicit version string
+ # either it's the complete name, or it's the complete name followed
+ # by an '=' sign preceding the old name.
+ new_name=${1%%=*}
+ if [ $# -gt 1 ]; then
+ pkg_name=$2
+ elif [ "$new_name" != "$1" ]; then
+ pkg_name=${1##*=}
+ fi
+ fi
+
+ if [ -z "$new_name" ]; then
+ # the user has not specified any version string, we'll use the directory
+ # name.
+ new_name=$(basename $CURDIR)
+ fi
+
+ rel_list=( ); dev_list=( )
+
+ # now we'll have to guess the new package name.
+ # The build rev part (flx*.*) will be ignored.
+ # We'll look for existing packages with the exact
+ # name+version, and if found, use this + the first unused build number.
+ # If not found, a new package is created with the exact name and flx0.1
+
+ radix=$(get_pkg_radix $new_name)
+ ver=$(get_pkg_ver $new_name)
+ build=$(get_build_num $new_name)
+ new_name=${radix:-*}-${ver:-*}
+
+ rel_list=( $(find $PKGROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) )
+ dev_list=( $(find $DEVROOT/ -maxdepth 1 -type d -name ${new_name}\* -printf "%p\n" 2>/dev/null) )
+ sort_list=(${rel_list[*]} ${dev_list[*]})
+
+ if [ "${sort_list[*]}" ]; then
+ sort_list=($(IFS=$'\n'; echo "${sort_list[*]%-${BUILDSFX}*([0-9]).+([0-9])*}" | sort -u) )
+ sort_list=( $(sortnames ${sort_list[*]}) )
+ if [ "${radix/*\\**/}" -a "${ver/*\\**/}" ] && \
+ ! (IFS=$'\n';echo "${sort_list[*]}"|grep -q "^$new_name\$"); then
+ # if the package was properly named, and not already listed, let's
+ # propose it on last position.
+ sort_list=( ${sort_list[*]} $new_name )
+ fi
+ # echo "package_list : ${sort_list[*]}"
+
+ # now, we'll present the possible names to the user
+ if [ ${#sort_list[*]} -gt 1 ]; then
+ local i=0
+ echo; echo ">>> Please select the name of the package to create :";echo
+ while [ $i -lt ${#sort_list[*]} ]; do
+ # we'll display an 'R' in front of released names, 'P'
+ # in front of packaged ones, or a 'D' for dev.
+ if [ -e "${sort_list[$i]}/RELEASED" ]; then
+ printf " %5d : [R] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ elif [ "${rel_list[*]/${sort_list[$i]}/}" != "${rel_list[*]}" ]; then
+ printf " %5d : [P] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ else
+ printf " %5d : [D] %s\n" $[$i+1] ${sort_list[$i]##*/}
+ fi
+ i=$[$i+1]
+ done
+
+ echo
+ while : ; do
+ echo -n "Choice [${sort_list[${#sort_list[*]}-1]##*/}]: "; read i
+ if [ -z "$i" ]; then
+ new_name=${sort_list[${#sort_list[*]}-1]}
+ break
+ elif [ "${i//[0-9]/}" ]; then
+ # not a plain integer, we'll take it for the new name
+ new_name=$i
+ break;
+ elif [ $i -ge 1 -a $i -le ${#sort_list[*]} ]; then
+ new_name=${sort_list[$[$i-1]]}
+ break;
+ fi
+ done
+ else
+ new_name=${sort_list[0]}
+ fi
+ # we'll search for all packages starting with the same name and version
+ # in both release and dev dirs. Then we'll be able to deduce the latest
+ # build number used.
+ #sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}*.\* -printf "%f\n" 2>/dev/null|sort -u) )
+ sort_list=( $(find $PKGROOT/ $DEVROOT/ -maxdepth 1 -type d -name ${new_name}-${BUILDSFX}${BUILDVER}.\* -printf "%p\n" 2>/dev/null|sort -u) )
+ if [ ${#sort_list[*]} -eq 0 ]; then
+ # this can happen with new BUILDSFX/BUILDVER
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ else
+ sort_list=( $(sortnames ${sort_list[*]} ))
+ new_name=${new_name}-$(get_next_build $(get_build_num ${sort_list[${#sort_list[*]}-1]}))
+ fi
+ else
+ if [ -z "${radix/*\\**/}" -o -z "${ver/*\\**/}" ]; then
+ echo "Error: no existing package matches $new_name, and wildcards"
+ echo "or incomplete names cannot be part of a real name."
+ exit 1
+ fi
+ # we keep new_name since it's syntactically correct
+ new_name=${new_name}-${BUILDSFX}${BUILDVER}.1
+ fi
+
+ #echo "new_name: $new_name"
+
+ # if pkg_name is unspecified, we'll use the current directory name to guess
+ # the source package, else we'll use the explicit name
+ echo; echo ">>> Please select the package to use as a reference :"; echo
+
+ get_name $pkg_name $new_name %P %D
+
+ if [ -z "$REPLY" ]; then
+ echo "No reference package found (even default). Please specify one."
+ exit 1
+ fi
+
+ echo "Using '$REPLY'."
+
+ if [ -e "$PKGROOT/$REPLY/build.cfg" ]; then
+ pkg_name=$PKGROOT/$REPLY
+ else
+ pkg_name=$DEVROOT/$REPLY
+ fi
+
+ # new_name is always relative to DEVROOT
+ #echo "new_name: $new_name ; old_name: $(basename $pkg_name)"
+
+ # we should verify that new_name/released doesn't exist before extracting
+ # anything into it, or even that new_name doesn't exist at all.
+ new_name=$DEVROOT/$new_name
+ if [ -e $new_name ]; then
+ echo "Error! new directory $new_name already exists. Refusing to overwrite."
+ exit 1
+ fi
+
+ rm -f ${LINKNAME} && mkdir -p $new_name && ln -s $new_name ${LINKNAME} && \
+ tar -C $pkg_name --exclude='./compiled/*' --exclude='./RELEASED*' --exclude='./pkg.*' \
+ --exclude='./CFLAGS' --exclude='./.dep' --exclude='./.lst' --exclude='./.tgz' \
+ --exclude='./Version' --one-file-system -cpf - . | tar -C $new_name -xf - || (rmdir $new_name ; rm -f ${LINKNAME})
+ chmod u+rw $new_name/build.cfg
+
+ echo "A new package '$(basename $new_name)' has been created as '$new_name', based on '$(basename $pkg_name)'."
+ echo "The link '${LINKNAME}' now points to it."
+ echo
+ if [ $(find $new_name/patches -type f |wc -l) -gt 0 ]; then
+ echo "*** Warning: there are patches to be applied, use >>>pkg info<<< ***"
+ echo
+ fi
+ set +o noglob
+ return 0
+}
+
+
+function do_edit {
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo "Editing $CFGFILE in read-only mode..."
+ vi -R $CFGFILE
+ else
+ echo "Editing $CFGFILE..."
+ vi $CFGFILE
+ fi
+}
+
+function do_cat {
+ cat $CFGFILE
+}
+
+function do_lst {
+ local FPNAME
+
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ cat $FPNAME.lst
+}
+
+function pre_info {
+ echo "Information for package '${EXACTPKG##*/}' (\${EXACTPKG##*/}) :"
+
+ echo " Package name : $PKGRADIX (\$PKGRADIX)"
+ echo " Package version : $PKGVER (\$PKGVER)"
+ echo " Distrib version : $DISTVER (\$DISTVER)"
+ echo -n " Config. file : "
+ if [ -e $CFGFILE ]; then
+ echo "$CFGFILE"
+ else
+ echo "none found."
+ fi
+ echo " Package file : $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF"
+ echo -n " Package size : "
+ if [ -e $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF ]; then
+ echo "$(du -b $PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF |cut -f1) bytes."
+ else
+ echo "does not exist yet."
+ fi
+ if [ -n "${PATCH_LIST}" ]; then
+ echo " Patches list : ${PATCH_LIST}"
+ else
+ echo " Empty patch list."
+ fi
+
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ echo " Last ChangeLog : $(grep -m 1 '^[0-9]\{4\}' $PKGDIR/ChangeLog)"
+ else
+ echo " No ChangeLog."
+ fi
+
+ if [ -e "$PKGDIR/RELEASED" ]; then
+ echo " Tagged as RELEASED"
+ else
+ echo " UNRELEASED."
+ fi
+
+ return 0
+}
+
+# does only compile, not changing the current config
+function do_compile_only {
+ $FLXMAKE
+ return $?
+}
+
+# new simplified name for 'config_only', which is deprecated, not changing current scripts.
+function do_config {
+ if declare -f do_config_only >/dev/null 2>&1; then
+ do_config_only
+ return $?
+ else
+ return 0
+ fi
+}
+
+# configures and compiles
+function do_compile {
+ ( do_config ) && ( do_compile_only )
+}
+
+# preparatory work for prepack()
+function pre_prepack {
+ if [ "$UID" != "0" -a "$force" != "1" ]; then
+ echo "You must specify '--force' to install as non-root"
+ exit 1
+ fi
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}"
+ # permissions are important here because we don't want to get an
+ # inherited setgid or something alike on the root dir
+ [ ! -d "$ROOTDIR" ] && { mkdir -p $ROOTDIR; chown 0:0 $ROOTDIR; chmod 0755 $ROOTDIR; }
+ #mkdir -p "$EXAMPLEDIR"
+ return 0
+}
+
+# build link in /opt directory
+# INPUT: selected path to creation in /opt
+function build_opt {
+ local dir
+
+ if [ -d $ROOTDIR/opt ] ; then (
+ [ $# = 0 ] && set -- bin sbin lib
+ set +o noglob
+ shopt -s nullglob
+ cd $ROOTDIR/opt
+ for dir in $* ; do
+ mkdir $dir
+ dirs=( */$dir )
+ [ -n "${dirs[*]}" ] && find ${dirs[@]}/ -xtype f -perm +111 -exec ln -s ../{} $dir \; -printf "ln -s ../%p $ROOTDIR/opt/$dir\n"
+ done
+ ) fi
+ return 0
+}
+
+# deletes the current prepack directory.
+function do_delpack {
+ # WARNING! here, we don't use $ROOTDIR because we don't want to risk
+ # erasing a wrong directory as root !
+ [ -d "$(pwd)/${INSTNAME}" ] && rm -rf "$(pwd)/${INSTNAME}"
+ return 0
+}
+
+# does a full clean
+function do_clean {
+ make distclean || make mrproper || make clean
+ ( do_delpack )
+ return 0
+}
+
+# applies all the patches to the current sources
+# files which match *.rej and *~ will be deleted
+function do_patch {
+ local i
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -Np$PATCH_LEVEL
+ else
+ patch -Np$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# reverts all the patches from the current sources
+# files which match *.rej and *~ will be deleted
+function do_unpatch {
+ local i
+ local UNPATCH_LIST=""
+
+ find . -name '*.rej' -o -name '*~' | xargs rm -f
+
+ for i in ${PATCH_LIST}; do
+ UNPATCH_LIST=( $i ${UNPATCH_LIST[@]} )
+ done
+
+ for i in ${UNPATCH_LIST[@]}; do
+ [ ! -e "$PKGDIR/patches/$i" -a -e "$PKGDIR/patches/$i.gz" ] && i="$i.gz"
+ if [ -z "${i##*.gz}" ]; then
+ gzip -cd < $PKGDIR/patches/$i | patch -RNp$PATCH_LEVEL
+ else
+ patch -RNp$PATCH_LEVEL < $PKGDIR/patches/$i
+ fi
+ done
+
+ if [ -z "$(find . -name '*.rej')" ]; then
+ find . -name '*~' | xargs rm -f
+ fi
+ return 0
+}
+
+# extracts a binary package into $ROOTDIR, to reflect the state prior to pack().
+function do_unpack {
+ local FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.$PKGSUFF
+ mkdir -p $ROOTDIR
+ cd $ROOTDIR
+
+ echo -n "Extracting $FILE into $ROOTDIR ... "
+ tar zUxpf $FILE >/dev/null 2>&1
+ echo "done."
+ return 0
+}
+
+# strips symbols from executables before building the package.
+# Abort if ROOTDIR doesn't exist (thus needing prepack() first).
+function do_strip {
+ if [ ! -d $ROOTDIR ] ; then
+ echo "Error: directory $ROOTDIR doesn't exist. Make sure you did 'prepack'."
+ exit 1
+ fi
+ #find $ROOTDIR/. -type f | xargs file | grep ":.*executable.*not stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ # allow executable and shared (.so), but not relocatable (.o), both stripped or not stripped
+ find $ROOTDIR/. -type f | xargs file | grep ":.*ELF.*\(executable\|\shared\).*stripped" | cut -f1 -d: | xargs ${STRIP} -x --strip-unneeded -R .note -R .comment > /dev/null 2>&1
+ return 0
+}
+
+# forces pack() to strip before starting, even if do_pack() is redefined by the user.
+function pre_pack {
+ # in the mean time, we avoid removing this directory since it could have
+ # been brought legally by an authorized package.
+ #[ $(find $EXAMPLEDIR | wc -l) = 1 ] && rmdir -p $EXAMPLEDIR 2>/dev/null
+ ( do_strip )
+ return 0
+}
+
+# this function finds perl dependencies for a given file.
+# It's only called from _do_pack_files() and do_pack()
+function get_perl_depend {
+ local filename=$1
+ local dep DEP
+ local DEP_FILE=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH.dep
+
+ DEP=$(grep "^\(.*['{\"]\)*[ ]*\(require\|use\) \+['\"]*[a-zA-Z][a-z:/A-Z0-9_-]*[; '\"]" $filename | \
+ sed -e 's/.*\(require\|use\) \+["'\'']\?\([^'\''" };]\+\)["'\'']\?/§§\2§§/g' \
+ -e 's/§§\([^§]\+\)§§[^§]*/ \1/g' | \
+ sed 's@::@/@g')
+ if [ "x$DEP" != "x" ] ; then
+ echo -n "$filename" >> $DEP_FILE
+ for dep in $DEP ; do
+ if [ "x${dep/*.*}" != "x" ] ; then
+ echo -n " $dep.pm" >> $DEP_FILE
+ else
+ echo -n " $dep" >> $DEP_FILE
+ fi
+ done
+ echo >> $DEP_FILE
+ fi
+}
+
+# same as pack, except that it uses files in the current directory as the root
+# entries, and that no strip, link nor compression is performed.
+# Only entries listed in the files pointed to by $* find their way to the archive.
+# This function relies on get_perl_depend().
+function _do_pack_files {
+ local DEP_FILE FPNAME ext
+ local FILE_LIST=$*
+
+ echo -n "Updating timestamps ... "
+ find . -not -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ echo -n "Creating $DEP_FILE ... "
+ touch $DEP_FILE
+ ( set +f; shopt -s nullglob ; shopt -s dotglob ; find * -type f -o -type l ) | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ # we try the special case of the '.' entry which is needed to set the root permissions.
+ # this entry must be set as "." in FILE_LIST.
+ if grep -q '^.[ ]' $FILE_LIST; then
+ set -- $(grep '^.[ ]' $FILE_LIST)
+ owner=${2%%:*}
+ group=${2##*:}
+ echo "d $3 $owner $group 0 -------------------------------- 0 ."
+ fi > $FPNAME.lst
+ (flx sign --no-depth --ignore-dot $(cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,') >> $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+
+ # we want everything, including directories.
+ cut -f1 -d' ' $FILE_LIST|sed -e 's,/$,,' | tar -T - --no-recursion --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# packs the prepacked files into a new file located in $DEVROOT.
+# any eventual old package is removed.
+# this function relies on _do_pack_files(), get_perl_depend(),
+function do_pack {
+ local DEP_FILE FPNAME
+ local FILE_LISTS ext
+
+ # normalize the list with an absolute path for each entry
+ for file in $FILE_LIST ; do
+ if [ -z "${file##/*}" ]; then
+ FILE_LISTS="$FILE_LISTS $file"
+ else
+ FILE_LISTS="$FILE_LISTS $CURDIR/$file"
+ fi
+ done
+ # FIXME: is this normal ???
+ if [ ! -d "$ROOTDIR" ] ; then
+ echo "Error: \$ROOTDIR doesn't point to a valid directory : $ROOTDIR"
+ exit 1
+ fi
+ cd $ROOTDIR
+
+ # use the file list when available
+ if [ "$FILE_LISTS" ]; then
+ _do_pack_files $FILE_LISTS
+ return $?
+ fi
+
+## ( find lib -type l -name "lib*.so*" | xargs rm -f ; \
+## find usr/lib -type l -name "lib*.so*" | xargs rm -f ; \
+## ldconfig -nr . ) > /dev/null 2>&1
+
+ echo -n "Updating libraries ... "
+ ldconfig -nr . lib usr/lib opt/*/lib > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Updating timestamps ... "
+ find . ! -type l | xargs touch -m
+ echo "done."
+
+ # full path name of different files
+ FPNAME=$PKGDIR/compiled/${EXACTPKG##*/}-$FLXARCH
+ DEP_FILE=$FPNAME.dep
+
+ # rebuild dependencies file, first is a diff file
+ echo -n "Creating $DEP_FILE ... "
+ rm -rf $DEP_FILE
+ if [ -e $DEP_FILE.diff ] ; then cat $DEP_FILE.diff > $DEP_FILE ; fi
+
+ # build a one shot function 'add' to add dependences
+ oldadd="$(declare -f add)"
+ # usage: add file [...] need file [...]
+ function add {
+ local file files
+ # remove file
+ while [ $# -gt 0 -a "x$1" != xneed ] ; do
+ files=( "$1" "${files[@]}" )
+ shift
+ done
+ [ $# -le 1 ] && return
+ shift
+ for file in "${files}" ; do echo "$file $*" >> $DEP_FILE ; done
+ }
+ # load dependences function
+ declare -f load_deps > /dev/null && ( load_deps )
+ # reset 'add' function
+ unset add
+ # reload old one
+ [ -n "$oldadd" ] && eval "$oldadd"
+
+ touch $DEP_FILE
+ find . \( -type f -o -type l \) -printf "%P\n" | while read ; do
+ case $REPLY in
+ *.pm|*.pl|*.ph)
+ get_perl_depend $REPLY
+ ;;
+ */man/man*/*.[0-9n])
+ if [ "${REPLY/*gz}" ] ; then
+ if [ -L $REPLY ] ; then
+ LINK=$(readlink $REPLY)
+ rm $REPLY
+ ln -s $LINK.gz $REPLY.gz
+ else
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ fi
+ echo "$REPLY \$MAN" >> $DEP_FILE
+ ;;
+ */info/*.info|*/info/*.info-[0-9]*)
+ if [ "${REPLY/*gz}" ] ; then
+ gzip -f -9 $REPLY
+ chmod 644 $REPLY.gz
+ fi
+ echo "$REPLY \$INFO" >> $DEP_FILE
+ ;;
+ bin/*|sbin/*|lib/*|*/sbin/*|*/bin/*|*/lib/*|*/libexec/*)
+ flr="$(file $REPLY)"
+ case "$flr" in
+ *\ shell\ *)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') \$SHELL">>$DEP_FILE
+ ;;
+ *perl\ commands*)
+ echo "$REPLY $(head -1 $REPLY| sed -e 's/^#\! *\([^ ]\+\).*/\1/') ">>$DEP_FILE
+ get_perl_depend $REPLY
+ ;;
+ *:\ symbolic\ link*)
+ echo "$REPLY %L:$(readlink $REPLY)" >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *dynamically\ linked*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ *\ ELF\ [0-9][0-9]-bit\ *shared\ object*)
+ elf_get_dep $REPLY >> $DEP_FILE
+ ;;
+ esac
+ ;;
+ esac
+ done
+ echo "done."
+
+ echo -n "Creating $FPNAME.lst ... "
+ ($FIND_CMD . | xargs flx sign --ignore-dot --no-depth > $FPNAME.lst) > /dev/null 2>&1
+ echo "done."
+
+ echo -n "Creating $FPNAME.$PKGSUFF ... "
+ # we want everything, and directories only if they're empty.
+ # All this without './' we shouldn't get an empty line since .
+ # should contain at least what we want to tar !
+ $FIND_CMD . | tar --no-recursion -T - --numeric-owner -cf - | gzip -9 >$FPNAME.$PKGSUFF 2>/dev/null
+
+ # create shortcuts ".*" for tgz, dep and lst files
+ for ext in dep lst tgz; do
+ rm -f $PKGDIR/.$ext
+ ln -sf compiled/${EXACTPKG##*/}-$FLXARCH.$ext $PKGDIR/.$ext
+ done
+ echo "done."
+ return 0
+}
+
+
+# this function prepares all needed variables to work in a cross-compiler environment
+function set_cross_environment {
+ # Handling of cross-compilers :
+ # - setting CC will force both HOSTCC and FLXCROSSCC
+ # - setting HOSTCC will keep it
+ # - setting FLXCROSS will set CC
+ # - setting FLXCROSSCC will set CC whatever FLXCROSS is.
+
+ if [ -z "$FLX_CROSS_OPT_SET" ]; then
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ AS=${AS:-as}
+ LD=${LD:-ld}
+ AR=${AR:-ar}
+ NM=${NM:-nm}
+ RANLIB=${RANLIB:-ranlib}
+ STRIP=${STRIP:-strip}
+ OBJDUMP=${OBJDUMP:-objdump}
+
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTAS=${HOSTAS:-$AS}
+ HOSTLD=${HOSTLD:-$LD}
+ HOSTAR=${HOSTAR:-$AR}
+ HOSTNM=${HOSTNM:-$NM}
+ HOSTSTRIP=${HOSTSTRIP:-$STRIP}
+ HOSTOBJDUMP=${HOSTOBJDUMP:-$OBJDUMP}
+
+ if [ -n "$FLXCROSS" ]; then
+ CC=${FLXCROSS}${CC} ; CC=${FLXCROSSCC:-$CC}
+ CXX=${FLXCROSS}${CXX} ; CXX=${FLXCROSSCXX:-$CXX}
+ AS=${FLXCROSS}${AS} ; AS=${FLXCROSSAS:-$AS}
+ LD=${FLXCROSS}${LD} ; LD=${FLXCROSSLD:-$LD}
+ AR=${FLXCROSS}${AR} ; AR=${FLXCROSSAR:-$AR}
+ NM=${FLXCROSS}${NM} ; NM=${FLXCROSSNM:-$NM}
+ RANLIB=${FLXCROSS}${RANLIB} ; RANLIB=${FLXCROSSRANLIB:-$RANLIB}
+ STRIP=${FLXCROSS}${STRIP} ; STRIP=${FLXCROSSSTRIP:-$STRIP}
+ OBJDUMP=${FLXCROSS}${OBJDUMP} ; OBJDUMP=${FLXCROSSOBJDUMP:-$OBJDUMP}
+ fi
+ # specify that we don't want to do this again
+ FLX_CROSS_OPT_SET=1
+ fi
+}
+
+# this function sets all needed compiler options
+function set_compiler_options {
+ # now we'll set default ARCH and CPU for the current FLXARCH if none is set.
+ case "$FLXARCH" in
+ i586|"") arch=${arch:-i586} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i686) arch=${arch:-i686} cpu=${cpu:-i686} basearch=${basearch:-i386} ;;
+ i486) arch=${arch:-i486} cpu=${cpu:-i486} basearch=${basearch:-i386} ;;
+ i386) arch=${arch:-i386} cpu=${cpu:-i386} basearch=${basearch:-i386} ;;
+ parisc) arch=${arch:-1.1} cpu=${cpu:-7100LC} basearch=${basearch:-1.1} ;;
+ sparc) arch=${arch:-sparc} cpu=${cpu:-sparc} basearch=${basearch:-sparc} ;;
+ sparc64) arch=${arch:-ultrasparc} cpu=${cpu:-ultrasparc} basearch=${basearch:-ultrasparc} ;;
+ ev[456]*|arm*|ppc*) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ *) arch=${arch:-$FLXARCH} cpu=${cpu:-$FLXARCH} basearch=${basearch:-$FLXARCH} ;;
+ esac
+
+ # FIXME: this should go into a per-architecture file
+ case "$FLXARCH" in
+ *86)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="i586"
+ FLX_ARCH_SMALL="$basearch"
+ GCC_ARCH_CURRENT="-march=$arch"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mcpu=$cpu"
+ GCC_CPU_COMMON="-mcpu=$FLX_ARCH_COMMON"
+ GCC_CPU_SMALL="-mcpu=$FLX_ARCH_SMALL"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+
+ parisc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="${FLXARCH##parisc}" ; FLX_ARCH_CURRENT="${FLX_ARCH_CURRENT:-1.1}"
+ FLX_ARCH_COMMON="1.0"
+ FLX_ARCH_SMALL="1.0"
+ GCC_ARCH_CURRENT="-march=$FLX_ARCH_CURRENT"
+ GCC_ARCH_COMMON="-march=$FLX_ARCH_COMMON"
+ GCC_ARCH_SMALL="-march=$FLX_ARCH_SMALL"
+ GCC_CPU_CURRENT="-mschedule=7100LC"
+ GCC_CPU_COMMON="-mschedule=7100"
+ GCC_CPU_SMALL="-mschedule=7100"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ sparc*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ ev[456]*)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_ARCH_CURRENT="-mcpu=$arch"
+ GCC_ARCH_COMMON="-mcpu=$arch"
+ GCC_ARCH_SMALL="-mcpu=$arch"
+ GCC_CPU_CURRENT="-mtune=$cpu"
+ GCC_CPU_COMMON="-mtune=$cpu"
+ GCC_CPU_SMALL="-mtune=$cpu"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ ;;
+
+ *)
+ CC=${CC:-gcc}
+ CXX=${CXX:-g++}
+ FLX_ARCH_CURRENT="$FLXARCH"
+ FLX_ARCH_COMMON="$FLXARCH"
+ FLX_ARCH_SMALL="$FLXARCH"
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -malign-jumps=0"
+ GCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $CC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ GCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ GCC_OPT_FAST="-O2 -fno-align-jumps"
+ GCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ case "$FLXHOSTARCH" in
+ *86)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ parisc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ sparc*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ ev[456]*)
+ HOSTCC_OPT_FASTEST="$GCC_OPT_FASTEST"
+ HOSTCC_OPT_FAST="$GCC_OPT_FAST"
+ HOSTCC_OPT_SMALL="$GCC_OPT_SMALL"
+ ;;
+
+ *)
+ HOSTCC=${HOSTCC:-$CC}
+ HOSTCXX=${HOSTCXX:-$CXX}
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -malign-jumps=0"
+ HOSTCC_OPT_SMALL="-Os -malign-jumps=0 -malign-loops=0 -malign-functions=0"
+ if [ $TESTGCC -gt 0 ] && $HOSTCC -fno-align-loops -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then
+ HOSTCC_OPT_FASTEST="-O3 -fomit-frame-pointer"
+ HOSTCC_OPT_FAST="-O2 -fno-align-jumps"
+ HOSTCC_OPT_SMALL="-Os -fno-align-functions -fno-align-loops -fno-align-jumps -fno-align-labels"
+ fi
+ ;;
+ esac
+
+ export FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL
+ export FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG
+ export CC CXX AS LD AR OBJDUMP NM STRIP RANLIB GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL
+ export GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL
+ export GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL
+ export HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL
+
+ return 0
+}
+
+# displays used environment variables
+function print_env {
+ set_cross_environment
+ set_compiler_options
+ for i in FLXHOSTOS FLXHOSTARCH FLXHOST FLXTARGOS FLXTARGARCH FLXTARG \
+ FLX_ARCH_CURRENT FLX_ARCH_COMMON FLX_ARCH_SMALL FLXARCH \
+ FLXCROSS FLXTOOLDIR FLXROOTDIR \
+ AR AS CC CXX LD NM OBJDUMP RANLIB STRIP \
+ GCC_ARCH_CURRENT GCC_ARCH_COMMON GCC_ARCH_SMALL \
+ GCC_CPU_CURRENT GCC_CPU_COMMON GCC_CPU_SMALL \
+ GCC_OPT_FASTEST GCC_OPT_FAST GCC_OPT_SMALL \
+ HOSTCC HOSTCXX \
+ HOSTCC_OPT_FASTEST HOSTCC_OPT_FAST HOSTCC_OPT_SMALL \
+ FLXMAKE FLXPMAKE; do
+ echo "$i=$(eval echo \$$i)"
+ done
+ exit 0
+}
+
+function usage {
+ # this is needed to present current options to the user
+ set_cross_environment
+ set_compiler_options
+
+ echo "PKG version $PKG_VERSION - Formilux package build utility."
+ echo "Usage:"
+ echo " pkg [-options]* <action> [ pkg [ pkg2 ] ]"
+ echo
+ echo " pkg newpkg [ new_pkg [ old_pkg ] ]"
+ echo " pkg newpkg [ newpkg ]=[ old_pkg ]"
+ echo " ex: pkg newpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1 openssl-0.9.6d-${BUILDSFX}${BUILDVER}.1"
+ echo " pkg newpkg =apache-1.3"
+ echo " pkg newpkg bash"
+ echo " pkg newpkg gcc gcc-3*${BUILDSFX}*.1"
+ echo
+ echo " pkg setpkg [ new_pkg ]"
+ echo " ex: pkg setpkg openssl-0.9.6g-${BUILDSFX}${BUILDVER}.1"
+ echo
+ echo " pkg { info | cat | edit | unpack | changelog } [ pkg ]"
+ echo " ex: pkg info"
+ echo " pkg info bash"
+ echo " pkg edit modutils-2.4"
+ echo " pkg cat gzip-1.3"
+ echo
+ echo " pkg { clean | compile | config | compile_only | build }*"
+ echo " pkg { prepack | strip | pack | delpack | release }*"
+ echo
+ echo " pkg { patch | unpatch } [ patch_name ]"
+ echo
+ echo " pkg { any_command } [ any_args ]"
+ echo
+ echo "User variables are :"
+ echo "PKGROOT : directory containing released packages <$PKGROOT>"
+ echo "DEVROOT : directory containing unreleased packages <$DEVROOT>"
+ echo "ROOTDIR : base directory for package installation (not source), <$ROOTDIR>"
+ echo "FLXARCH : architecture to use for the package, <$FLXARCH>"
+ echo "KERNDIR : kernel sources location, if needed, <$KERNDIR>"
+ echo
+ echo "Architecture-specific variables :"
+ echo -e " CURRENT\t|COMMON\t|SMALL"
+ echo -e "FLX_ARCH_ : $FLX_ARCH_CURRENT\t| $FLX_ARCH_COMMON\t| $FLX_ARCH_SMALL"
+ echo -e "GCC_ARCH_ : $GCC_ARCH_CURRENT\t| $GCC_ARCH_COMMON\t| $GCC_ARCH_SMALL"
+ echo -e "GCC_CPU_ : $GCC_CPU_CURRENT\t| $GCC_CPU_COMMON\t| $GCC_CPU_SMALL"
+ echo "GCC_OPT_FASTEST=$GCC_OPT_FASTEST"
+ echo "GCC_OPT_FAST=$GCC_OPT_FAST"
+ echo "GCC_OPT_SMALL=$GCC_OPT_SMALL"
+ echo
+ echo "Use pkg --env to get all variables."
+
+# Those two are not user-settable anymore
+# echo "CFGFILE : force to use of a .pkg, <$CFGFILE>"
+# echo "DISTVER : build version (${BUILDSFX}${BUILDVER}.1)"
+ exit 1
+}
+
+# displays usage
+function do_help {
+ usage
+ return 0
+}
+
+# creates a new changelog entry and prompts the user to add information.
+function do_changelog {
+ # Let's create a new changelog entry
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t* '; echo ''; echo '.' ;
+ echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+
+ # we'll ask the user to fill the changelog
+ vi -c ":3" $PKGDIR/ChangeLog
+ return 0
+}
+
+# marks the current package as released
+function do_release {
+ local last_pkg
+
+ echo "#####################################################"
+ echo "# Release command not implemented yet ! Aborting... #"
+ echo "#####################################################"
+ #exit 1
+ # some important checks before things get wrong
+ if [ -z "$PKGROOT" -o -z "$PKGDIR" -o -z "$EXACTPKG" ]; then
+ echo "Critical error : PKGROOT, PKGDIR and EXACTPKG must be set !"
+ exit 1
+ fi
+
+ if ! [ -s "$PKGDIR/.lst" -a -e "$PKGDIR/.dep" -a -s "$PKGDIR/.tgz" ]; then
+ echo "Nothing to be released in this package."
+ echo "Please ensure that .lst, .dep and .tgz exist."
+ exit 1
+ fi
+
+ # first, the destination directory must not exist
+ if [ -d "$PKGROOT/${EXACTPKG##*/}" ]; then
+ if [ -e "$PKGROOT/${EXACTPKG##*/}/RELEASED" ]; then
+ echo "Error: This package already exists."
+ else
+ echo "Error: The package directory $PKGROOT/${EXACTPKG##*/} already exists."
+ fi
+ exit 1
+ fi
+
+ # identify last changelog entry
+ last_pkg=""
+ if [ -e "$PKGDIR/ChangeLog" ]; then
+ last_pkg=$(grep -m 1 $'^[\t ]*\* released' "$PKGDIR/ChangeLog")
+ last_pkg=${last_pkg##*released }
+ fi
+
+ if [ "$last_pkg" != "$EXACTPKG" ]; then
+ # Let's create a new changelog entry
+ touch $PKGDIR/ChangeLog # avoid error message in case it doesn't exist
+ (echo '0a'; date +"%Y/%m/%d %H:%M $LOGNAME@$HOSTNAME";
+ echo ''; echo $'\t'"* released $EXACTPKG";
+ echo ''; echo '.' ; echo '1,$wq') | ed $PKGDIR/ChangeLog >/dev/null
+ fi
+
+ # we'll ask the user to fill the changelog
+ vi -c ":4" $PKGDIR/ChangeLog
+
+#<FIXME.WTA>
+#traiter le cas où PKGROOT/PKGDIR existe déjà mais pour d'autres archi
+#</FIXME>
+
+ if ! mv $PKGDIR $PKGROOT/ ; then
+ echo "Error: cannot move the package to the released directory. Cancelling."
+ # the mv here fails atomically, so nothing's lost in PKGDIR, but we have
+ # to clean a possible partial copy
+ rm -rf $PKGROOT/${EXACTPKG##*/}
+ exit 2
+ fi
+
+ touch $PKGROOT/${EXACTPKG##*/}/RELEASED
+
+ return 0
+}
+
+# usage: install-files <owner> <perm> <dest> file...
+#
+function install-files {
+ local owner="$1" ; shift
+ local perm="$1" ; shift
+ local dst="$1" ; shift
+ local file
+
+ [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}"
+ cp -dpfP "$@" "$ROOTDIR/$dst/" && \
+ ( cd "$ROOTDIR/$dst" && chown -h $owner "${@##*/}" && chmod $perm "${@##*/}" )
+
+ [ -n "$FILE_LIST" ] && for file in "$@"; do echo "$dst/$file $owner $perm"; done >> $FILE_LIST
+}
+
+# usage: install-file <owner> <perm> <file> <dest>
+#
+function install-file {
+ local owner="$1" ; shift
+ local perm="$1" ; shift
+ local src="$1" ; shift
+ local dst="$1" ; shift
+
+ [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}"
+ if cp -dpfP "$src" "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst" \
+ && [ ! -L "$ROOTDIR/$dst" ]; then chmod $perm "$ROOTDIR/$dst"; fi
+
+ [ -n "$FILE_LIST" ] && echo $dst $owner $perm >> $FILE_LIST
+}
+
+# usage: install-dir <owner> <perm> <dir>...
+#
+function install-dir {
+ local owner="$1" ; shift
+ local perm="$1" ; shift
+ local dst
+
+ for dst in "$@"; do
+ mkdir -pm $perm "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst"
+ [ -n "$FILE_LIST" ] && echo $dst $owner $perm >> $FILE_LIST
+ done
+}
+
+# usage: install-ln <owner> <target> <dest>
+#
+function install-ln {
+ local owner="$1" ; shift
+ local target="$1" ; shift
+ local dst="$1" ; shift
+
+ [ -n "${dst##*/*}" -o -d "$ROOTDIR/${dst%/*}" ] || mkdir -p "$ROOTDIR/${dst%/*}"
+ ln -s "$target" "$ROOTDIR/$dst" && chown -h $owner "$ROOTDIR/$dst"
+ [ -n "$FILE_LIST" ] && echo $dst $owner 000 >> $FILE_LIST
+}
+
+
+######
+###### here are some functions used only from main
+######
+
+function known_cmd {
+ declare -f pre_$ACTION > /dev/null && { ( pre_$ACTION $* ) || return $?; }
+ declare -f do_$ACTION > /dev/null && { ( do_$ACTION $* ) || return $?; }
+ declare -f post_$ACTION > /dev/null && { ( post_$ACTION $* ) || return $?; }
+ return 0
+}
+
+
+######
+###### here is the main entry point
+######
+
+# scan the command line
+
+release_only=0
+force=0
+TESTGCC=0
+PRINTUSAGE=0
+PRINTENV=0
+ARGLIST=( )
+ACTION=
+CHAINCMD=1
+
+[ $# -eq 0 ] && PRINTUSAGE=1
+
+while [ $# -gt 0 ] ; do
+ case "$1" in
+ --force )
+ force=1
+ ;;
+ --help|-h)
+ PRINTUSAGE=1
+ ;;
+ --env|-e)
+ PRINTENV=1
+ TESTGCC=1
+ ;;
+ --rel|-r*)
+ release_only=1
+ ;;
+ --)
+ shift
+ ARGLIST=(${ARGLIST[*]} $*)
+ break
+ ;;
+ -* )
+ PRINTUSAGE=1
+ ;;
+ *)
+ ARGLIST=(${ARGLIST[*]} "$1")
+ ;;
+ esac
+ shift
+done
+
+
+#echo "arglist=${ARGLIST[*]}"
+
+[ $PRINTENV -gt 0 ] && print_env
+[ $PRINTUSAGE -gt 0 ] && usage
+[ ${#ARGLIST[*]} -lt 1 ] && usage
+
+# Some actions can be chained, others not. we'll get the longest
+# possible chain, and stop once we encounter a non-chainable action
+
+while [ $CHAINCMD -gt 0 -a ${#ARGLIST[@]} -gt 0 ]; do
+ set -o noglob
+ ACTION=${ARGLIST[0]}
+ TESTGCC=0
+ # unset ARGLIST[0] ### doesn't work in scripts with this shitty bash !!!
+ ARGLIST[0]= ; ARGLIST=( ${ARGLIST[*]} ) # gets expanded with shitty bash !
+
+ case "$ACTION" in
+ newpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ # newpkg is the only command which doesn't start by a package lookup.
+ ;;
+ setpkg)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name $1 %P default
+ ;;
+ info|edit|cat|unpack|changelog)
+ CHAINCMD=0
+ KNOWNCMD=1
+ get_name ${ARGLIST[0]} %L %P %D
+ [ -d "$PKGDIR" ] || PKGDIR=
+ ;;
+ patch|unpatch)
+ CHAINCMD=0
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ compile_only|config|config_only|compile|build)
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ TESTGCC=1
+ # get_name %L
+ ;;
+ prepack|strip|pack|delpack|release|clean)
+ KNOWNCMD=1
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ *)
+ CHAINCMD=0
+ KNOWNCMD=0
+ if [ -r ".flxpkg/Version" ]; then
+ REPLY="$(cat .flxpkg/Version)"
+ REPLY="${REPLY##*/}"
+ PKGDIR="$CURDIR/.flxpkg/."
+ else
+ REPLY="$(basename $(readlink ${LINKNAME}) 2>/dev/null)"
+ PKGDIR="$(readlink ${LINKNAME} 2>/dev/null)"
+ fi
+ # get_name %L
+ ;;
+ esac
+
+ [ $CHAINCMD -gt 0 ] && (echo;echo "===> PKG: starting [$ACTION] <===") >&2
+
+ set +o noglob
+ if [ "$ACTION" != "newpkg" ]; then
+ if [ -z "$REPLY" ]; then
+ echo "Error: package name not found."
+ exit 1
+ fi
+ EXACTPKG="$PKGDIR/$REPLY"
+
+ if [ -z "$PKGDIR" ]; then
+ if [ -e "$PKGROOT/${EXACTPKG##*/}/build.cfg" ]; then
+ PKGDIR="$PKGROOT/${EXACTPKG##*/}"
+ else
+ PKGDIR="$DEVROOT/${EXACTPKG##*/}"
+ fi
+ fi
+ CFGFILE="$PKGDIR/build.cfg"
+ PKGRADIX="$(get_pkg_radix ${EXACTPKG##*/})"
+ PKGVER="$(get_pkg_ver ${EXACTPKG##*/})"
+ DISTVER="$(get_build_num ${EXACTPKG##*/})"
+ ROOTDIR="${ROOTDIR:-$CURDIR/${INSTNAME}}"
+ EXAMPLEDIR="${ROOTDIR}/usr/share/examples"
+
+ # for compatibility with old functions. Not used anywhere outside this script.
+ packver="${EXACTPKG##*/}"
+ pack="$PKGRADIX"
+ fi
+
+ set_cross_environment
+ set_compiler_options
+
+ if [ "$ACTION" != "newpkg" ]; then
+ . $CFGFILE
+ fi
+
+ # FLXMAKE is used for sequential make and FLXPMAKE for parallel make
+ FLXMAKE="${FLXMAKE:-make}"
+ FLXPMAKE="${FLXPMAKE:-$FLXMAKE}"
+
+ export DISTVER PKGRADIX PKGVER FLXMAKE FLXPMAKE PATCH_LIST FILE_LIST
+
+# echo "ACTION=$ACTION, KNOWNCMD=$KNOWNCMD, CHAINCMD=$CHAINCMD"
+# echo "ARGLIST=${ARGLIST[*]}"
+
+ if [ $KNOWNCMD -gt 0 ]; then
+ known_cmd ${ARGLIST[*]} || exit 1
+ else
+ if declare -f do_$ACTION >/dev/null; then
+ ( do_$ACTION ${ARGLIST[*]} ) || exit 1
+ fi
+ fi
+ [ $CHAINCMD -gt 0 ] && (echo "===> PKG: end of [$ACTION] <===";echo) >&2
+
+ # now, we'll loop only if we were in a chainable action
+done
+
+[ $CHAINCMD -gt 0 ] && (echo "===> PKG: [END] <===";echo) >&2
+exit 0
+