GDSS_OBJS=warehouse.o
OBJS= acl.o boot.o directory.o hesiod.o hosts.o mailhub.o \
- ndb.o network.o nfs.o pobox.o print.o zephyr.o \
- @GDSS_OBJS@
+ ndb.o network.o nfs.o pobox.o postoffice.o print.o \
+ www.o zephyr.o @GDSS_OBJS@
GDSS_CFILES=warehouse.c
CFILES= acl.c boot.c directory.c hesiod.c hosts.c mailhub.c \
- ndb.c network.c nfs.c pobox.c print.c zephyr.c \
- @GDSS_CFILES@
+ ndb.c network.c nfs.c pobox.c postoffice.c print.c \
+ www.c zephyr.c @GDSS_CFILES@
GDSS_TARGET=warehouse.gen
TARGET= acl.gen boot.gen directory.gen hesiod.gen hosts.gen \
mailhub.gen ndb.gen network.gen nfs.gen pobox.gen \
- print.gen zephyr.gen @GDSS_TARGET@
+ postoffice.gen print.gen www.gen zephyr.gen @GDSS_TARGET@
-SCRIPTS=boot.sh hesiod.sh mailhub.sh nfs.sh null.sh print.sh \
- sapprint.gen sapprint.sh warehouse.sh
+SCRIPTS=boot.sh hesiod.sh mailhub.sh nfs.sh null.sh \
+ postoffice.sh print.sh sapprint.gen sapprint.sh warehouse.sh \
+ www.sh
.SUFFIXES: .pc .gen
zephyr.gen: zephyr.o libdcm.a $(MR_LIBDEP)
$(CC) -o $@ $(LDFLAGS) zephyr.o libdcm.a $(SQL_LIBS) $(LIBS)
+
+postoffice.gen: postoffice.o libdcm.a $(MR_LIBDEP)
+ $(CC) -o $@ $(LDFLAGS) postoffice.o libdcm.a $(SQL_LIBS) $(LIBS)
+
+www.gen: www.o libdcm.a $(MR_LIBDEP)
+ $(CC) -o $@ $(LDFLAGS) www.o libdcm.a $(SQL_LIBS) $(LIBS)
+
--- /dev/null
+/* $Id$
+ *
+ * This generates the post office location data.
+ *
+ * tom@mit.edu
+ *
+ * Copyright 1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#include <mit-copyright.h>
+#include <moira.h>
+#include <moira_site.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include "util.h"
+
+EXEC SQL INCLUDE sqlca;
+
+RCSID("$Header$");
+
+
+#ifndef PO_SUBDIR
+#define PO_SUBDIR "postoffice"
+#endif
+
+#define MAX_RECSIZE 1000
+
+char *whoami = "postoffice.gen";
+char *db = "moira/moira";
+
+void pobox(char *);
+
+
+int main(int argc, char **argv)
+{
+ char cmd[BUFSIZ];
+ char po_dir[MAXPATHLEN], wpo_dir[MAXPATHLEN];
+ struct stat sb;
+ char *c;
+ int flag;
+
+ initialize_sms_error_table();
+
+ if (argc == 1)
+ sprintf(po_dir, "%s/%s", DCM_DIR, PO_SUBDIR);
+ else
+ {
+ sprintf(po_dir, "%s", argv[1]);
+ /* fake out dcm - we'll append .out later */
+ if (c = strrchr(po_dir, '.'))
+ *c = '\0';
+ }
+ sprintf(wpo_dir, "%s~", po_dir);
+
+ if (argc > 2)
+ {
+ fprintf(stderr, "usage: %s [outdir]\n", argv[0]);
+ exit(MR_ARGS);
+ }
+
+ if (stat(wpo_dir, &sb) < 0)
+ {
+ if (errno == ENOENT)
+ {
+ if (mkdir(wpo_dir, 0700) < 0)
+ {
+ fprintf(stderr, "%s: unable to make directory %s (%s))\n",
+ whoami, wpo_dir, strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "%s: cannot stat %s (%s)\n", whoami, wpo_dir,
+ strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ }
+ else if (!S_ISDIR(sb.st_mode))
+ {
+ fprintf(stderr, "%s: %s not a directory\n" , whoami, wpo_dir);
+ exit(MR_CCONFIG);
+ }
+
+ EXEC SQL CONNECT :db;
+
+ flag = 0;
+ if (stat(po_dir, &sb) == 0)
+ {
+ if (ModDiff (&flag, "filesys", sb.st_mtime))
+ exit(MR_DATE);
+ }
+ if (flag < 0)
+ {
+ fprintf(stderr, "%s: %s does not need to be rebuilt.\n", whoami, po_dir);
+ unlink(wpo_dir);
+ }
+ else
+ {
+ fprintf(stderr, "%s: building po databases...\n", whoami);
+ pobox(wpo_dir);
+
+ if (stat(po_dir, &sb) != -1)
+ {
+ fprintf(stderr, "%s: removing %s\n", whoami, po_dir);
+ sprintf(cmd, "rm -r %s", po_dir);
+ if (strncmp(po_dir, wpo_dir, strlen(po_dir)))
+ exit(MR_CCONFIG);
+ if (system(cmd))
+ {
+ fprintf(stderr, "%s: unable to remove %s (%s)", whoami, po_dir,
+ strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ }
+
+ rename(wpo_dir, po_dir);
+ }
+
+ fprintf(stderr, "%s: building tar file...\n", whoami);
+ sprintf(cmd, "(cd %s; tar cf - . ) > %s.out", po_dir, po_dir);
+ if (system(cmd))
+ exit(MR_TAR_FAIL);
+
+ exit(MR_SUCCESS);
+}
+
+void pobox(char *path)
+{
+ char *c;
+ char mdir[MAXPATHLEN];
+ char mout[MAXPATHLEN], qout[MAXPATHLEN];
+ struct stat sb;
+ FILE *moutp, *qoutp;
+
+ EXEC SQL BEGIN DECLARE SECTION;
+ char machine[MACHINE_NAME_SIZE];
+ char label[FILESYS_LABEL_SIZE], type[FILESYS_TYPE_SIZE];
+ char partition[NFSPHYS_DIR_SIZE];
+ int mid, quota;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
+
+ EXEC SQL DECLARE po_curses CURSOR FOR
+ SELECT m.name, m.mach_id from machine m, serverhosts s
+ WHERE s.service='POSTOFFICE' AND s.mach_id=m.mach_id
+ ORDER by m.name;
+ EXEC SQL OPEN po_curses;
+
+ while (1)
+ {
+ EXEC SQL FETCH po_curses INTO :machine, :mid;
+ if (sqlca.sqlcode)
+ break;
+ if (!*strtrim(machine))
+ continue;
+
+ sprintf(mdir, "%s/%s", path, machine);
+ if (stat(mdir, &sb) < 0)
+ {
+ if (errno == ENOENT)
+ {
+ if (mkdir(mdir, 0700) < 0)
+ {
+ fprintf(stderr, "%s: unable to make directory %s (%s)\n",
+ whoami, mdir, strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "%s: cannot stat %s (%s)\n", whoami, mdir,
+ strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ }
+ sprintf(mout, "%s/mailboxes", mdir);
+ sprintf(qout, "%s/quota", mdir);
+ if (!(moutp = fopen(mout, "w")))
+ {
+ fprintf(stderr, "%s: cannot open %s for writing (%s)\n", whoami,
+ mout, strerror(errno));
+ exit(MR_OCONFIG);
+ }
+
+ if (!(qoutp = fopen(qout, "w")))
+ {
+ fprintf(stderr, "%s: cannot open %s for writing (%s)\n", whoami,
+ qout, strerror(errno));
+ exit(MR_OCONFIG);
+ }
+
+ EXEC SQL DECLARE filsys_cursor CURSOR FOR
+ SELECT f.label, f.lockertype, p.dir, q.quota
+ FROM filesys f, nfsphys p, quota q
+ WHERE f.mach_id=:mid AND f.type='IMAP' AND f.createflg!=0
+ AND f.filsys_id=q.filsys_id
+ AND f.mach_id=p.mach_id AND f.phys_id=p.nfsphys_id
+ ORDER BY f.label, p.dir, q.quota;
+ EXEC SQL OPEN filsys_cursor;
+
+ while (1)
+ {
+ EXEC SQL FETCH filsys_cursor INTO :label, :type, :partition, :quota;
+ if (sqlca.sqlcode)
+ break;
+ if (!*strtrim(label))
+ continue;
+ if (!*strtrim(type))
+ continue;
+ if (!*strtrim(partition))
+ continue;
+
+ if (!strncmp(&label[strlen(label)-3], ".po", 3))
+ label[strlen(label)-3] = '\0';
+ lowercase(label);
+ lowercase(type);
+ lowercase(partition);
+
+ fprintf(moutp, "%s.%s\t%s\t%s\t%s\n", type, label, partition,
+ label, "lrswipcda");
+ fprintf(qoutp, "%s.%s\t%d\n", type, label, quota);
+ }
+
+ EXEC SQL CLOSE filsys_cursor;
+ EXEC SQL COMMIT;
+
+ if (fclose(moutp))
+ {
+ fprintf(stderr, "%s: unable to close file %s (%s)\n", whoami,
+ mout, strerror(errno));
+ exit(MR_CCONFIG);
+ }
+
+ if (fclose(qoutp))
+ {
+ fprintf(stderr, "%s: unable to close file %s (%s)\n", whoami,
+ qout, strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ }
+
+ EXEC SQL CLOSE po_curses;
+ EXEC SQL COMMIT;
+ return;
+
+sqlerr:
+ db_error(sqlca.sqlcode);
+ exit(MR_DBMS_ERR);
+}
--- /dev/null
+#!/bin/sh
+# This script performs postoffice updates.
+#
+# $Header$
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/etc:/usr/etc:/usr/athena/bin:/usr/local/bin
+export PATH
+
+# The following exit codes are defined and MUST BE CONSISTENT with the
+# error codes the library uses:
+MR_NOCRED=47836470
+MR_MISSINGFILE=47836473
+MR_MKCRED=47836474
+MR_TARERR=47836476
+
+umask 22
+
+TARFILE=/var/tmp/po.out
+SRC_DIR=/var/tmp/po.dir
+IMAP_ROOT=/usr/local/cyrus
+IMAP_CONFIG=${IMAP_ROOT}/config
+IMAP_CHECK=${IMAP_CONFIG}/ignore_update_checks
+IMAP_MBOXES=${IMAP_CONFIG}/mailboxes.input;
+IMAP_QUOTA=${IMAP_CONFIG}/quota
+IMAP_QINPUT=${IMAP_QUOTA}/input
+IMAP_BIN=${IMAP_ROOT}/bin
+
+
+#
+# handle tar file
+#
+
+if [ ! -r ${TARFILE} ]; then
+ exit ${MR_TARERR}
+fi
+
+rm -rf ${SRC_DIR}
+mkdir ${SRC_DIR}
+chmod 700 ${SRC_DIR}
+
+uchost=`hostname | tr '[a-z]' '[A-Z]'`
+echo $uchost | egrep -e "." > /dev/null
+if [ $? != 0 ]; then
+ domain=`grep domain /etc/resolv.conf | awk '{print $2}' |tr '[a-z]' '[A-Z]'`
+
+ uchost=$uchost.$domain
+fi
+
+cd ${SRC_DIR}
+tar xvf ${TARFILE}
+if [ $? != 0 ]; then
+ exit ${MR_TARERR}
+fi
+
+if [ ! -d $uchost ]; then
+ echo "no directory for "$uchost
+ exit ${MR_MISSINGFILE}
+fi
+
+cd $uchost
+
+
+#
+# handle mboxes file
+#
+
+cp mailboxes ${IMAP_MBOXES}
+if [ $? != 0 ]; then
+ echo "failed to copy mailboxes"
+ exit ${MR_NOCRED}
+fi
+
+if [ -r {$IMAP_MBOXES} ]; then
+ egrep "\..*\." ${IMAP_CONFIG}/mailboxes >> ${IMAP_MBOXES}
+fi
+
+sort -o ${IMAP_MBOXES} ${IMAP_MBOXES}
+
+
+#
+# handle quotas
+#
+
+rm -f ${IMAP_QINPUT}
+cp quota ${IMAP_QINPUT}
+if [ $? != 0 ]; then
+ echo "failed to copy quota"
+ exit ${MR_NOCRED}
+fi
+
+
+#
+# save
+#
+cp ${IMAP_CONFIG}/mailboxes ${IMAP_CONFIG}/mailboxes.save
+
+#
+# synchronize
+#
+LD_LIBRARY_PATH=/usr/local/tcl/lib
+export LD_LIBRARY_PATH
+${IMAP_BIN}/cyradm -file /usr/local/bin/sync.cyradm sync -d
+if [ $? != 0 ]; then
+ exit ${MR_MKCRED}
+fi
+
+#
+# backup
+#
+cp ${IMAP_CONFIG}/mailboxes ${IMAP_CONFIG}/mailboxes.backup
+
+#
+# cleanup
+#
+
+if [ -f ${TARFILE} ]; then
+ rm -f ${TARFILE}
+fi
+
+if [ -d ${SRC_DIR} ]; then
+ cd ${SRC_DIR}/..
+ rm -rf ${SRC_DIR}
+fi
+
+if [ -f $0 ]; then
+ rm -f $0
+fi
+
+exit 0
--- /dev/null
+/* $Id$
+ *
+ * This generates the web server user & group data.
+ *
+ * tom@mit.edu
+ *
+ * Copyright 1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#include <mit-copyright.h>
+#include <moira.h>
+#include <moira_site.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include "util.h"
+
+EXEC SQL INCLUDE sqlca;
+
+RCSID("$Header$");
+
+
+#ifndef WWW_SUBDIR
+#define WWW_SUBDIR "www"
+#endif
+
+#define MAX_RECSIZE 10240
+
+char *whoami = "www.gen";
+char *db = "moira/moira";
+
+void filsys(FILE *out);
+void group(FILE *out);
+
+char www_dir[MAXPATHLEN];
+
+char *colors[] = {"red", "green", "blue", "yellow", "mauve", "spooge",
+ "rose", "ivory", "mitbeige", "twinkie", "midnightblue",
+ "grey", "lilac", "orange", "purple", "ronhoffmanngreen"};
+int ncolors = 16;
+
+
+int main(int argc, char **argv)
+{
+ char outgrp[MAXPATHLEN];
+ char outfs[MAXPATHLEN];
+ char wkgrp[MAXPATHLEN];
+ char wkfs[MAXPATHLEN];
+ char cmd[BUFSIZ];
+ FILE *outgrpf;
+ FILE *outfsf;
+ struct stat sb;
+ char *c;
+ int flag;
+
+ initialize_sms_error_table();
+
+ if (argc == 1)
+ sprintf(www_dir, "%s/%s", DCM_DIR, WWW_SUBDIR);
+ else
+ {
+ sprintf(www_dir, "%s", argv[1]);
+ /* fake out dcm - we'll append .out later */
+ if (c = strrchr(www_dir, '.'))
+ *c = '\0';
+ }
+
+ if (argc > 2)
+ {
+ fprintf(stderr, "usage: %s [outdir]\n", argv[0]);
+ exit(MR_ARGS);
+ }
+
+ if (stat(www_dir, &sb) < 0)
+ {
+ if (errno == ENOENT)
+ {
+ if (mkdir(www_dir, 0700) < 0)
+ {
+ fprintf(stderr, "%s: unable to make directory %s (%s))\n",
+ whoami, www_dir, strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "%s: cannot stat %s (%s)\n", whoami, www_dir,
+ strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ }
+ else if(!S_ISDIR(sb.st_mode))
+ {
+ fprintf(stderr, "%s: %s not a directory\n" , whoami, www_dir);
+ exit(MR_CCONFIG);
+ }
+
+ EXEC SQL CONNECT :db;
+
+ sprintf(outgrp, "%s/group", www_dir);
+ sprintf(outfs, "%s/filsys", www_dir);
+ sprintf(wkgrp, "%s/group~", www_dir);
+ sprintf(wkfs, "%s/filsys~", www_dir);
+
+ flag = 0;
+ if (stat(outfs, &sb) == 0)
+ {
+ if (ModDiff (&flag, "filesys", sb.st_mtime))
+ exit(MR_DATE);
+ }
+ if (flag < 0)
+ fprintf(stderr, "%s: %s does not need to be rebuilt.\n", whoami, outfs);
+ else
+ {
+ fprintf(stderr, "%s: building fs database...\n", whoami);
+ if (!(outfsf = fopen(wkfs, "w")))
+ {
+ fprintf(stderr, "%s: cannot open %s for writing (%s)\n", whoami,
+ wkfs, strerror(errno));
+ exit(MR_OCONFIG);
+ }
+ filsys(outfsf);
+ if (fclose(outfsf))
+ {
+ fprintf(stderr, "%s: close of %s failed (%s)", whoami,
+ wkfs, strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ fix_file(outfs);
+ }
+
+ flag = 0;
+ if (stat(outgrp, &sb) == 0)
+ {
+ if (ModDiff (&flag, "list", sb.st_mtime) ||
+ ModDiff (&flag, "users", sb.st_mtime))
+ exit(MR_DATE);
+ }
+ if (flag < 0)
+ fprintf(stderr, "%s: %s does not need to be rebuilt.\n", whoami, outgrp);
+ else
+ {
+ fprintf(stderr, "%s: building group database...\n", whoami);
+ if (!(outgrpf = fopen(wkgrp, "w")))
+ {
+ fprintf(stderr, "%s: cannot open %s for writing (%s)\n", whoami,
+ wkgrp, strerror(errno));
+ exit(MR_OCONFIG);
+ }
+ group(outgrpf);
+ if (fclose(outgrpf))
+ {
+ fprintf(stderr, "%s: close of %s failed (%s)", whoami, wkgrp,
+ strerror(errno));
+ exit(MR_CCONFIG);
+ }
+ fix_file(outgrp);
+ }
+
+ fprintf(stderr, "%s: building tar file...\n", whoami);
+ sprintf(cmd, "(cd %s; tar cf - . ) > %s.out", www_dir, www_dir);
+ if (system(cmd))
+ exit(MR_TAR_FAIL);
+
+ exit(MR_SUCCESS);
+}
+
+void filsys(FILE *out)
+{
+ char *c;
+ EXEC SQL BEGIN DECLARE SECTION;
+ char label[FILESYS_LABEL_SIZE], path[FILESYS_NAME_SIZE];
+ int status;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
+
+ EXEC SQL DECLARE filsys_cursor CURSOR FOR
+ SELECT label, name FROM filesys WHERE type='AFS' ORDER by label;
+ EXEC SQL OPEN filsys_cursor;
+
+ while (1)
+ {
+ EXEC SQL FETCH filsys_cursor INTO :label, :path;
+ if (sqlca.sqlcode)
+ break;
+ if (!*strtrim(label))
+ continue;
+ if (!*strtrim(path))
+ continue;
+ fprintf(out, "%s:%s\n", label, path);
+ }
+
+ EXEC SQL CLOSE filsys_cursor;
+ EXEC SQL COMMIT;
+
+ return;
+
+sqlerr:
+ db_error(sqlca.sqlcode);
+ exit(MR_DBMS_ERR);
+}
+
+void group(FILE *out)
+{
+ int first;
+ int recsize;
+
+ EXEC SQL BEGIN DECLARE SECTION;
+ char user[USERS_LOGIN_SIZE];
+ char list[LIST_NAME_SIZE];
+ char parent[LIST_NAME_SIZE];
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL WHENEVER SQLERROR GOTO sqlerr;
+
+ EXEC SQL DECLARE user_cursor CURSOR FOR
+ SELECT login FROM users WHERE status=1 ORDER by login;
+ EXEC SQL OPEN user_cursor;
+
+ while (1)
+ {
+ EXEC SQL FETCH user_cursor INTO :user;
+ if (sqlca.sqlcode)
+ break;
+ strtrim(user);
+ recsize = strlen(user) + 3;
+ first = 1;
+
+ EXEC SQL DECLARE member_cursor CURSOR FOR
+ SELECT DISTINCT l.name from list l, imembers i, users u
+ WHERE u.login=:user AND u.users_id=i.member_id AND
+ i.member_type='USER' AND i.list_id=l.list_id AND
+ l.grouplist != 0 and l.active != 0
+ ORDER by l.name;
+ EXEC SQL OPEN member_cursor;
+
+ while (1)
+ {
+ EXEC SQL FETCH member_cursor INTO :list;
+ if (sqlca.sqlcode)
+ break;
+ strtrim(list);
+ if (first)
+ fprintf(out, "%s:xjOhFdLKGK84w:", user);
+ fprintf(out, "%s%s", first ? "" : ",", list);
+ recsize += strlen(list) + 1;
+ first = 0;
+ if (recsize > MAX_RECSIZE)
+ {
+ fprintf(stderr, "truncated group list for %s\n", user);
+ break;
+ }
+ }
+
+ EXEC SQL CLOSE member_cursor;
+ EXEC SQL COMMIT;
+
+ if (!first)
+ fprintf(out, "\n");
+ }
+
+ EXEC SQL CLOSE user_cursor;
+ EXEC SQL COMMIT;
+
+ return;
+
+sqlerr:
+ db_error(sqlca.sqlcode);
+ exit(MR_DBMS_ERR);
+}
--- /dev/null
+#!/bin/sh
+# This script performs updates of the web server.
+# $Header$
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/etc:/usr/etc:/usr/athena/bin:/usr/local/bin
+export PATH
+
+# The following exit codes are defined and MUST BE CONSISTENT with the
+# error codes the library uses:
+MR_HESFILE=47836472
+MR_MISSINGFILE=47836473
+MR_NAMED=47836475
+MR_TARERR=47836476
+
+umask 22
+
+TARFILE=/usr/tmp/www.out
+SRC_DIR=/usr/local/apache/etc
+BIN_DIR=/usr/local/apache/bin
+DEST_DIR=/usr/local/apache/etc
+
+if [ ! -r $TARFILE ]; then
+ exit $MR_MISSINGFILE
+fi
+
+cd $SRC_DIR
+rm -rf build
+mkdir build
+if [ $? != 0 ]; then
+ exit $MR_TARERR
+fi
+
+rm -rf save2
+if [ -d save ]; then
+ mv -f save save2
+fi
+mkdir save
+if [ $? != 0 ]; then
+ exit $MR_TARERR
+fi
+
+cd build
+
+for file in `tar tf $TARFILE | awk '{print $1}' | sed 's;/$;;'` ; do
+ if [ $file != . ]; then
+ rm -rf $file
+ echo extracting $file
+ tar xf $TARFILE $file
+ if [ $? != 0 ]; then
+ exit $MR_TARERR
+ fi
+ $BIN_DIR/dbmanage $file import $file.db
+ if [ $? != 0 ]; then
+ exit $MR_TARERR
+ fi
+ mv $DEST_DIR/$file $SRC_DIR/save/$file
+ mv $DEST_DIR/$file.db $SRC_DIR/save/$file.db
+ mv $SRC_DIR/build/$file $DEST_DIR/$file
+ mv $SRC_DIR/build/$file.db $DEST_DIR/$file.db
+ fi
+done
+
+cd ..
+
+rm -f $TARFILE
+echo removed tarfile
+rm -f $0
+echo removed self
+
+exit 0