/* $NetBSD: supmsg.c,v 1.18 2011/08/31 16:25:00 plunky Exp $ */ /* * Copyright (c) 1992 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ /* ********************************************************************** * HISTORY * * 7-July-93 Nate Williams at Montana State University * Modified SUP to use gzip based compression when sending files * across the network to save BandWidth * * Revision 2.4 92/09/09 22:05:17 mrt * Moved PFI definition under __STDC__ conditional since it * is already defined in libc.h in this case. * [92/09/01 mrt] * * Revision 2.3 92/08/11 12:08:12 mrt * Added copyright * [92/08/10 mrt] * Brad's changes: Delinted, Incorporated updated variable * argument list usage from old msgxfer.c * [92/07/24 mrt] * * Revision 2.2 89/08/23 15:02:56 gm0w * Created from separate message modules. * [89/08/14 gm0w] * ********************************************************************** */ #include #include #include #include "libc.h" #include "c.h" #include "supcdefs.h" #include "supextern.h" #define MSGSUBR #define MSGFILE #include "supmsg.h" /* * signon message */ extern int pgmver; /* program version of partner */ extern int pgmversion; /* my program version */ extern char *scmver; /* scm version of partner */ extern int fspid; /* process id of fileserver */ static int refuseone(TREE *, void *); static int listone(TREE *, void *); static int needone(TREE *, void *); static int denyone(TREE *, void *); static int writeone(TREE *, void *); int msgsignon(void) { int x; if (isserver) { x = readmsg(MSGSIGNON); if (x == SCMOK) x = readint(&protver); if (x == SCMOK) x = readint(&pgmver); if (x == SCMOK) x = readstring(&scmver); if (x == SCMOK) x = readmend(); } else { x = writemsg(MSGSIGNON); if (x == SCMOK) x = writeint(PROTOVERSION); if (x == SCMOK) x = writeint(pgmversion); if (x == SCMOK) x = writestring(scmversion); if (x == SCMOK) x = writemend(); } return (x); } int msgsignonack(void) { int x; if (isserver) { x = writemsg(MSGSIGNONACK); if (x == SCMOK) x = writeint(PROTOVERSION); if (x == SCMOK) x = writeint(pgmversion); if (x == SCMOK) x = writestring(scmversion); if (x == SCMOK) x = writeint(fspid); if (x == SCMOK) x = writemend(); } else { x = readmsg(MSGSIGNONACK); if (x == SCMOK) x = readint(&protver); if (x == SCMOK) x = readint(&pgmver); if (x == SCMOK) x = readstring(&scmver); if (x == SCMOK) x = readint(&fspid); if (x == SCMOK) x = readmend(); } return (x); } /* * setup message */ extern int xpatch; /* setup crosspatch to a new client */ extern char *xuser; /* user,group,acct for crosspatch */ extern char *collname; /* base directory */ extern char *basedir; /* base directory */ extern int basedev; /* base directory device */ extern int baseino; /* base directory inode */ extern time_t lasttime; /* time of last upgrade */ extern int listonly; /* only listing files, no data xfer */ extern int newonly; /* only send new files */ extern char *release; /* release name */ extern int setupack; /* ack return value for setup */ int msgsetup(void) { int x; if (isserver) { x = readmsg(MSGSETUP); if (x != SCMOK) return (x); if (protver >= 7) { x = readint(&xpatch); if (x != SCMOK) return (x); } else xpatch = FALSE; if (xpatch) { x = readstring(&xuser); if (x != SCMOK) return (x); return (readmend()); } x = readstring(&collname); if (x == SCMOK) x = readint((void *) &lasttime); if (x == SCMOK) x = readstring(&basedir); if (x == SCMOK) x = readint(&basedev); if (x == SCMOK) x = readint(&baseino); if (x == SCMOK) x = readint(&listonly); if (x == SCMOK) x = readint(&newonly); if (x == SCMOK) { if (protver < 6) release = NULL; else x = readstring(&release); } if (x == SCMOK) x = readmend(); } else { x = writemsg(MSGSETUP); if (x != SCMOK) return (x); if (protver >= 7) { x = writeint(xpatch); if (x != SCMOK) return (x); } if (xpatch) { x = writestring(xuser); if (x != SCMOK) return (x); return (writemend()); } if (x == SCMOK) x = writestring(collname); if (x == SCMOK) x = writeint((int) lasttime); if (x == SCMOK) x = writestring(basedir); if (x == SCMOK) x = writeint(basedev); if (x == SCMOK) x = writeint(baseino); if (x == SCMOK) x = writeint(listonly); if (x == SCMOK) x = writeint(newonly); if (x == SCMOK && protver >= 6) x = writestring(release); if (x == SCMOK) x = writemend(); } return (x); } int msgsetupack(void) { if (isserver) return (writemint(MSGSETUPACK, setupack)); return (readmint(MSGSETUPACK, &setupack)); } /* * crypt test message */ extern char *crypttest; /* encryption test string */ int msgcrypt(void) { if (isserver) return (readmstr(MSGCRYPT, &crypttest)); return (writemstr(MSGCRYPT, crypttest)); } int msgcryptok(void) { if (isserver) return (writemnull(MSGCRYPTOK)); return (readmnull(MSGCRYPTOK)); } /* * login message */ extern char *logcrypt; /* login encryption test */ extern char *loguser; /* login username */ extern char *logpswd; /* password for login */ extern int logack; /* login ack status */ extern char *logerror; /* error from login */ int msglogin(void) { int x; if (isserver) { x = readmsg(MSGLOGIN); if (x == SCMOK) x = readstring(&logcrypt); if (x == SCMOK) x = readstring(&loguser); if (x == SCMOK) x = readstring(&logpswd); if (x == SCMOK) x = readmend(); } else { x = writemsg(MSGLOGIN); if (x == SCMOK) x = writestring(logcrypt); if (x == SCMOK) x = writestring(loguser); if (x == SCMOK) x = writestring(logpswd); if (x == SCMOK) x = writemend(); } return (x); } int msglogack(void) { int x; if (isserver) { x = writemsg(MSGLOGACK); if (x == SCMOK) x = writeint(logack); if (x == SCMOK) x = writestring(logerror); if (x == SCMOK) x = writemend(); } else { x = readmsg(MSGLOGACK); if (x == SCMOK) x = readint(&logack); if (x == SCMOK) x = readstring(&logerror); if (x == SCMOK) x = readmend(); } return (x); } /* * refuse list message */ extern TREE *refuseT; /* tree of files to refuse */ static int /*ARGSUSED*/ refuseone(TREE * t, void *v __unused) { return (writestring(t->Tname)); } int msgrefuse(void) { int x; if (isserver) { char *name; x = readmsg(MSGREFUSE); if (x == SCMOK) x = readstring(&name); while (x == SCMOK) { if (name == NULL) break; (void) Tinsert(&refuseT, name, FALSE); free(name); name = NULL; x = readstring(&name); } if (x == SCMOK) x = readmend(); } else { x = writemsg(MSGREFUSE); if (x == SCMOK) x = Tprocess(refuseT, refuseone, NULL); if (x == SCMOK) x = writestring(NULL); if (x == SCMOK) x = writemend(); } return (x); } /* * list files message */ extern TREE *listT; /* tree of files to list */ extern time_t scantime; /* time that collection was scanned */ static int /*ARGSUSED*/ listone(TREE * t, void *v __unused) { int x; x = writestring(t->Tname); if (x == SCMOK) x = writeint((int) t->Tmode); if (x == SCMOK) x = writeint((int) t->Tflags); if (x == SCMOK) x = writeint(t->Tmtime); return (x); } int msglist(void) { int x; if (isserver) { x = writemsg(MSGLIST); if (x == SCMOK) x = Tprocess(listT, listone, NULL); if (x == SCMOK) x = writestring(NULL); if (x == SCMOK) x = writeint((int) scantime); if (x == SCMOK) x = writemend(); } else { char *name; int mode, flags, mtime; TREE *t; x = readmsg(MSGLIST); if (x == SCMOK) x = readstring(&name); while (x == SCMOK) { if (name == NULL) break; x = readint(&mode); if (x == SCMOK) x = readint(&flags); if (x == SCMOK) x = readint(&mtime); if (x != SCMOK) break; t = Tinsert(&listT, name, TRUE); free(name); t->Tmode = mode; t->Tflags = flags; t->Tmtime = mtime; x = readstring(&name); } if (x == SCMOK) x = readint((void *) &scantime); if (x == SCMOK) x = readmend(); } return (x); } /* * files needed message */ extern TREE *needT; /* tree of files to need */ static int /*ARGSUSED*/ needone(TREE * t, void *v __unused) { int x; x = writestring(t->Tname); if (x == SCMOK) x = writeint((t->Tflags & FUPDATE) != 0); return (x); } int msgneed(void) { int x; if (isserver) { char *name; int update; TREE *t; x = readmsg(MSGNEED); if (x == SCMOK) x = readstring(&name); while (x == SCMOK) { if (name == NULL) break; x = readint(&update); if (x != SCMOK) break; t = Tinsert(&needT, name, TRUE); free(name); if (update) t->Tflags |= FUPDATE; x = readstring(&name); } if (x == SCMOK) x = readmend(); } else { x = writemsg(MSGNEED); if (x == SCMOK) x = Tprocess(needT, needone, NULL); if (x == SCMOK) x = writestring(NULL); if (x == SCMOK) x = writemend(); } return (x); } /* * files denied message */ extern TREE *denyT; /* tree of files to deny */ static int /*ARGSUSED*/ denyone(TREE * t, void *v __unused) { return (writestring(t->Tname)); } int msgdeny(void) { int x; if (isserver) { x = writemsg(MSGDENY); if (x == SCMOK) x = Tprocess(denyT, denyone, NULL); if (x == SCMOK) x = writestring(NULL); if (x == SCMOK) x = writemend(); } else { char *name; x = readmsg(MSGDENY); if (x == SCMOK) x = readstring(&name); while (x == SCMOK) { if (name == NULL) break; (void) Tinsert(&denyT, name, FALSE); free(name); name = NULL; x = readstring(&name); } if (x == SCMOK) x = readmend(); } return (x); } /* * send file message */ int msgsend(void) { if (isserver) return (readmnull(MSGSEND)); return (writemnull(MSGSEND)); } /* * receive file message */ extern TREE *upgradeT; /* pointer to file being upgraded */ static int /*ARGSUSED*/ writeone(TREE * t, void *v __unused) { return (writestring(t->Tname)); } int msgrecv(int (*xferfile)(TREE *, va_list), ...) { va_list args; int x; TREE *t = upgradeT; va_start(args, xferfile); if (isserver) { x = writemsg(MSGRECV); if (t == NULL) { if (x == SCMOK) x = writestring(NULL); if (x == SCMOK) x = writemend(); va_end(args); return (x); } if (x == SCMOK) x = writestring(t->Tname); if (x == SCMOK) x = writeint(t->Tmode); if (t->Tmode == 0) { if (x == SCMOK) x = writemend(); va_end(args); return (x); } if (x == SCMOK) x = writeint(t->Tflags); if (x == SCMOK) x = writestring(t->Tuser); if (x == SCMOK) x = writestring(t->Tgroup); if (x == SCMOK) x = writeint(t->Tmtime); if (x == SCMOK) x = Tprocess(t->Tlink, writeone, NULL); if (x == SCMOK) x = writestring(NULL); if (x == SCMOK) x = Tprocess(t->Texec, writeone, NULL); if (x == SCMOK) x = writestring(NULL); if (x == SCMOK) x = (*xferfile) (t, args); if (x == SCMOK) x = writemend(); } else { char *linkname, *execcmd; if (t == NULL) { va_end(args); return (SCMERR); } x = readmsg(MSGRECV); if (x == SCMOK) x = readstring(&t->Tname); if (x == SCMOK && t->Tname == NULL) { x = readmend(); if (x == SCMOK) x = (*xferfile) (NULL, args); va_end(args); return (x); } if (x == SCMOK) x = readint(&t->Tmode); if (t->Tmode == 0) { x = readmend(); if (x == SCMOK) x = (*xferfile) (t, args); va_end(args); return (x); } if (x == SCMOK) x = readint(&t->Tflags); if (x == SCMOK) x = readstring(&t->Tuser); if (x == SCMOK) x = readstring(&t->Tgroup); if (x == SCMOK) x = readint(&t->Tmtime); t->Tlink = NULL; if (x == SCMOK) x = readstring(&linkname); while (x == SCMOK) { if (linkname == NULL) break; (void) Tinsert(&t->Tlink, linkname, FALSE); free(linkname); linkname = NULL; x = readstring(&linkname); } t->Texec = NULL; if (x == SCMOK) x = readstring(&execcmd); while (x == SCMOK) { if (execcmd == NULL) break; (void) Tinsert(&t->Texec, execcmd, FALSE); free(execcmd); execcmd = NULL; x = readstring(&execcmd); } if (x == SCMOK) x = (*xferfile) (t, args); if (x == SCMOK) x = readmend(); } va_end(args); return (x); } /* * protocol done message */ extern int doneack; extern char *donereason; int msgdone(void) { int x; if (protver < 6) { printf("Error, msgdone should not have been called."); return (SCMERR); } if (isserver) { x = readmsg(MSGDONE); if (x == SCMOK) x = readint(&doneack); if (x == SCMOK) x = readstring(&donereason); if (x == SCMOK) x = readmend(); } else { x = writemsg(MSGDONE); if (x == SCMOK) x = writeint(doneack); if (x == SCMOK) x = writestring(donereason); if (x == SCMOK) x = writemend(); } return (x); } /* * go away message */ extern char *goawayreason; /* reason for goaway */ int msggoaway(void) { return (writemstr(MSGGOAWAY, goawayreason)); } /* * cross-patch protocol message */ extern int xargc; /* arg count for crosspatch */ extern char **xargv; /* arg array for crosspatch */ int msgxpatch(void) { int x; int i; if (isserver) { x = readmsg(MSGXPATCH); if (x != SCMOK) return (x); x = readint(&xargc); if (x != SCMOK) return (x); xargc += 2; xargv = (char **) calloc(sizeof(char *), (unsigned) xargc + 1); if (xargv == NULL) return (SCMERR); for (i = 2; i < xargc; i++) { x = readstring(&xargv[i]); if (x != SCMOK) return (x); } x = readmend(); } else { x = writemsg(MSGXPATCH); if (x != SCMOK) return (x); x = writeint(xargc); if (x != SCMOK) return (x); for (i = 0; i < xargc; i++) { x = writestring(xargv[i]); if (x != SCMOK) return (x); } x = writemend(); } return (x); } /* * Compression check protocol message */ extern int docompress; /* Compress file before sending? */ int msgcompress(void) { if (isserver) return (readmint(MSGCOMPRESS, &docompress)); return (writemint(MSGCOMPRESS, docompress)); }