From de56407f0fd27d5366a936b872972630f1683f0f Mon Sep 17 00:00:00 2001 From: wesommer Date: Sat, 22 Aug 1987 16:34:57 +0000 Subject: [PATCH] Initial revision --- backup/copy_backups.c | 108 ++++++ clients/Makefile | 23 ++ gen/hesiod.sh | 33 ++ gen/nfs.sh | 9 + lib/Makefile | 163 +++++++++ lib/fixname.c | 174 +++++++++ lib/mr_ops.c | 49 +++ server/meinitlst.c | 170 +++++++++ server/mr_smalloc.c | 784 +++++++++++++++++++++++++++++++++++++++++ update/Makefile | 170 +++++++++ update/auth_001.c | 93 +++++ update/checksum.c | 36 ++ update/client.c | 421 ++++++++++++++++++++++ update/exec_002.c | 65 ++++ update/get_file.c | 190 ++++++++++ update/hostname.c | 34 ++ update/inst_001.c | 43 +++ update/log.c | 92 +++++ update/send_file.c | 113 ++++++ update/ticket.c | 69 ++++ update/update_server.c | 145 ++++++++ update/xfer_002.c | 94 +++++ 22 files changed, 3078 insertions(+) create mode 100644 backup/copy_backups.c create mode 100644 clients/Makefile create mode 100644 gen/hesiod.sh create mode 100644 gen/nfs.sh create mode 100644 lib/Makefile create mode 100644 lib/fixname.c create mode 100644 lib/mr_ops.c create mode 100644 server/meinitlst.c create mode 100644 server/mr_smalloc.c create mode 100644 update/Makefile create mode 100644 update/auth_001.c create mode 100644 update/checksum.c create mode 100644 update/client.c create mode 100644 update/exec_002.c create mode 100644 update/get_file.c create mode 100644 update/hostname.c create mode 100644 update/inst_001.c create mode 100644 update/log.c create mode 100644 update/send_file.c create mode 100644 update/ticket.c create mode 100644 update/update_server.c create mode 100644 update/xfer_002.c diff --git a/backup/copy_backups.c b/backup/copy_backups.c new file mode 100644 index 00000000..a92eb7e0 --- /dev/null +++ b/backup/copy_backups.c @@ -0,0 +1,108 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright (C) 1987 by the Massachusetts Institute of Technology + * + * $Log$ + * Revision 1.1 1987-08-22 17:03:18 wesommer + * Initial revision + * + */ + +#ifndef lint +static char *rcsid_copy_backups_c = "$Header$"; +#endif lint +#include +#include +#include +#include "update.h" + +char *whoami; +char host[BUFSIZ]; +char buf[BUFSIZ]; + +static struct update_desc info = { + 42, /* last_time_tried */ + 1, /* success */ + 12, /* interval */ + "backup", /* service_name */ + "ZEUS.MIT.EDU", /* host_name */ + "/tmp/frobnicate", /* target_path */ + 2, /* override */ + 1, /* enable */ + "/dev/null" + /* instructions */ +}; + +extern char *error_message(); +#include + +main(argc,argv) + int argc; + char **argv; +{ + int rc; + DIR *pd, *sd; + struct direct *pde, *sde; + + whoami = rindex(argv[0], '/'); + if (whoami) + whoami++; + else + whoami = argv[0]; + whoami = argv[0]; + if (chdir ("/u3/sms_backup") < 0) { + perror("can't change to /u3/sms_backup"); + exit(1); + } + + pd = opendir("."); + if (pd == NULL) { + perror("can't open sms_backup directory"); + exit(1); + } + + while ( (pde = readdir(pd)) != NULL ) { + char *dir_name = pde->d_name; + printf("Directory: %s\n", dir_name); + + if (dir_name[0] == '.') continue; /* ignore hidden files */ + + if (chdir(dir_name) < 0) { + perror(dir_name); + continue; + } + sd = opendir ("."); + if (sd == NULL) { + perror("Can't open ."); + goto dotdot; + } + while ( (sde = readdir(sd)) != NULL ) { + if (sde->d_name[0] == '.') continue; + + sprintf(buf, "/site/sms/sms_backup/%s/%s", dir_name, sde->d_name); + printf("Updating: %s\n", buf); + info.target_path = buf; + rc = sms_update_server(&info, sde->d_name); + if (rc) printf("return code: %s\n", error_message(rc)); + } + closedir(sd); + + dotdot: + chdir(".."); + } + closedir(pd); +} + +/* + * Local Variables: + * mode: c + * c-indent-level: 4 + * c-continued-statement-offset: 4 + * c-brace-offset: -4 + * c-argdecl-indent: 4 + * c-label-offset: -4 + * End: + */ diff --git a/clients/Makefile b/clients/Makefile new file mode 100644 index 00000000..9195bb34 --- /dev/null +++ b/clients/Makefile @@ -0,0 +1,23 @@ +# Makefile for first release of SMS. +# +# $Source$ +# $Header$ +# $Author$ +# + +DESTDIR= + +SUBDIRS= aliasbld finger listmaint madm rvdmaint servermaint usermaint userreg + +all: + for i in ${SUBDIRS}; do \ + (cd $$i; make ${MFLAGS} all); done + +install: + for i in ${SUBDIRS}; do \ + (cd $$; make ${MFLAGS} install); done + +clean: + for i in ${SUBDIRS}; do \ + (cd $$i; make ${MFLAGS} clean); done + diff --git a/gen/hesiod.sh b/gen/hesiod.sh new file mode 100644 index 00000000..4d8a6bc9 --- /dev/null +++ b/gen/hesiod.sh @@ -0,0 +1,33 @@ +#! /bin/sh +TARFILE=/tmp/hesiod +SRC_DIR=/etc/athena/_nameserver +DEST_DIR=/etc/athena/nameserver +if [ ! -d $SRC_DIR ]; then + /bin/rm -f $SRC_DIR + /bin/mkdir $SRC_DIR + /bin/chmod 755 $SRC_DIR +fi +#if [ ! -d $DEST_DIR ]; then +# /bin/rm -f $DEST_DIR +# /bin/mkdir $DEST_DIR +# /bin/chmod 755 $DEST_DIR +#fi +cd $SRC_DIR +for file in `/bin/tar tf $TARFILE`; do + if [ ./ = $file ]; then continue; fi + /bin/tar xf $TARFILE $file + if [ -s $file ]; then + /bin/mv -f $file $DEST_DIR + else + /bin/rm -f $file + fi +done +#/bin/rm -f $TARFILE +#kill -HUP `/bin/cat /etc/named.pid` + + +exit +# +# $Source$ +# $Header$ +# diff --git a/gen/nfs.sh b/gen/nfs.sh new file mode 100644 index 00000000..99ec36e3 --- /dev/null +++ b/gen/nfs.sh @@ -0,0 +1,9 @@ +mkdir /tmp/nfs.dir +cd /tmp/nfs.dir +tar xf /tmp/nfs +chmod 775 /tmp/nfs.dir +exit +# +# $Source$ +# $Header$ +# diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 00000000..14c96b6d --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,163 @@ +# $Source$ +# $Author$ +# $Header$ +# +# Makefile for SMS library. +# +LIBSRC=sms_auth.c sms_call.c sms_connect.c sms_data.c sms_init.c \ + sms_shutdown.c sms_query.c sms_param.c sms_access.c sms_misc.c \ + sms_al_filsys.c sms_al_pobox.c menu.c admin_call.c admin_util_new.c \ + sms_do_update.c fixname.c + +CFILES=${LIBSRC} + +LIBOBJ=sms_auth.o sms_call.o sms_connect.o sms_data.o sms_et.o \ + sms_init.o sms_shutdown.o sms_query.o sms_param.o sms_access.o \ + sms_misc.o sms_al_filsys.o sms_al_pobox.o krb_et.o menu.o \ + admin_call.o admin_util_new.o admin_err.o sms_do_update.o \ + fixname.o + +COPTS= -O + +INCDIRS=-I../include + +CFLAGS= ${INCDIRS} ${COPTS} +LINTFLAGS= -uhv + +ALL=libsms.a llib-lsms.ln libsms_p.a + +.c.o: + ${CC} -c -pg ${CFLAGS} $*.c + ld -x -r $*.o + mv a.out profiled/$*.o + ${CC} -c ${CFLAGS} $*.c + ld -x -r $*.o + mv a.out $*.o + +all: ${ALL} + +libsms.a: ${LIBOBJ} + ar cruv $@ ${LIBOBJ} + ranlib $@ + (cd profiled; ar cruv ../libsms_p.a ${LIBOBJ}; ranlib ../libsms_p.a) + +smslib.dvi: smslib.tex + latex smslib.tex + +krb_et.o: krb_et.et + compile_et krb_et.et + cp krb_et.o profiled/krb_et.o + +sms_et.o: sms_et.et + compile_et sms_et.et + cp sms_et.o profiled/sms_et.o + +sms_et.h: sms_et.o + +admin_err.o: admin_err.et + compile_et admin_err.et + cp admin_err.o profiled/admin_err.o + +admin_err.h: admin_err.o + +../include/sms_et.h: sms_et.h + +clean: + rm -f ${ALL} + rm -f *.o *~ admin_err.h sms_et.h krb_et.h profiled/*.o \#* + rm -f *.PS *.aux *.dvi *.log + rm -f *.bak + + +install: + install -m 644 libsms.a ${DESTDIR}/usr/athena/lib/libsms.a + ranlib ${DESTDIR}/usr/athena/lib/libsms.a + install -m 644 libsms_p.a ${DESTDIR}/usr/athena/lib/libsms_p.a + ranlib ${DESTDIR}/usr/athena/lib/libsms_p.a + -mkdir ${DESTDIR}/usr/athena/lib/lint + install -m 644 llib-lsms.ln ${DESTDIR}/usr/athena/lib/lint/llib-lsms.ln + +TAGS: $(CFILES) + -etags $(CFILES) + +lint: ${CFILES} llib-lsms.ln + lint ${LINTFLAGS} ${INCDIRS} sms_main.c llib-lsms.ln + +llib-lsms.ln: ${LIBSRC} + lint -Csms $(LINTFLAGS) $(INCDIRS) ${LIBSRC} + +depend: $(CFILES) sms_et.h admin_err.h + $(CC) -M $(CFLAGS) $(CFILES) | \ + sed -e 's; ./; ;' \ + -e ':loop' \ + -e 's/\.\.\/[^ /]*\/\.\./../' \ + -e 't loop' | \ + awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \ + else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ + else rec = rec " " $$2 } } \ + END { print rec } ' > makedep + echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep + echo '$$r makedep' >>eddep + echo 'w' >>eddep + cp Makefile Makefile.bak + ed - Makefile < eddep + rm eddep makedep +# +# the last constant line in the makefile should be... +# DO NOT DELETE THIS LINE + +sms_auth.o: sms_auth.c sms_private.h sms_proto.h /usr/include/stdio.h +sms_auth.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +sms_auth.o: /usr/include/time.h ../include/sms.h ../include/sms_et.h +sms_auth.o: /usr/include/krb.h /usr/include/des.h +sms_call.o: sms_call.c sms_private.h sms_proto.h /usr/include/stdio.h +sms_call.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +sms_call.o: /usr/include/time.h ../include/sms.h ../include/sms_et.h +sms_connect.o: sms_connect.c sms_private.h sms_proto.h /usr/include/stdio.h +sms_connect.o: ../include/gdb.h /usr/include/sys/types.h +sms_connect.o: /usr/include/sys/time.h /usr/include/time.h ../include/sms.h +sms_connect.o: ../include/sms_et.h +sms_data.o: sms_data.c sms_private.h sms_proto.h /usr/include/stdio.h +sms_data.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +sms_data.o: /usr/include/time.h ../include/sms.h ../include/sms_et.h +sms_init.o: sms_init.c sms_private.h sms_proto.h /usr/include/stdio.h +sms_init.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +sms_init.o: /usr/include/time.h ../include/sms.h ../include/sms_et.h +sms_shutdown.o: sms_shutdown.c sms_private.h sms_proto.h /usr/include/stdio.h +sms_shutdown.o: ../include/gdb.h /usr/include/sys/types.h +sms_shutdown.o: /usr/include/sys/time.h /usr/include/time.h ../include/sms.h +sms_shutdown.o: ../include/sms_et.h +sms_query.o: sms_query.c sms_private.h sms_proto.h /usr/include/stdio.h +sms_query.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +sms_query.o: /usr/include/time.h ../include/sms.h ../include/sms_et.h +sms_param.o: sms_param.c /usr/include/sys/types.h /usr/include/netinet/in.h +sms_param.o: sms_private.h sms_proto.h /usr/include/stdio.h ../include/gdb.h +sms_param.o: /usr/include/sys/types.h /usr/include/sys/time.h +sms_param.o: /usr/include/time.h ../include/sms.h ../include/sms_et.h +sms_access.o: sms_access.c sms_private.h sms_proto.h /usr/include/stdio.h +sms_access.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +sms_access.o: /usr/include/time.h ../include/sms.h ../include/sms_et.h +sms_misc.o: sms_misc.c /usr/include/strings.h +sms_al_filsys.o: sms_al_filsys.c ../include/sms_et.h /usr/include/stdio.h +sms_al_pobox.o: sms_al_pobox.c ../include/sms_et.h /usr/include/stdio.h +sms_al_pobox.o: /usr/include/ctype.h +menu.o: menu.c /usr/include/stdio.h /usr/include/curses.h /usr/include/stdio.h +menu.o: /usr/include/sgtty.h /usr/include/sys/ioctl.h +menu.o: /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h +menu.o: /usr/include/ctype.h ../include/menu.h +admin_call.o: admin_call.c /usr/include/sys/errno.h /usr/include/sys/types.h +admin_call.o: /usr/include/sys/time.h /usr/include/time.h +admin_call.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h +admin_call.o: /usr/include/sys/ttydev.h /usr/include/sys/socket.h +admin_call.o: /usr/include/netinet/in.h /usr/include/netdb.h +admin_call.o: /usr/include/strings.h /usr/include/stdio.h admin_err.h +admin_call.o: admin_server.h prot.h /usr/include/krb.h /usr/include/des.h +admin_util_new.o: admin_util_new.c /usr/include/sys/types.h +admin_util_new.o: /usr/include/sys/errno.h /usr/include/sys/ioctl.h +admin_util_new.o: /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h +admin_util_new.o: /usr/include/sys/signal.h /usr/include/sys/file.h +admin_util_new.o: /usr/include/sys/param.h /usr/include/machine/machparam.h +admin_util_new.o: /usr/include/signal.h /usr/include/sys/types.h +admin_util_new.o: /usr/include/stdio.h /usr/include/strings.h +admin_util_new.o: /usr/include/krb.h /usr/include/des.h /usr/include/setjmp.h +admin_util_new.o: /usr/include/pwd.h admin_server.h prot.h admin_err.h diff --git a/lib/fixname.c b/lib/fixname.c new file mode 100644 index 00000000..91d53d07 --- /dev/null +++ b/lib/fixname.c @@ -0,0 +1,174 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright (C) 1987 by the Massachusetts Institute of Technology + * + * $Log$ + * Revision 1.1 1987-08-22 17:14:30 wesommer + * Initial revision + * + */ + +#ifndef lint +static char *rcsid_fixname_c = "$Header$"; +#endif lint + +#include +#include + +#define LAST_LEN 15 +#define FIRST_LEN 15 + +void FixName(ilnm, ifnm, last, first, middle) + char *ilnm, *ifnm; + char *first, *last, *middle; +{ + int ends_jr=0, ends_iii=0, ends_iv=0; + + Upcase(ilnm); + Upcase(ifnm); + + /* Last name ... */ + + TrimTrailingSpace(ilnm); + LookForJrAndIII(ilnm, &ends_jr, &ends_iii, &ends_iv); + LookForSt(ilnm); + LookForO(ilnm); + FixCase(ilnm); + strncpy(last, ilnm, LAST_LEN); + + /* First name & middle initial ... */ + + TrimTrailingSpace(ifnm); + LookForJrAndIII(ifnm, &ends_jr, &ends_iii, &ends_iv); + + GetMidInit(ifnm, middle); + + FixCase(ifnm); +#ifdef notdef + /* okay, finish up first name */ + AppendJrOrIII(ifnm, &ends_jr, &ends_iii, &ends_iv); +#endif notdef + strncpy(first, ifnm, FIRST_LEN); +} +#ifdef notdef +AppendJrOrIII(nm, phas_jr, phas_iii, phas_iv) +register char *nm; +register int *phas_jr; +register int *phas_iii; +register int *phas_iv; +{ + if (*phas_jr) { + strcat(nm, ", Jr."); + } + else if (*phas_iii) { + strcat(nm, " III"); + } + else if (*phas_iv) { + strcat(nm, " IV"); + } +} +#endif notdef +FixCase(p) +register char *p; +{ + register int cflag; /* convert to lcase, unless at start or following */ + /* a space or punctuation mark (e.g., '-') */ + + for (cflag = 0; *p; p++) { + if (cflag && isupper(*p)) { + *p = tolower(*p); + } + else if (isspace(*p) || ispunct(*p)) { + cflag = 0; + } + else { + cflag = 1; + } + } +} + +LookForJrAndIII(nm, pends_jr, pends_iii, pends_iv) +register char *nm; +register int *pends_jr; +register int *pends_iii; +register int *pends_iv; +{ + register int len = strlen(nm); + + if (len >= 4 && !strcmp(nm + len - 3, " JR")) { + *pends_jr = 1; + nm[len - 3] = '\0'; + } + else if (len >= 4 && !strcmp(nm + len - 3, " IV")) { + *pends_iv = 1; + nm[len - 3] = '\0'; + } + else if (len >= 5 && !strcmp(nm + len - 4, " JR.")) { + *pends_jr = 1; + nm[len - 4] = '\0'; + } + else if (len >= 5 && !strcmp(nm + len - 4, " III")) { + *pends_iii = 1; + nm[len - 4] = '\0'; + } +} + +LookForSt(nm) /* ST PIERRE, etc. */ +register char *nm; +{ + char temp[256]; + + if (!strcmp(nm,"ST ")) { + strcpy(temp, nm + 3); + strcpy(nm, "ST. "); + strcat(nm, temp); + } +} + +LookForO(nm) /* O BRIEN, etc. */ +register char *nm; +{ + if (!strcmp(nm, "O ") && isalpha(nm[2])) { + nm[1] = '\''; + } +} + +TrimTrailingSpace(ip) +register char *ip; +{ + register char *p; + for (p = ip + strlen(ip) - 1; p >= ip && isspace(*p); p--) { + *p = '\0'; + } +} + +Upcase(cp) + char *cp; +{ + register int c; + + for ( ; c= *cp; cp++) + if (islower(c)) *cp = toupper(c); +} + +GetMidInit(nm, mi) +register char *nm; /* truncate at first space, if any such */ +register char *mi; /* set to first char after first space, if any such */ +{ + while (*nm && !isspace(*nm)) { + nm++; + } + if (*nm) { + *nm++ = '\0'; + } + while (*nm && isspace(*nm)) { + nm++; + } + if (*nm) { + *mi++ = *nm; + } + *mi = '\0'; +} diff --git a/lib/mr_ops.c b/lib/mr_ops.c new file mode 100644 index 00000000..63d194fe --- /dev/null +++ b/lib/mr_ops.c @@ -0,0 +1,49 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright (C) 1987 by the Massachusetts Institute of Technology + * + * This routine is part of the client library. It handles + * creating a connection to the sms server. + */ + +#ifndef lint +static char *rcsid_sms_do_update_c = "$Header$"; +#endif lint + +#include "sms_private.h" + +int sms_do_update() +{ + int status; + sms_params param_st; + struct sms_params *params = NULL; + struct sms_params *reply = NULL; + + CHECK_CONNECTED; + params = ¶m_st; + params->sms_procno = SMS_DO_UPDATE; + params->sms_argc = 0; + params->sms_argl = NULL; + params->sms_argv = NULL; + + if ((status = sms_do_call(params, &reply)) == 0) + status = reply->sms_status; + + sms_destroy_reply(reply); + + return status; +} + +/* + * Local Variables: + * mode: c + * c-indent-level: 4 + * c-continued-statement-offset: 4 + * c-brace-offset: -4 + * c-argdecl-indent: 4 + * c-label-offset: -4 + * End: + */ diff --git a/server/meinitlst.c b/server/meinitlst.c new file mode 100644 index 00000000..5e93c179 --- /dev/null +++ b/server/meinitlst.c @@ -0,0 +1,170 @@ +/* + * $Source$ + * $Author$ + * $Header$ + * + * Copyright (C) 1987 by the Massachusetts Institute of Technology + * + * This code is a reverse-engineered version of + * ~rtingres/lib/compatlib(meinitlst.o) with a better malloc and + * free. + * $Log$ + * Revision 1.1 1987-08-22 17:29:33 wesommer + * Initial revision + * + */ + +#ifndef lint +static char *rcsid_meinitlst_c = "$Header$"; +#endif lint + +#include +#include + +/* + * entry points: + * MEinitLists() + * calloc() + * free() + * malloc() + * memalign() + * realloc() + * valloc() + */ + +struct cons { + char *car; + char *cdr; +}; +extern int Status; +extern char MEsetup; +extern struct cons MElist, MEfreelist; +extern short ME_pid; +extern char *MElistHead, *MEfreeHead; + +MEinitLists() +{ + Status = 0; + MEsetup = 1; + MElist.car = 0; + MElist.cdr = MElistHead; + MEfreelist.car = 0; + MEfreelist.cdr = MEfreeHead; + ME_pid = getpid() & 0x7fff; + return 0; +} +#ifdef notdef +free(addr) +{ + return MEfree(addr); +} + +caddr_t malloc(size) + u_int size; +{ + char *temp; + if(MEalloc(1, size, &temp)) return 0; + else return temp; +} + +caddr_t calloc(a1, a2) + int a1, a2; +{ + char *temp; + if (MEcalloc(a1, a2, &temp)) return 0; + else return temp; +} + +caddr_t realloc(adr, nsize) + char *adr; + u_int nsize; +{ + char *new_addr; + u_int cur_size; + if (MEsize(adr, &cur_size)) return 0; + if (cur_size >= nsize) return adr; + if ( (new_addr = malloc(nsize)) == 0) return 0; + (void) MEcopy(adr, cur_size, new_addr); + (void) free(adr); + return new_addr; +} +#endif notdef +#ifdef notdef +valloc(size) + int size; +{ + static int pagesize; + if (pagesize == 0) pagesize = getpagesize(); + return memalign(pagesize, size); +} + +memalign(alignment, size) +{ + int temp1; + int temp2; + int temp3; + int temp4; + if (!size || alignment & 1) { + errno = EINVAL; + return 0; + } + if (alignment < 4) alignment = 4; + +/* +_memalign: fc0 +_memalign+2: subl2 $10,sp +_memalign+5: tstl 8(ap) +_memalign+8: beql _memalign+e +_memalign+a: blbc 4(ap),_memalign+18 +>_memalign+e: movl $16,_errno +>_memalign+15: clrf r0 +_memalign+17: ret +>_memalign+18: cmpl 4(ap),$4 +_memalign+1c: bgequ _memalign+22 +_memalign+1e: movl $4,4(ap) +>_memalign+22: pushl $4 +_memalign+24: addl3 $3,8(ap),-(sp) +_memalign+29: calls $2,udiv +_memalign+30: ashl $2,r0,8(ap) +_memalign+35: addl3 4(ap),8(ap),r0 +_memalign+3b: addl3 $20,r0,-4(fp) +_memalign+40: pushl -4(fp) +_memalign+43: calls $1,_malloc +_memalign+4a: movl r0,r11 +_memalign+4d: beql _memalign+15 +_memalign+4f: subl3 $10,r11,r10 +_memalign+53: ashl $0,4(r10),r8 +_memalign+58: pushl 4(ap) +_memalign+5b: subl3 $1,4(ap),r0 +_memalign+60: addl3 r11,r0,-(sp) +_memalign+64: calls $2,udiv +_memalign+6b: mull3 4(ap),r0,-c(fp) +_memalign+71: movl -c(fp),r7 +_memalign+75: subl3 $10,r7,r6 +_memalign+79: subl3 r10,r6,-8(fp) +_memalign+7e: subl2 -8(fp),r8 +_memalign+82: cmpl -8(fp),$10 +_memalign+86: bgequ _memalign+a7 +_memalign+88: pushl 8(ap) +_memalign+8b: pushl 4(ap) +_memalign+8e: calls $2,_memalign +_memalign+95: movl r0,-10(fp) +_memalign+99: pushl r11 +_memalign+9b: calls $1,_free +_memalign+a2: movl -10(fp),r0 +_memalign+a6: ret +>_memalign+a7: movl -8(fp),r0 +_memalign+ab: extzv $0,$20,r0,4(r10) +_memalign+b1: extzv $0,$20,r8,4(r6) +_memalign+b7: movl (r10),(r6) +_memalign+ba: movw 8(r10),8(r6) +_memalign+bf: movl r6,_MElist +_memalign+c6: cmpl _MElist+4,r10 +_memalign+cd: bneq _memalign+d6 +_memalign+cf: movl r6,_MElist+4 +>_memalign+d6: pushl r10 +_memalign+d8: calls $1,_MEf_add +_memalign+df: addl3 $10,r6,r0 +_memalign+e3: ret +*/ +#endif notdef diff --git a/server/mr_smalloc.c b/server/mr_smalloc.c new file mode 100644 index 00000000..9909f187 --- /dev/null +++ b/server/mr_smalloc.c @@ -0,0 +1,784 @@ +#include +botch(message) + char *message; +{ + fprintf(stderr, "Malloc botch: %s\n", message); + abort(); +} + +#define rcheck +/**************************************************************** + * * + * Storage Allocator for Foundation. * + * Built from gnuemacs storage allocator * + * * + ****************************************************************/ + +/* Copyright (C) 1985 Richard M. Stallman, + based mostly on the public domain work of others. + +This program is distributed in the hope that it will be useful, +but without any warranty. No author or distributor +accepts responsibility to anyone for the consequences of using it +or for whether it serves any particular purpose or works at all, +unless he says so in writing. + + Permission is granted to anyone to distribute verbatim copies + of this program's source code as received, in any medium, provided that + the copyright notice, the nonwarraty notice above + and this permission notice are preserved, + and that the distributor grants the recipient all rights + for further redistribution as permitted by this notice, + and informs him of these rights. + + Permission is granted to distribute modified versions of this + program's source code, or of portions of it, under the above + conditions, plus the conditions that all changed files carry + prominent notices stating who last changed them and that the + derived material, including anything packaged together with it and + conceptually functioning as a modification of it rather than an + application of it, is in its entirety subject to a permission + notice identical to this one. + + Permission is granted to distribute this program (verbatim or + as modified) in compiled or executable form, provided verbatim + redistribution is permitted as stated above for source code, and + A. it is accompanied by the corresponding machine-readable + source code, under the above conditions, or + B. it is accompanied by a written offer, with no time limit, + to distribute the corresponding machine-readable source code, + under the above conditions, to any one, in return for reimbursement + of the cost of distribution. Verbatim redistribution of the + written offer must be permitted. Or, + C. it is distributed by someone who received only the + compiled or executable form, and is accompanied by a copy of the + written offer of source code which he received along with it. + + Permission is granted to distribute this program (verbatim or as modified) + in executable form as part of a larger system provided that the source + code for this program, including any modifications used, + is also distributed or offered as stated in the preceding paragraph. + +In other words, you are welcome to use, share and improve this program. +You are forbidden to forbid anyone else to use, share and improve +what you give them. Help stamp out software-hoarding! */ + +/**************************************************************** + * * + * Helpful historical comments * + * * + ****************************************************************/ + +/* + * @(#)nmalloc.c 1 (Caltech) 2/21/82 + * + * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs + * + * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD. + * + * This is a very fast storage allocator. It allocates blocks of a small + * number of different sizes, and keeps free lists of each size. Blocks + * that don't exactly fit are passed up to the next larger size. In this + * implementation, the available sizes are (2^n)-4 (or -16) bytes long. + * This is designed for use in a program that uses vast quantities of + * memory, but bombs when it runs out. To make it a little better, it + * warns the user when he starts to get near the end. + * + * June 84, ACT: modified rcheck code to check the range given to malloc, + * rather than the range determined by the 2-power used. + * + * Jan 85, RMS: calls malloc_warning to issue warning on nearly full. + * No longer Emacs-specific; can serve as all-purpose malloc for GNU. + * You should call malloc_init to reinitialize after loading dumped Emacs. + * Call malloc_stats to get info on memory stats if MSTATS turned on. + * realloc knows how to return same block given, just changing its size, + * if the power of 2 is correct. + * + * Jan 86, WDC: Removed Emacs specific stuff, and neatened a few comments. + * + * March 86 WDC: Added in code by Eichin for Scribble checking of blocks + * Scribble check writes a known pattern into the free blocks, checks it + * to see if it is still undamaged before allocating it. It writes a + * different pattern into the space beyond the end of an allocated block, + * and tests it for damage when expanding the block's bounds in realloc. + * Note, this check takes *TIME* and should not be compiled in by default. + * + * Berkeley UNIX 4.3 has a storage allocator that shares a common + * ancestor with this one. It handles realloc compatibly with the + * archaic use of realloc on an already freed block to "compact" + * storage. It uses a pagesize system call rather than assuming the + * page size is 1024 bytes. Finally it guarantees that a freed block + * is not munged by the allocator itself, incase someone wants to fiddle + * with freed space after freeing it but before allocating more. + * + * This particular storage allocator would benefit from having a + * non-hardwired pagesize. But because of the scribble check it would + * not be useful to keep the free pointer in the header. SO: When you + * free something allocated with this allocator, DONT TRY TO USE IT. + * It is GUARANTEED to be damaged by the freeing process. + * + * For interfacing to systems that want to be able to ask the size of + * the allocated block, rather than remembering it, the m_blocksize + * function, rips open the block and tells you how big it is. The size + * returned is nbytes, the number of bytes asked for, NOT the actual + * amount of space in the block. + */ + +/**************************************************************** + * * + * Includes, declarations, and definitions * + * * + ****************************************************************/ + +/* Determine which kind of system this is. */ +#include +#ifndef SIGTSTP +#define USG +#else /* SIGTSTP */ +#ifdef SIGIO +#define BSD42 +#endif /* SIGIO */ +#endif /* SIGTSTP */ + +#ifndef BSD42 +#ifndef USG +#include /* warn the user when near the end */ +#endif +#else /* if BSD42 */ +#include +#include +#endif /* BSD42 */ + +#ifdef scribblecheck +#define rcheck +#endif /* we need to have range data to use block boundary checking */ + +#ifdef rcheck +/* + * To implement range checking, we write magic values in at the + * beginning and end of each allocated block, and make sure they + * are undisturbed whenever a free or a realloc occurs. + */ + +/* Written in each of the 4 bytes following the block's real space */ +#define MAGIC1 0x55 +#define MAGICFREE 0x69 /* 0110 1001 Magic value for Free blocks */ + +/* Written in the 4 bytes before the block's real space */ +#define MAGIC4 0x55555555 +#define MAGICFREE4 0x69696969 + +#define ASSERT(p) if (!(p)) botch("p"); else +#define EXTRA 4 /* 4 bytes extra for MAGIC1s */ +#else +#define ASSERT(p) +#define EXTRA 0 +#endif /* rcheck */ + +#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */ +#define ISFREE ((char) 0x54) /* magic byte that implies free block */ + /* this is for error checking only */ + +/* If range checking is not turned on, all we have is a flag + * indicating whether memory is allocated, an index in nextf[], + * and a field that tells how many bytes. + * To realloc() memory we copy nbytes. + * 16 bits of header space is unused. + */ +struct mhead { + char mh_alloc; /* ISALLOC or ISFREE */ + char mh_index; /* index in nextf[] */ + unsigned short mh_extra;/* Currently wasted 16 bits */ +/* Remainder are valid only when block is allocated */ + unsigned mh_nbytes; /* number of bytes allocated */ +#ifdef rcheck + int mh_magic4; /* should be == MAGIC4 */ +#endif /* rcheck */ +}; + +/* + * Access free-list pointer of a block. + * It is stored at block + 4. + * This is not a field in the mhead structure because we want + * sizeof (struct mhead) to describe the overhead for when the + * block is in use, and we do not want the free-list pointer + * to count in that. + */ +#define CHAIN(a) \ + (*(struct mhead **) (sizeof (char *) + (char *) (a))) + + +/**************************************************************** + * * + * Variable Creations * + * * + ****************************************************************/ + +extern char etext; +extern char *start_of_data (); /* This seems necessary for USG */ + +#ifdef notdef + +/* These two are for user programs to look at, when they are interested. */ + +int malloc_sbrk_used; /* amount of data space used now */ +int malloc_sbrk_unused; /* amount more we can have */ +#endif notdef +/* start of data space; can be changed by calling init_malloc */ +static char *data_space_start; + +#ifdef MSTATS +/* + * nmalloc[i] is the difference between the number of mallocs and frees + * for a given block size. + */ +static int nmalloc[30]; +static int nmal, nfre; +#endif /* MSTATS */ + +/* + * nextf[i] is the pointer to the next free block of size 2^(i+3). The + * smallest allocatable block is 8 bytes. The overhead information will + * go in the first int of the block, and the returned pointer will point + * to the second. + */ +static struct mhead *nextf[30]; + +/* Number of bytes of writable memory we can expect to be able to get */ +static int lim_data; +/* Level number of warnings already issued. + * 0 -- no warnings issued. + * 1 -- 75% warning already issued. + * 2 -- 85% warning already issued. + */ +static int warnlevel; + +#ifdef notdef +/* nonzero once initial bunch of free blocks made */ +static int gotpool; +#endif notdef + +/**************************************************************** + * * + * Start of procedures * + * * + * malloc_init, m_blocksize * + * * + ****************************************************************/ + +/* + * Cause reinitialization based on job parameters; + * also declare where the end of pure storage is. + */ +malloc_init (start) + char *start; +{ + data_space_start = start; + lim_data = 0; + warnlevel = 0; +} + +int m_blocksize(a_block) + char *a_block; +{ + return(((struct mhead *)a_block-1)->mh_nbytes); +} +extern int MEinitLists(); + +static int (*foo)() = MEinitLists; + + +/**************************************************************** + * * + * morecore - Ask the system for more memory * + * * + ****************************************************************/ + +static +morecore (nu) /* ask system for more memory */ + register int nu; /* size index to get more of */ +{ + char *sbrk (); + register char *cp; + register int nblks; + register int siz; + +#ifdef notdef + if (!data_space_start) + { +#if defined(USG) + data_space_start = start_of_data (); +#else /* not USG */ + data_space_start = &etext; +#endif /* not USG */ + } + + if (lim_data == 0) + get_lim_data (); + + /* On initial startup, get two blocks of each size up to 1k bytes */ + if (!gotpool) + getpool (), getpool (), gotpool = 1; + + /* Find current end of memory and issue warning if getting near max */ + + cp = sbrk (0); + siz = cp - data_space_start; + malloc_sbrk_used = siz; + malloc_sbrk_unused = lim_data - siz; + + switch (warnlevel) + { + case 0: + if (siz > (lim_data / 4) * 3) + { + warnlevel++; + malloc_warning ("Warning: past 75% of memory limit"); + } + break; + case 1: + if (siz > (lim_data / 20) * 17) + { + warnlevel++; + malloc_warning ("Warning: past 85% of memory limit"); + } + break; + case 2: + if (siz > (lim_data / 20) * 19) + { + warnlevel++; + malloc_warning ("Warning: past 95% of memory limit"); + } + break; + } + + if ((int) cp & 0x3ff) /* land on 1K boundaries */ + sbrk (1024 - ((int) cp & 0x3ff)); +#endif notdef + + /* Take at least 2k, and figure out how many blocks of the desired size + we're about to get */ + nblks = 1; + if ((siz = nu) < 8) + nblks = 1 << ((siz = 8) - nu); +#ifdef notdef + if ((cp = sbrk (1 << (siz + 3))) == (char *) -1) + return; /* no more room! */ +#endif notdef + { + char *tcp; + if (MEalloc(1, 1 << (siz+3), &tcp)) + return; /* No more room! */ + cp = tcp; + } + if ((int) cp & 7) + { /* shouldn't happen, but just in case */ + cp = (char *) (((int) cp + 8) & ~7); + nblks--; + } + + /* save new header and link the nblks blocks together */ + nextf[nu] = (struct mhead *) cp; + siz = 1 << (nu + 3); + while (1) + { + ((struct mhead *) cp) -> mh_alloc = ISFREE; + ((struct mhead *) cp) -> mh_index = nu; +#ifdef rcheck + ((struct mhead *) cp) -> mh_magic4 = MAGICFREE4; +#endif /* rcheck */ +#ifdef scribblecheck + { + /* Check that upper stuff was still MAGIC1 */ + register char *m = (char *)((struct mhead *)cp+1); + register char *en = (8< mh_alloc = ISFREE; + ((struct mhead *) cp) -> mh_index = 0; +#ifdef rcheck + ((struct mhead *) cp) -> mh_magic4 = MAGICFREE4; +#endif /* rcheck */ + cp += 8; + + for (nu = 0; nu < 7; nu++) + { + CHAIN (cp) = nextf[nu]; + nextf[nu] = (struct mhead *) cp; + ((struct mhead *) cp) -> mh_alloc = ISFREE; + ((struct mhead *) cp) -> mh_index = nu; +#ifdef rcheck + ((struct mhead *) cp) -> mh_magic4 = MAGICFREE4; +#endif /* rcheck */ +#ifdef scribblecheck + { + register char *m = (char *)((struct mhead *)cp+1); + register char *en = (8<> 2; + + while (shiftr >>= 1) + nunits++; + } + + /* If there are no blocks of the appropriate size, go get some */ + /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */ + if (nextf[nunits] == 0) + morecore (nunits); + + /* Get one block off the list, and set the new list head */ + if ((p = nextf[nunits]) == 0) + return 0; + nextf[nunits] = CHAIN (p); + + /* Check for free block clobbered */ + /* If not for this check, we would gobble a clobbered free chain ptr */ + /* and bomb out on the NEXT allocate of this size block */ + if (p -> mh_alloc != ISFREE || p -> mh_index != nunits) +#ifdef rcheck + botch ("block on free list clobbered"); +#else /* not rcheck */ + abort (); +#endif /* not rcheck */ +#ifdef rcheck + if (p -> mh_magic4 != MAGICFREE4) + botch ("Magic in block on free list clobbered"); +#endif /* rcheck */ +#ifdef scribblecheck + /* Check for block filled with magic numbers, then change to zeros */ + { + register char *m = (char *) (p + 1); + register char *en = (8<mh_index) + (char *) p; + register int block_valid = 0; + while(m mh_alloc = ISALLOC; + p -> mh_nbytes = n; +#ifdef rcheck + p -> mh_magic4 = MAGIC4; + { + register char *m = (char *) (p + 1) + n; +#ifdef scribblecheck + register char *en = (8<mh_index)+(char *)p; + /* point to end of block */ + while (m mh_alloc == ISALLOC); +#ifdef rcheck + ASSERT (p -> mh_magic4 == MAGIC4); + ap += p -> mh_nbytes; + p->mh_magic4 = MAGICFREE4; + ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1); + ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1); +#endif /* rcheck */ + } + { + register int nunits = p -> mh_index; + + ASSERT (nunits <= 29); +#ifdef scribblecheck + { + /* Check that upper stuff was still MAGIC1 */ + register char *m = (char *) (p + 1) + p->mh_nbytes; + register char *en = (8<mh_index) + (char *) p; + register int block_valid = 0; + while(m mh_alloc = ISFREE; + CHAIN (p) = nextf[nunits]; + nextf[nunits] = p; +#ifdef MSTATS + nmalloc[nunits]--; + nfre++; +#endif /* MSTATS */ + } +} + +/**************************************************************** + * * + * realloc - resize a block, copy if necessary * + * * + ****************************************************************/ + +char * +realloc (mem, n) + char *mem; + register unsigned n; +{ + register struct mhead *p; + register unsigned int tocopy; + register int nbytes; + register int nunits; + + if ((p = (struct mhead *) mem) == 0) + return malloc (n); + p--; + nunits = p -> mh_index; + ASSERT (p -> mh_alloc == ISALLOC); + tocopy = p -> mh_nbytes; +#ifdef rcheck + ASSERT (p -> mh_magic4 == MAGIC4); + { + register char *m = mem + tocopy; +#ifdef scribblecheck + register char *en = (8<mh_index) + (char *)p; + register int block_valid = 0; + while(m (4 << nunits) && nbytes <= (8 << nunits)) + { + /* Here we check on realloc if we are grabbing unused space */ +#ifdef rcheck + register char *m = mem + tocopy; +#ifdef scribblecheck + register char *en = (8<mh_index) + (char *) p; + while (m mh_nbytes = n; + return mem; + } + + if (n < tocopy) + tocopy = n; + { + register char *new; + + if ((new = malloc (n)) == 0) + return 0; + bcopy (mem, new, tocopy); + free (mem); + return new; + } +} + +/**************************************************************** + * * + * Memory Statistics stuff * + * * + ****************************************************************/ + +#ifdef MSTATS +/* Return statistics describing allocation of blocks of size 2**n. */ + +struct mstats_value + { + int blocksize; + int nfree; + int nused; + }; + +struct mstats_value +malloc_stats (size) + int size; +{ + struct mstats_value v; + register int i; + register struct mhead *p; + + v.nfree = 0; + + if (size < 0 || size >= 30) + { + v.blocksize = 0; + v.nused = 0; + return v; + } + + v.blocksize = 1 << (size + 3); + v.nused = nmalloc[size]; + + for (p = nextf[size]; p; p = CHAIN (p)) + v.nfree++; + + return v; +} +#endif /* MSTATS */ + +#ifdef notdef +/**************************************************************** + * * + * Stuff having to do with determining memory limits * + * * + ****************************************************************/ + +/* + * This function returns the total number of bytes that the process + * will be allowed to allocate via the sbrk(2) system call. On + * BSD systems this is the total space allocatable to stack and + * data. On USG systems this is the data space only. + */ + +#ifdef USG + +get_lim_data () +{ + extern long ulimit (); + + lim_data = ulimit (3, 0); + lim_data -= (long) data_space_start; +} + +#else /* not USG */ +#ifndef BSD42 + +get_lim_data () +{ + lim_data = vlimit (LIM_DATA, -1); +} + +#else /* BSD42 */ + +get_lim_data () +{ + struct rlimit XXrlimit; + + getrlimit (RLIMIT_DATA, &XXrlimit); + lim_data = XXrlimit.rlim_cur; /* soft limit */ +} + +#endif /* BSD42 */ +#endif /* not USG */ +#endif notdef + +/* + * Calloc - allocate and clear memory block + */ +char * +calloc(num, size) + register unsigned num, size; +{ + extern char *malloc(); + register char *p; + + size *= num; + if (p = malloc(size)) + bzero(p, size); + return (p); +} + +cfree(p, num, size) + char *p; + unsigned num; + unsigned size; +{ + free(p); +} diff --git a/update/Makefile b/update/Makefile new file mode 100644 index 00000000..30f63621 --- /dev/null +++ b/update/Makefile @@ -0,0 +1,170 @@ +# +# $Source$ +# $Header$ +# + +# +# Makefile for 'update' directory. +# + +CC= cc +INCS= -I../include +DEFS= +CFLAGS= -g ${INCS} ${DEFS} +LINTFLAGS= ${INCS} +LDFLAGS= -x + +# server object files +SOBJS= dispatch.o initialize_server.o \ + quit.o xfer_001.o misc.o inst_001.o sync.o auth_001.o \ + exec_001.o get_file.o xfer_002.o exec_002.o + +# client object files +COBJS= client2.o ticket.o send_file.o + +# common object files +COMOBJS= log_error.o hostname.o smsu_int.o log.o checksum.o + +SSRCS= dispatch.c initialize_server.c \ + quit.c xfer_001.c misc.c inst_001.c sync.c auth_001.c \ + exec_001.c get_file.c xfer_002.c exec_002.c + +CSRCS= client.c ticket.c send_file.c client2.c + +COMSRCS= log_error.c hostname.c log.c checksum.c + +# libmisc.a includes libcom_err.a and a working malloc() +LIBS= -L../lib -lgdb -lkrb -ldes -lcom_err + +all: server sms_update.o test + +clean: + -rm -f ${COBJS} ${SOBJS} ${COMOBJS} + -rm -f server sms_update.o test test.o smsu_int.h + -rm -f core a.out *~ \#* + +lint: + lint ${LINTFLAGS} ${SSRCS} ${COMSRCS} + lint ${LINTFLAGS} ${CSRCS} ${COMSRCS} + +server: ${SOBJS} ${COMOBJS} + rm -f server + ${CC} ${CFLAGS} -o server ${SOBJS} ${COMOBJS} ${LIBS} + +sms_update.o: ${COBJS} ${COMOBJS} + ld ${LDFLAGS} -r -o sms_update.o ${COBJS} ${COMOBJS} + -chmod -x sms_update.o + +smsu_int.o smsu_int.h: smsu_int.et + ../lib/et/compile_et smsu_int + +test.o: test.c + -rm -f test.o + ${CC} ${CFLAGS} -c test.c + +test: test.o sms_update.o + rm -f test + ${CC} ${CFLAGS} -o test test.o sms_update.o ${LIBS} + +SRCS= ${SSRCS} ${CSRCS} ${COMSRCS} +depend: smsu_int.h + -rm -f eddep makedep + ${CC} -M ${CFLAGS} ${SRCS} | \ + sed -e 's; ./; ;' \ + -e ':loop' \ + -e 's/\.\.\/[^ /]*\/\.\./../' \ + -e 't loop' | \ + awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \ + else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ + else rec = rec " " $$2 } } \ + END { print rec } ' > makedep + echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep + echo '$$r makedep' >>eddep + echo 'w' >>eddep + -rm -f Makefile.bak + cp Makefile Makefile.bak + ed - Makefile < eddep + rm -f eddep makedep +# +# the last line in the makefile should be... +# DO NOT DELETE THIS LINE + +dispatch.o: dispatch.c /usr/include/stdio.h ../include/gdb.h +dispatch.o: /usr/include/sys/types.h /usr/include/sys/time.h +dispatch.o: /usr/include/time.h /usr/include/errno.h /usr/include/strings.h +dispatch.o: ../include/update.h sms_update_int.h smsu_int.h kludge.h +initialize_server.o: initialize_server.c /usr/include/stdio.h ../include/gdb.h +initialize_server.o: /usr/include/sys/types.h /usr/include/sys/time.h +initialize_server.o: /usr/include/time.h +quit.o: quit.c /usr/include/stdio.h ../include/gdb.h /usr/include/sys/types.h +quit.o: /usr/include/sys/time.h /usr/include/time.h +xfer_001.o: xfer_001.c /usr/include/stdio.h /usr/include/strings.h +xfer_001.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +xfer_001.o: /usr/include/time.h /usr/include/ctype.h /usr/include/sys/param.h +xfer_001.o: /usr/include/machine/machparam.h /usr/include/signal.h +xfer_001.o: /usr/include/sys/types.h /usr/include/sys/file.h smsu_int.h +xfer_001.o: kludge.h +misc.o: misc.c /usr/include/stdio.h ../include/gdb.h /usr/include/sys/types.h +misc.o: /usr/include/sys/time.h /usr/include/time.h sms_update_int.h kludge.h +misc.o: /usr/include/sys/param.h /usr/include/machine/machparam.h +misc.o: /usr/include/signal.h /usr/include/sys/types.h smsu_int.h +inst_001.o: inst_001.c /usr/include/stdio.h ../include/gdb.h +inst_001.o: /usr/include/sys/types.h /usr/include/sys/time.h +inst_001.o: /usr/include/time.h kludge.h sms_update_int.h +sync.o: sync.c /usr/include/stdio.h ../include/gdb.h /usr/include/sys/types.h +sync.o: /usr/include/sys/time.h /usr/include/time.h kludge.h smsu_int.h +auth_001.o: auth_001.c /usr/include/stdio.h /usr/include/strings.h +auth_001.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +auth_001.o: /usr/include/time.h smsu_int.h kludge.h /usr/include/krb.h +auth_001.o: /usr/include/des.h /usr/include/netinet/in.h /usr/include/errno.h +exec_001.o: exec_001.c /usr/include/stdio.h ../include/gdb.h +exec_001.o: /usr/include/sys/types.h /usr/include/sys/time.h +exec_001.o: /usr/include/time.h sms_update_int.h kludge.h smsu_int.h +get_file.o: get_file.c /usr/include/stdio.h ../include/gdb.h +get_file.o: /usr/include/sys/types.h /usr/include/sys/time.h +get_file.o: /usr/include/time.h /usr/include/ctype.h /usr/include/sys/param.h +get_file.o: /usr/include/machine/machparam.h /usr/include/signal.h +get_file.o: /usr/include/sys/types.h /usr/include/sys/file.h +get_file.o: ../include/update.h smsu_int.h kludge.h +xfer_002.o: xfer_002.c /usr/include/stdio.h ../include/gdb.h +xfer_002.o: /usr/include/sys/types.h /usr/include/sys/time.h +xfer_002.o: /usr/include/time.h /usr/include/ctype.h /usr/include/sys/param.h +xfer_002.o: /usr/include/machine/machparam.h /usr/include/signal.h +xfer_002.o: /usr/include/sys/types.h /usr/include/sys/file.h smsu_int.h +xfer_002.o: kludge.h /usr/include/strings.h +exec_002.o: exec_002.c /usr/include/stdio.h /usr/include/sys/wait.h +exec_002.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +exec_002.o: /usr/include/time.h ../include/update.h sms_update_int.h kludge.h +exec_002.o: smsu_int.h +client.o: client.c /usr/include/stdio.h ../include/gdb.h +client.o: /usr/include/sys/types.h /usr/include/sys/time.h /usr/include/time.h +client.o: /usr/include/sys/stat.h /usr/include/sys/file.h +client.o: /usr/include/sys/param.h /usr/include/machine/machparam.h +client.o: /usr/include/signal.h /usr/include/sys/types.h ../include/update.h +client.o: /usr/include/errno.h sms_update_int.h smsu_int.h /usr/include/krb.h +client.o: /usr/include/des.h kludge.h +stubs.o: stubs.c ../include/update.h +ticket.o: ticket.c /usr/include/stdio.h /usr/include/krb.h /usr/include/des.h +ticket.o: /usr/include/sys/types.h /usr/include/sys/stat.h +ticket.o: /usr/include/strings.h sms_update_int.h ../include/com_err.h +ticket.o: ../include/mit-sipb-copyright.h kludge.h +send_file.o: send_file.c /usr/include/stdio.h ../include/com_err.h +send_file.o: ../include/mit-sipb-copyright.h ../include/gdb.h +send_file.o: /usr/include/sys/types.h /usr/include/sys/time.h +send_file.o: /usr/include/time.h smsu_int.h /usr/include/sys/file.h +send_file.o: ../include/update.h sms_update_int.h kludge.h +client2.o: client2.c /usr/include/stdio.h /usr/include/strings.h +client2.o: ../include/gdb.h /usr/include/sys/types.h /usr/include/sys/time.h +client2.o: /usr/include/time.h /usr/include/sys/stat.h /usr/include/sys/file.h +client2.o: /usr/include/sys/param.h /usr/include/machine/machparam.h +client2.o: /usr/include/signal.h /usr/include/sys/types.h ../include/update.h +client2.o: /usr/include/errno.h sms_update_int.h smsu_int.h /usr/include/krb.h +client2.o: /usr/include/des.h kludge.h +log_error.o: log_error.c /usr/include/stdio.h /usr/include/syslog.h +hostname.o: hostname.c /usr/include/stdio.h /usr/include/sys/types.h +hostname.o: /usr/include/netinet/in.h /usr/include/netdb.h /usr/include/ctype.h +hostname.o: /usr/include/strings.h +log.o: log.c /usr/include/stdio.h ../include/com_err.h +log.o: ../include/mit-sipb-copyright.h /usr/include/varargs.h +log.o: ../include/update.h /usr/include/krb.h /usr/include/des.h +checksum.o: checksum.c /usr/include/stdio.h /usr/include/sys/file.h diff --git a/update/auth_001.c b/update/auth_001.c new file mode 100644 index 00000000..47c9df59 --- /dev/null +++ b/update/auth_001.c @@ -0,0 +1,93 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_auth_001_c = "$Header$"; +#endif lint + +#include +#include +#include "gdb.h" +#include "smsu_int.h" +#include "kludge.h" +#include +#include +#include + +extern char buf[BUFSIZ]; +extern int have_authorization; +extern struct sockaddr_in *client_address(); +extern CONNECTION conn; +int code; +extern char *PrincipalHostname(); +static char sms[] = "sms"; +static char qmark[] = "???"; + +/* + * authentication request auth_001: + * + * >>> (STRING) "auth_001" + * <<< (int) 0 + * >>> (STRING) ticket + * <<< (int) code + * + */ + +int +auth_001(str) + char *str; +{ + STRING data; + char host[BUFSIZ]; + AUTH_DAT ad; + char realm[REALM_SZ]; + KTEXT_ST ticket_st; + + if (send_ok()) + lose("sending okay for authorization (auth_001)"); + code = receive_object(conn, (char *)&data, STRING_T); + if (code) { + code = connection_errno(conn); + lose("awaiting Kerberos authenticators"); + } + gethostname(host, BUFSIZ); + ticket_st.mbz = 0; + ticket_st.length = MAX_STRING_SIZE(data); + bcopy(STRING_DATA(data), ticket_st.dat, MAX_STRING_SIZE(data)); + code = rd_ap_req(&ticket_st, sms, + PrincipalHostname(host), 0, + &ad, "/etc/srvtab"); + if (code) { + code = krb_err_frob(code); + strcpy(ad.pname, qmark); + strcpy(ad.pinst, qmark); + strcpy(ad.prealm, qmark); + goto auth_failed; + } + if (get_krbrlm(realm,0)) + realm[0] = '\0'; + code = EPERM; + if (strcmp(sms, ad.pname)) + goto auth_failed; + if (ad.pinst[0] != '\0') + goto auth_failed; + if (strcmp(realm, ad.prealm)) + goto auth_failed; + if (send_ok()) + lose("sending approval of authorization"); + have_authorization = 1; + return(0); +auth_failed: + sprintf(buf, "auth for %s.%s@%s failed: %s", + ad.pname, ad.pinst, ad.prealm, error_message(code)); + { + register int rc; + rc = send_object(conn, (char *)&code, INTEGER_T); + code = rc; + } + if (code) + lose("sending rejection of authenticator"); + return(EPERM); +} diff --git a/update/checksum.c b/update/checksum.c new file mode 100644 index 00000000..c2336aaf --- /dev/null +++ b/update/checksum.c @@ -0,0 +1,36 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_checksum_c = "$Header$"; +#endif lint + +#include +#include + +/* + * checksum_fd(fd) + * returns 24-bit checksum of bytes in file + */ + +int +checksum_fd(fd1) + int fd1; +{ + int fd; + register int sum; + register int ch; + register FILE *f; + + fd = dup(fd1); + sum = 0; + (void) lseek(fd, 0, L_SET); + f = fdopen(fd, "r"); + while ((ch = getc(f)) != EOF) { + sum = (sum + ch) & ((1<<24)-1); + } + fclose(f); + return(sum); +} diff --git a/update/client.c b/update/client.c new file mode 100644 index 00000000..3c115183 --- /dev/null +++ b/update/client.c @@ -0,0 +1,421 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_client2_c = "$Header$"; +#endif lint + +/* + * MODULE IDENTIFICATION: + * $Header$ + * Copyright 1987 MIT Project Athena. + * DESCRIPTION: + * This code handles the actual distribution of data files + * to servers in the SMS server-update program. + * AUTHOR: + * Ken Raeburn (spook@athena.MIT.EDU), + * MIT Project Athena/MIT Information Systems. + * DEFINED VALUES: + * conn + * update_info + * sms_update_server + * VERSION HISTORY: + * $Log$ + * Revision 1.1 1987-08-22 17:53:46 wesommer + * Initial revision + * + */ + +#include +#include +#include "gdb.h" +#include +#include +#include +#include "update.h" +#include +#include "sms_update_int.h" +#include "smsu_int.h" +#include + +extern char *malloc(), *error_message(); +extern int errno; + +/* XXX */ +#include "kludge.h" +/* XXX */ + +static char buf[BUFSIZ]; + +CONNECTION conn; +struct update_desc *info; + +static int code; + +/* + * FUNCTION: + * initialize() + * DESCRIPTION: + * Insures that various libraries have a chance to get + * initialized. + * INPUT: + * OUTPUT: + * RETURN VALUE: + * void + * SIDE EFFECTS: + * Initializes GDB library and SMSU error table. + * PROBLEMS: + * + */ +static +void +initialize() +{ + static int initialized = 0; + if (!initialized) { + gdb_init(); + init_smsU_err_tbl(); + initialized++; + } +} + +/* + * FUNCTION: + * sms_update_server(info) + * DESCRIPTION: + * Attempts to perform an update based on the information + * contained in the data structure pointed to by "info". + * Errors in performing the update are logged with the + * sms_log* routines; the 'override' field may be updated + * to cause updates to occur other than on the regular + * schedule (generally to force an earlier retry). + * INPUT: + * info->service_name + * Name of service to be updated; used to find + * the source data file in the SMS data directory. + * info->host_name + * info->target_path + * Location to install the file. + * info->enable + * Must be non-zero. + * info->instructions + * Sequence of commands to execute on remote + * machine to effect the installation. + * OUTPUT: + * info->last_time + * Set to the current time if the update was + * attempted. + * info->success + * Set to non-zero if the update succeeded, set + * to zero otherwise. + * info->override + * Set to -1 if the update succeeds, to (possibly) + * some other value otherwise. + * RETURN VALUE: + * int: + * Error code, or zero if no error was detected + * in the data supplied to this routine. + * SIDE EFFECTS: + * May write information to logs. + * PROBLEMS: + * + */ + +int +sms_update_server(update_info, pathname) + struct update_desc *update_info; + char *pathname; +{ +#define ASSERT(condition,amsg) \ + if (!(condition)) { msg = amsg; code = 0; goto local_error; } +#define NONNULL(str) \ + (((str) != (char *)NULL) && ((size = strlen(str)) != 0)) +#define IO_ERROR(msg) \ + {log_priority=log_ERROR;com_err(whoami,connection_errno(conn),msg);goto io_error;} + + char *service_address; + char *service_updated; + char *msg; + register char *cp; + STRING string_data, string2; + int size, num; + int fd = -1; + struct stat statb; + + /* variable initializations */ + code = 0; + info = update_info; + service_updated = (char *)NULL; + STRING_DATA(string_data) = (char *)NULL; + + /* pessimism */ + info->success = 0; + + /* some sanity checking of arguments while we build data */ + strcpy(buf, "???:???"); + ASSERT(NONNULL(info->host_name), "null host name"); + /* XXX -- check length here */ + strcpy(buf, info->host_name); + for (cp = buf; *cp; cp++) + ; + strcpy(cp, ":???"); + ASSERT(NONNULL(info->service_name), "null service name"); + /* XXX -- check length here */ + strcpy(++cp, info->service_name); + service_updated = malloc(strlen(buf)+1); + /* XXX -- check allocation succeeded */ + strcpy(service_updated, buf); + service_address = malloc(strlen(SERVICE_NAME)+strlen(info->host_name)+1); + if (!service_address) { + code = errno; + info->override = -1; + return(code); + } + strcpy(service_address, info->host_name); + strcat(service_address, ":"); + strcat(service_address, SERVICE_NAME); + ASSERT(info->enable, "server is disabled"); + ASSERT(NONNULL(info->target_path), "null target pathname"); + ASSERT(size < MAXPATHLEN, "target pathname too long"); + ASSERT(info->target_path[0] == '/', "non-absolute pathname supplied"); + + initialize(); + + string_alloc(&string2, BUFSIZ); + + sprintf(buf, "starting update for %s", service_updated); + sms_log_info(buf); + + fd = open(pathname, O_RDONLY, 0); + if (fd < 0) { + code = errno; + msg = pathname; + goto local_error; + } + if (fstat(fd, &statb)) { + code = errno; + close(fd); fd = -1; + strcat(buf, ": can't fstat:"); + strcat(buf, error_message(code)); + sms_log_error(buf); + goto error_exit; + } + size = statb.st_size; + + /* open connection */ + conn = start_server_connection(service_address, 0); + if (!conn) { + com_err(whoami, 0, "can't connect to update %s", service_address); + connect_failed: + if (info->override<0 || info->override>INTERVAL_connection_failed) + info->override = INTERVAL_connection_failed; + return(0); + } + else if (connection_status(conn) == CON_STOPPED) { + com_err(whoami, connection_errno(conn), ": can't connect to update %s", + service_address); + goto connect_failed; + } + + + /* send authenticators */ + code = send_auth(); + if (code) { + sprintf(buf, "authorization attempt to %s failed: %s\n", + service_updated, error_message(code)); + goto update_failed; + } + + /* send file over */ + fd = open(pathname, O_RDONLY, 0); + if (fd < 0) { + code = errno; + msg = pathname; + goto local_error; + } + sprintf(STRING_DATA(string2), "XFER_002 %d %d %s", + size, checksum_fd(fd), info->target_path); + code = send_object(conn, (char *)&string2, STRING_T); + if (code) + IO_ERROR("%s: sending XFER_002 request"); + code = receive_object(conn, (char *)&num, INTEGER_T); + if (code) + IO_ERROR("%s: getting reply from XFER_002 request"); + if (num) { + sprintf(buf, "transfer request to %s (XFER_002) rejected: %s", + service_updated, error_message(num)); + update_failed: + sms_log_error(buf); + /* + * * if the update fails, something is probably wrong on + * * the remote side; we'll have to let a maintainer + * * take care of it. don't bother trying again any sooner + * * than INTERVAL_update_failed minutes + * */ + update_failed_1: + if (info->override < INTERVAL_update_failed && info->override != -1) + info->override = INTERVAL_update_failed; + goto do_quit; + } + /* send actual data */ + code = send_file(pathname, size); + if (code) + goto update_failed_1; + string_free(&string_data); + close(fd); + + /* send instructions for installation */ + strcpy(buf, "/tmp/sms-update.XXXXXX"); + mktemp(buf); + fd = open(info->instructions, O_RDONLY, 0); + if (fd < 0) { + code = errno; + log_priority = log_ERROR; + com_err(whoami, code, ": can't open %s", info->instructions); + send_quit(); + info->override = INTERVAL_local_error; + goto error_exit; + } + if (fstat(fd, &statb)) { + code = errno; + close(fd); + fd = -1; + log_priority = log_ERROR; + com_err(whoami, code, ": can't fstat %s", info->instructions); + goto error_exit; + } + sprintf(STRING_DATA(string2), "XFER_002 %d %d %s", + statb.st_size, checksum_fd(fd), buf); + code = send_object(conn, (char *)&string2, STRING_T); + if (code) + IO_ERROR("%s: sending request for transfer of instructions"); + code = receive_object(conn, (char *)&num, INTEGER_T); + if (code) + IO_ERROR("%s: lost reply from installation script request"); + if (num) { + com_err(whoami, num, ": transfer request rejected for %s", buf); + goto update_failed_1; + } + code = send_file(info->instructions, statb.st_size); + if (code) + goto update_failed_1; + + /* perform installation */ + code = execute(buf); + if (code) { + sprintf(buf, "installation of %s failed: %s", service_updated, + error_message(code)); + sms_log_error(buf); + } + + /* clear override timer and indicate success */ + info->override = -1; + info->success = 1; + + /* finished updates */ +do_quit: + send_quit(); + + /* fall through */ +EGRESS: + code = 0; +error_exit: + info->last_time = time((long *)0); + if (STRING_DATA(string2)) + string_free(&string2); + if (STRING_DATA(string_data)) + string_free(&string_data); + conn = sever_connection(conn); + return(code); + +local_error: + log_priority = log_ERROR; + com_err(whoami, code, code ? ": %s" : "%s", msg); + return(SMSU_INTERNAL_ERROR); + +io_error: + sms_log_error(buf); + if (info->override== -1 || info->override > INTERVAL_connection_lost) + info->override = INTERVAL_connection_lost; + goto EGRESS; + +#undef IO_ERROR +#undef NONNULL +#undef ASSERT +} + +static +send_auth() +{ + KTEXT_ST ticket_st; + KTEXT ticket = &ticket_st; + STRING data; + register int code; + int response; + + code = get_sms_update_ticket(info->host_name, ticket); + if (code) { + return(code); + } + STRING_DATA(data) = "AUTH_001"; + MAX_STRING_SIZE(data) = 9; + code = send_object(conn, (char *)&data, STRING_T); + if (code) { + return(connection_errno(conn)); + } + code = receive_object(conn, (char *)&response, INTEGER_T); + if (code) { + return(connection_errno(conn)); + } + if (response) { + return(response); + } + STRING_DATA(data) = (char *)ticket->dat; + MAX_STRING_SIZE(data) = ticket->length; + code = send_object(conn, (char *)&data, STRING_T); + if (code) { + return(connection_errno(conn)); + } + code = receive_object(conn, (char *)&response, INTEGER_T); + if (code) { + return(connection_errno(conn)); + } + if (response) { + return(response); + } + return(0); +} + +static +execute(path) + char *path; +{ + int response; + STRING data; + register int code; + + string_alloc(&data, BUFSIZ); + sprintf(STRING_DATA(data), "EXEC_002 %s", path); + code = send_object(conn, (char *)&data, STRING_T); + if (code) + return(connection_errno(conn)); + code = receive_object(conn, (char *)&response, INTEGER_T); + if (code) + return(connection_errno(conn)); + if (response) + return(response); + return(0); +} + +send_quit() +{ + STRING str; + if (!conn) + return; + string_alloc(&str, 5); + (void) strcpy(STRING_DATA(str), "quit"); + (void) send_object(conn, (char *)&str, STRING_T); + string_free(&str); +} diff --git a/update/exec_002.c b/update/exec_002.c new file mode 100644 index 00000000..4f4d06c4 --- /dev/null +++ b/update/exec_002.c @@ -0,0 +1,65 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_exec_002_c = "$Header$"; +#endif lint + +#include +#include +#include "gdb.h" +#include "update.h" +#include "sms_update_int.h" +#include "kludge.h" +#include "smsu_int.h" + +extern CONNECTION conn; +extern int code, errno; + +int +exec_002(str) + char *str; +{ + union wait waitb; + int n, pid; + + str += 8; + while (*str == ' ') + str++; + pid = fork(); + switch (pid) { + case -1: + n = errno; + log_priority = log_ERROR; + com_err(whoami, errno, ": can't fork to run install script"); + code = send_object(conn, (char *)&n, INTEGER_T); + if (code) + exit(1); + return; + case 0: + execlp(str, str, (char *)NULL); + n = errno; + log_priority = log_ERROR; + com_err(whoami, n, ": %s", str); + (void) send_object(conn, (char *)&n, INTEGER_T); + exit(1); + default: + do { + n = wait(&waitb); + } while (n != -1 && n != pid); + if (waitb.w_status) { + log_priority = log_ERROR; + com_err(whoami, 0, "child exited with status %d", waitb.w_status); + code = send_object(conn, (char *)&n, INTEGER_T); + if (code) + exit(1); + } + else { + code = send_ok(); + if (code) + exit(1); + } + } +} diff --git a/update/get_file.c b/update/get_file.c new file mode 100644 index 00000000..8495caa9 --- /dev/null +++ b/update/get_file.c @@ -0,0 +1,190 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_get_file_c = "$Header$"; +#endif lint + +#include +#include "gdb.h" +#include +#include +#include +#include "update.h" +#include "smsu_int.h" +#include "kludge.h" + +extern CONNECTION conn; +char buf[BUFSIZ]; + +extern int code, errno; + +extern int have_authorization, have_file, done; + +int get_block(); + +/* + * get_file() + * + * arguments: + * char *pathname + * file to receive + * int file_size + * number of bytes + * int checksum + * linear checksum of bytes + * + * syntax: + * (initial protocol already done) + * <<< (int)code (can we accept the file?) + * >>> (STRING)data + * <<< (int)code + * >>> (STRING)data + * <<< (int)code + * ... + * >>> (STRING)data (last data block) + * <<< (int)code (from read, write, checksum verify) + * + * returns: + * int + * 0 for success, 1 for failure + * + * function: + * perform initial preparations and receive file as + * a single string, storing it into + * + */ + +int +get_file(pathname, file_size, checksum) + char *pathname; + int file_size; + int checksum; +{ + int fd, n_written; + int found_checksum; + + if (!have_authorization) { + reject_call(SMSU_NO_AUTH); + return(1); + } + if (done) /* re-initialize data */ + initialize(); + /* unlink old file */ + (void) unlink(pathname); + /* open file descriptor */ + fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY, 0700); + if (fd == -1) { + code = errno; + sprintf(buf, "%s: creating file %s (get_file)", + error_message(code), pathname); + sms_log_error(buf); + report_error("reporting file creation error (get_file)"); + return(1); + } + /* check to see if we've got the disk space */ + n_written = 0; + while (n_written < file_size) { + register int n_wrote; + n_wrote = write(fd, buf, sizeof(buf)); + if (n_wrote == -1) { + code = errno; + sprintf(buf, "%s: verifying free disk space for %s (get_file)", + error_message(code), pathname); + sms_log_error(buf); + /* do all we can to free the space */ + (void) unlink(pathname); + (void) ftruncate(fd, 0); + (void) close(fd); + report_error("reporting test-write error (get_file)"); + return(1); + } + n_written += n_wrote; + } + lseek(fd, 0, L_SET); + if (send_ok()) + lose("sending okay for file transfer (get_file)"); + n_written = 0; + while (n_written < file_size && code == 0) { + int n_got = get_block(fd, file_size - n_written); + if (n_got == -1) { + /* get_block has already printed a message */ + unlink(pathname); + return(1); + } + n_written += n_got; + if (n_written != file_size) + if (send_ok()) + lose("receiving data"); + } + if (code) { + code = connection_errno(conn); + report_error("reading file (get_file)"); + return(1); + } + fsync(fd); + ftruncate(fd, file_size); + fsync(fd); + close(fd); + /* validate checksum */ + fd = open(pathname, O_RDONLY, 0); + if (fd == -1) { + code = errno; + report_error("re-opening file for checksum verification"); + return(1); + } + found_checksum = checksum_fd(fd); + if (checksum != found_checksum) { + code = SMSU_CHECKSUM; + com_err(whoami, code, ": expected = %d, found = %d", + checksum, found_checksum); + report_error("checksum error"); + return(1); + } + close(fd); + /* send ack or nack */ + have_file = 1; + if (send_ok()) { + code = connection_errno(conn); + (void) unlink(pathname); + lose("sending ok after file transfer (get_file)"); + return(1); + } + return(0); +} + +static int +get_block(fd, max_size) + int fd; + int max_size; +{ + STRING data; + int n_read, n; + + code = receive_object(conn, (char *)&data, STRING_T); + if (code) { + code = connection_errno(conn); + lose("receiving data file (get_file)"); + } + n_read = MIN(MAX_STRING_SIZE(data), max_size); + n = 0; + while (n < n_read) { + register int n_wrote; + n_wrote = write(fd, STRING_DATA(data)+n, + n_read-n); + if (n_wrote == -1) { + code = errno; + sprintf(buf, "%s: writing file (get_file)", error_message(code)); + sms_log_error(buf); + string_free(&data); + report_error("reporting write error (get_file)"); + close(fd); + return(-1); + } + n += n_wrote; + } + string_free(&data); + return(n); +} diff --git a/update/hostname.c b/update/hostname.c new file mode 100644 index 00000000..09a9129d --- /dev/null +++ b/update/hostname.c @@ -0,0 +1,34 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_hostname_c = "$Header$"; +#endif lint + +/* PrincipalHostname, borrowed from rcmd.c in Kerberos code */ +#include +#include +#include +#include +#include +#include +char * +PrincipalHostname(alias) + char *alias; +{ + struct hostent *h; + char *phost = alias; + if ((h=gethostbyname(alias)) != (struct hostent *)NULL) { + char *p = index(h->h_name, '.'); + if (p) + *p = NULL; + p = phost = h->h_name; + do { + if (isupper(*p)) + *p = tolower(*p); + } while (*p++); + } + return(phost); +} diff --git a/update/inst_001.c b/update/inst_001.c new file mode 100644 index 00000000..195ce441 --- /dev/null +++ b/update/inst_001.c @@ -0,0 +1,43 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_inst_001_c = "$Header$"; +#endif lint + +#include +#include "gdb.h" +#include "kludge.h" +#include "sms_update_int.h" + +STRING instructions = { 0, 0 }; +extern CONNECTION conn; +extern int have_instructions; +extern int code; + +/* + * instruction sequence transmission: + * syntax: + * >>> (STRING) "inst_001" + * <<< (int)0 + * >>> (STRING) instructions + * <<< (int)0 + */ + +inst_001(str) + char *str; +{ + if (send_ok()) + lose("sending okay for inst_001"); + code = receive_object(conn, (char *)&instructions, STRING_T); + if (code) { + report_error("reporting failure to receive instructions"); + return; + } + have_instructions = 1; + if (send_ok()) + lose("sending okay after instructions"); + dprintf(("got instructions: %s\n", STRING_DATA(instructions))); +} diff --git a/update/log.c b/update/log.c new file mode 100644 index 00000000..7d352bb2 --- /dev/null +++ b/update/log.c @@ -0,0 +1,92 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_log_c = "$Header$"; +#endif lint + +/* + * handle logging for dcm and update server + * + * this should eventually use zephyr + */ + +/* + * define syslog for using syslog, + * default to tty + */ +#define use_syslog + +#include +#include "com_err.h" +#include +#include "update.h" +#include + +#ifdef use_syslog +#include +#else +#define use_tty +#endif + +#ifdef use_syslog +int syslog_prio[] = { + LOG_DEBUG, + LOG_INFO, + LOG_WARNING, + LOG_ERR +}; +#endif +int log_priority; + +sms_update_com_err_hook(whoami, code, fmt, args) + char *whoami; + int code; + char *fmt; + va_list args; +{ + char buf[BUFSIZ], *cp; + FILE _strbuf; + +#ifndef use_syslog + strcpy(buf, whoami); + for (cp = buf; *cp; cp++) + ; + *cp++ = ':'; + *cp++ = ' '; +#else + cp = buf; + *cp = '\0'; +#endif + if (code) { + strcpy(cp, error_message(code)); + while (*cp) + cp++; + } + _strbuf._flag = _IOWRT+_IOSTRG; + _strbuf._ptr = cp; + _strbuf._cnt = BUFSIZ-(cp-buf); + _doprnt(fmt, args, &_strbuf); + putc('\0', &_strbuf); +#ifdef use_syslog + syslog(syslog_prio[log_priority], "%s", buf); +#endif +#ifdef use_tty + puts(buf); +#endif +} + +sms_update_initialize() +{ + static int initialized = 0; + if (initialized) + return; +#ifdef use_syslog + openlog(whoami, LOG_PID, LOG_DAEMON); +#endif + (void) set_com_err_hook(sms_update_com_err_hook); + log_priority = log_INFO; + initialized = 1; +} diff --git a/update/send_file.c b/update/send_file.c new file mode 100644 index 00000000..6772736f --- /dev/null +++ b/update/send_file.c @@ -0,0 +1,113 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_send_file_c = "$Header$"; +#endif lint + +#include +#include "com_err.h" +#include "gdb.h" +#include "smsu_int.h" +#include +#include "update.h" +#include "sms_update_int.h" +#include "kludge.h" + +extern CONNECTION conn; +extern int errno; +char buf[BUFSIZ]; +extern struct update_desc *info; + +/* + * syntax: + * (already sent) pathname file_size checksum + * <<< (int)code can we send it? + * >>> data + * <<< 0 + * >>> data + * <<< 0 + * .... + * >>> data (last block) + * <<< 0 (on final write, close, sync, checksum) + * + * returns: + * 0 on success + * 1 on error (file not found, etc) + */ + +int +send_file(pathname, n_to_send) + char *pathname; + int n_to_send; +{ + int n, fd, code; + STRING data; + + fd = open(pathname, O_RDONLY, 0); + if (fd == -1) { + sprintf(buf, "%s: can't open %s for transmission", + error_message(errno), pathname); + sms_log_error(buf); + return(1); + } + code = receive_object(conn, (char *)&n, INTEGER_T); + if (code) { + com_err(whoami, connection_errno(conn), ": lost connection"); + info->override = INTERVAL_connection_lost; + close(fd); + return(1); + } + if (n) { + log_priority = log_ERROR; + com_err(whoami, n, ": from remote server: can't update %s", + pathname); + info->override = INTERVAL_update_failed; + close(fd); + return(1); + } + string_alloc(&data, UPDATE_BUFSIZ); + while (n_to_send > 0) { +#ifdef DEBUG + printf("n_to_send = %d\n", n_to_send); +#endif /* DEBUG */ + n = read(fd, STRING_DATA(data), UPDATE_BUFSIZ); + if (n < 0) { + sprintf(buf, "%s: reading %s for transmission", + error_message(errno), pathname); + sms_log_error(buf); + close(fd); + return(1); + } + MAX_STRING_SIZE(data) = n; + code = send_object(conn, (char *)&data, STRING_T); + if (code) { + sprintf(buf, "%s: transmitting file %s", + error_message(connection_errno(conn)), pathname); + sms_log_error(buf); + close(fd); + return(1); + } + n_to_send -= n; + code = receive_object(conn, (char *)&n, INTEGER_T); + if (code) { + sprintf(buf, + "%s: awaiting ACK remote server during transmission of %s", + error_message(connection_errno(conn)), pathname); + sms_log_error(buf); + close(fd); + return(1); + } + if (n) { + sprintf(buf, "%s: from remote server during transmission of %s", + error_message(n), pathname); + sms_log_error(buf); + close(fd); + return(1); + } + } + close(fd); + return(0); +} diff --git a/update/ticket.c b/update/ticket.c new file mode 100644 index 00000000..c27f3738 --- /dev/null +++ b/update/ticket.c @@ -0,0 +1,69 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_ticket_c = "$Header$"; +#endif lint + +#include +#include +#include +#include +#include +#include "sms_update_int.h" +#include "com_err.h" +#include "kludge.h" + +/* too bad we can't set the pathname easily */ +/*static char tkt_pathname[] = "/tmp/tkt:sms";*/ +static char *srvtab = SRVTAB; /* default == /etc/srvtab */ +static char realm[REALM_SZ]; +static char sms[] = "sms"; + +extern char *tkt_string(), *PrincipalHostname(); +static int initialized = 0; + +#define init() { if (!initialized) { get_krbrlm(realm,0); initialized=1; }} + +int +get_sms_update_ticket(host, ticket) + char *host; + KTEXT ticket; +{ + register int code; + register int pass; + char phost[BUFSIZ]; + + pass = 1; + init(); + strcpy(phost, PrincipalHostname(host)); + try_it: + code = mk_ap_req(ticket, sms, phost, realm, (long)0); + if (pass == 1) { + /* maybe we're taking too long? */ + if ((code = get_sms_tgt()) != 0) { + /* don't need phost buffer any more */ + sprintf(phost, "%s: can't get Kerberos TGT", + error_message(code)); + sms_log_error(phost); + return(code); + } + pass++; + goto try_it; + } + return(krb_err_frob(code)); +} + +int +get_sms_tgt() +{ + register int code; + init(); + code = get_svc_in_tkt(sms, "", realm, "krbtgt", realm, 1, srvtab); + if (!code) + return(0); + else + return(krb_err_frob(code)); +} diff --git a/update/update_server.c b/update/update_server.c new file mode 100644 index 00000000..06154637 --- /dev/null +++ b/update/update_server.c @@ -0,0 +1,145 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_dispatch_c = "$Header$"; +#endif lint + +#include +#include "gdb.h" +#include +#include +#include "update.h" +#include "sms_update_int.h" +#include "smsu_int.h" + +/* XXX */ +#include "kludge.h" +/* XXX */ + +extern int auth_001(), exec_001(), inst_001(), xfer_001(); +extern int xfer_002(), exec_002(); + +extern int sync_proc(), quit(); + +extern void gdb_debug(); +extern int exit(), abort(), errno; + +CONNECTION conn; +int code; +char *whoami; + +#define send_int(n) \ + (_send_int=(n),send_object(conn,(char *)&_send_int,INTEGER_T)) +int _send_int; + +struct _dt { + char *str; + int (*proc)(); +} dispatch_table[] = { + { "INST_001", inst_001 }, + { "AUTH_001", auth_001 }, + { "XFER_001", xfer_001 }, + { "EXEC_001", exec_001 }, + { "XFER_002", xfer_002 }, + { "EXEC_002", exec_002 }, + { "quit", quit }, + { (char *)NULL, abort } +}; + +/* + * general scratch space -- useful for building + * error messages et al... + */ +char buf[BUFSIZ]; +err(code, fmt) + int code; + char *fmt; +{ + sprintf(buf, fmt, error_message(code)); + sms_log_error(buf); +} + +main(argc, argv) + int argc; + char **argv; +{ + STRING str; + struct _dt *d; + +#ifdef DEBUG + gdb_debug(GDB_NOFORK); +#endif /* DEBUG */ + + whoami = rindex(argv[0], '/'); + if (whoami) + whoami++; + else + whoami = argv[0]; + + /* interpret arguments here */ + if (argc != 1) { + fprintf(stderr, "Usage: %s\n", whoami); + exit(1); + } + /* well, sort of... */ + + umask(0077); + sms_update_initialize(); + init_smsU_err_tbl(); + + /* wait for connection */ + gdb_init(); + conn = create_forking_server(SERVICE_NAME, 0); + if (!conn) { + err(errno, "%s: can't get connection"); + exit(1); + } + if (connection_status(conn) == CON_STOPPED) { + com_err(whoami, connection_errno(conn), ": can't get connection"); + exit(1); + } + + sms_log_info("got connection"); + /* got a connection; loop forever */ + while (1) { + register char *cp; + code = receive_object(conn, (char *)&str, STRING_T); + if (code) { + err(connection_errno(conn), "%s: receiving command"); + sever_connection(conn); + exit(1); + } + cp = index(STRING_DATA(str), ' '); + if (cp) + *cp = '\0'; + for (d = dispatch_table; d->str; d++) { + if (!strcmp(d->str, STRING_DATA(str))) { + if (cp) + *cp = ' '; +#ifdef DEBUG + printf("got request: %s\n", STRING_DATA(str)); +#endif /* DEBUG */ + (void)(d->proc)(STRING_DATA(str)); + goto ok; + } + } + sprintf(buf, "unknown request received: %s\n", STRING_DATA(str)); + sms_log_error(buf); + code = send_int(SMSU_UNKNOWN_PROC); + if (code) { + err(connection_errno(conn), "%s: sending UNKNOWN_PROC"); + } + ok: + string_free(&str); + } +} + +int +send_ok() +{ + static int zero = 0; + return((code = send_object(conn, (char *)&zero, INTEGER_T))); +} diff --git a/update/xfer_002.c b/update/xfer_002.c new file mode 100644 index 00000000..209af2c6 --- /dev/null +++ b/update/xfer_002.c @@ -0,0 +1,94 @@ +/* + * $Source$ + * $Header$ + */ + +#ifndef lint +static char *rcsid_xfer_002_c = "$Header$"; +#endif lint + +#include +#include "gdb.h" +#include +#include +#include +#include "smsu_int.h" +#include "kludge.h" +#include + +extern CONNECTION conn; +char buf[BUFSIZ]; + +extern int code, errno; + +extern int have_authorization, have_file, done; + +/* + * + * syntax: + * >>> (STRING)"xfer_002" filesize checksum pathname + * <<< (int)0 + * >>> (STRING)data + * <<< (int)code + * >>> (STRING)data + * <<< (int)code + * ... + * >>> (STRING)data (last data block) + * <<< (int)code (from read, write, checksum verify) + * + * function: + * perform initial preparations and receive file as + * a single string, storing it into .sms_update. + * + * still to be done: file locking; perform transfers in pieces instead + * of all at once; use checksums + */ + +int +xfer_002(str) + char *str; +{ + int file_size; + int checksum; + char *pathname; + + str += 8; + while (*str == ' ') + str++; + if (!*str) { + failure: + reject_call(SMSU_BAD_ARGS); + return; + } + file_size = atoi(str); + while (isdigit(*str)) + str++; + while (*str == ' ') + str++; + checksum = atoi(str); + while (isdigit(*str)) + str++; + while (*str == ' ') + str++; + if (*str != '/') + goto failure; + pathname = str; + if (!have_authorization) { + reject_call(SMSU_NO_AUTH); + return; + } + if (done) /* re-initialize data */ + initialize(); + code = send_ok(); + if (code) + lose("sending ok for file xfer (2)"); + code = get_file(pathname, file_size, checksum); + if (!code) { + char buf[BUFSIZ]; + have_file = 1; + strcpy(buf, "transferred file "); + strcat(buf, pathname); + sms_log_info(buf); + } + return; +} -- 2.45.2