:li

!!!makefile

  1	SHELL=/bin/sh 
 
  2	SERVEROBJS =  rupdate_svc.o \
  3	              rupdate_sub.o \
  4	              rupdate_xdr.o
 
  5	CLIENTOBJS = rupdate.o \
  6	             rupdate_clnt.o \
  7	             rupdate_xdr.o
 
  8	# -lsun wird nur fuer IRIX benoetigt
  9	#SYS_LIBS = -lsun
 10	LIBS = $(SYS_LIBS) -lc
 
 
 11	all: rupdate rupdate_svc
 
 12	rupdate: $(CLIENTOBJS)
 13	   $(CC) $(LDFLAGS) -o $@ $(CLIENTOBJS) $(LIBS)
 
 14	rupdate_svc: $(SERVEROBJS)
 15	   $(CC) $(LDFLAGS) -o $@ $(SERVEROBJS) $(LIBS)
 
 16	rupdate_sub.o: rupdate_sub.c 
 17	   $(CC) $(CFLAGS) -c $< -D$(OS) 
 
 18	rupdate.c:   rupdate.h 
 
 19	rupdate_sub.c:   rupdate.h 
 
 20	rupdate.h: rupdate.x 
 21	   rpcgen $?
 22	   (rm -f rupdate_svc.c)
 
 23	rupdate_svc.c: rupdate.x
 24	   rpcgen -s udp -o $@ rupdate.x
 
 25	clean::
 26	   rm -f *.o
 27	   rm -f rupdate_svc.c rupdate_clnt.c rupdate._xdr.c rupdate.h

:li

rupdate.c

  1	/****************************************************************************
  2	 * rupdate: Rdist Abgleich initiiert vom Client
  3	 ***************************************************************************/
  4	#include <stdio.h>
  5	#include <unistd.h>
  6	#include <ctype.h>
  7	#ifdef sun     /* SunOS < 4.0.3 */
  8	#include <sys/time.h>
  9	#else
 10	#include <time.h>
 11	#endif
 12	#include <sys/errno.h>
 13	#include <sys/stat.h>
 14	#include <strings.h>
 15	#include <rpc/rpc.h>
 16	#include <rpc/pmap_prot.h>
 17	#include <netdb.h>
 18	#include <sys/socket.h>
 19	#include "rupdate.h"
 
 20	extern int errno;
 21	extern char *getenv();
 22	static struct timeval timeout = { 5, 0 };
 23	static struct timeval long_timeout = { 300, 0 };
 
 24	main(argc, argv)
 25	     int argc;
 26	     char *argv[];
 27	{
 28	     CLIENT *cl;
 29	     int sock, portno, *pret;
 30	     char *cp, *server, lfn[128], updatetime[9];
 31	     struct stat sp;
 32	     struct tm *tp;
 33	     struct sockaddr_in server_addr;
 34	     struct hostent *hp = NULL;
 35	     cl_arch myarch;
 36	     appl_version *serv_version;
 
 37	     /* 
 38	      * Version ermitteln:
 39	      */
 40	     if ((cp = getenv("RUPDATEPATH")) != NULL) {
 41	          sprintf(lfn,"%s/%s",cp,argv[0]);
 42	          if (!stat(lfn, &sp)) {
 
 43	               /*
 44	                *  Aenderungsdatum dieses Programms holen:
 45	                */
 46	               tp = localtime(&sp.st_mtime);
 47	               sprintf(updatetime, "%.4d%.2d%.2d",
 48	                     1900 + tp->tm_year, 1 + tp->tm_mon, 
 49	                     tp->tm_mday);
 50	          } else {
 51	               fprintf(stderr,
 52	               "Environment Variable RUPDATEPATH nicht definiert!\n");
 53	               exit(-1);
 54	          }
 55	     }
 56	     /* 
 57	      * Struktur belegen:
 58	      */
 59	     myarch.appl_version = updatetime;
 60	     myarch.appl_name =    "cad";
 61	     myarch.cl_architecture = "sun4";
 62	     myarch.cl_osrelease = "4.1";
 63	     if ((server = getenv("DISTHOST")) == NULL) {
 64	          server = "disthost";
 65	     }
 
 66	     /* 
 67	      * Internet-Adresse bestimmen:
 68	      */
 69	     if ((hp = gethostbyname (server)) == NULL) {
 70	          fprintf(stderr,"Rupdate: Server nicht bekannt!\n");
 71	          exit(1);
 72	     }
 73	     server_addr.sin_family = AF_INET;
 74	     server_addr.sin_port = 0;
 75	     bcopy (hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length);
 
 76	     /* 
 77	      * Initialisierung des Servers pruefen:
 78	     .* pmap_getport holt die Portnummer des Servers vom Portmapper
 79	      */
 80	     portno = pmap_getport(&server_addr, RUPDATE, RUPDATEVERS,IPPROTO_UDP);
 81	     if (portno == 0) {
 82	          fprintf(stderr,"Update-Service nicht verfuegbar!\n");
 83	          exit(0);
 84	     }
 85	     /* 
 86	      * Verbindung aufbauen:
 87	      */
 88	     server_addr.sin_family = AF_INET;
 89	     server_addr.sin_port = htons(portno); 
 90	     bcopy (hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length);
 91	     sock = RPC_ANYSOCK;
 92	     cl = clntudp_create(&server_addr, RUPDATE, RUPDATEVERS, timeout, &sock);
 93	     if (cl == NULL) {
 94	          goto end_label;
 95	     }
 96	     
 97	     /*
 98	      * Version vergleichen:
 99	      */
100	     serv_version = checkversions_1(&myarch, cl);
101	     if (serv_version == NULL) {
102	          clnt_perror(cl, server);
103	          goto end_label;
104	     }
105	     
106	     /* 
107	      * Falls erforderlich, Rdist auf Server aktivieren:
108	      */
109	     if (serv_version->status) {
110	          /*
111	           * Timeout hochsetzen:
112	           */
113	          clnt_control(cl,CLSET_RETRY_TIMEOUT,&long_timeout);
114	          pret = update_1(serv_version, cl);
115	          if (pret == NULL) {
116	               clnt_perror(cl, server);
117	               goto end_label;
118	          }
119	          if (*pret) {
120	               printf("Update erfolgreich durchgefuehrt!\n");
121	          }
122	     }
 
123	end_label:
124	     CLNT_DESTROY(cl);
125	     (void)close(sock);
126	     exit(0);

:li

rupdate.x

  1	/*
  2	 * XDR- und RPC-Beschreibung fuer remote Update (iX Heft 5/92) 
  3	 */
 
  4	const MAXAPPLVERSION      = 9;
  5	const MAXAPPLNAME           =32;
  6	const MAXARCHNAMELEN      = 9;
  7	const MAXOSRELEASE           = 9;
 
  8	/*
  9	.* XDR-Definitionen:
 10	 * Informationen ueber die Anwendung auf Client-Seite:
 11	 */
 12	struct cl_arch {
 13	     string      appl_version<MAXAPPLVERSION>;
 14	     string      appl_name<MAXAPPLNAME>;
 15	     string      cl_architecture<MAXARCHNAMELEN>;
 16	     string      cl_osrelease<MAXOSRELEASE>;
 17	};
 
 18	/*
 19	 * Zusaetzlich mit Rueckgabestatus:
 20	 */
 
 21	struct appl_version {
 22	     cl_arch      client_arch;
 23	     int          status;
 24	};
 
 25	/*
 26	 * RPC-Programme
 27	 * =============
 28	 */
 29	program RUPDATE {
 30	     version RUPDATEVERS {
 
 31	          /*
 32	           * CHECKVERSIONS 
 33	           * Vergleicht Server- mit Client-Version
 34	           */
 35	          appl_version CHECKVERSIONS(cl_arch) = 1;
 
 36	          /*
 37	           * UPDATE
 38	           * Update vornehmen:
 39	           */
 40	          int      UPDATE(appl_version) = 2;
 
 41	     } = 1;
 42	} = 0x1fffff55;

:li

rupdate_sub.c

  1	#include <stdio.h>
  2	#include <unistd.h>
  3	#include <ctype.h>
  4	#include <sys/types.h>
  5	#include <sys/socket.h>
  6	#include <sys/stat.h>
  7	#ifdef sun      /* < SunOS 4.0.3 */
  8	#include <sys/time.h>
  9	#else
 10	#include <time.h>
 11	#endif
 12	#include <rpc/rpc.h>
 13	#include <string.h>
 14	#include "rupdate.h"
 
 15	static char applstr[36];
 16	static int appllen;
 17	extern char *getenv();
 
 18	/*
 19	 * Checkversions_1 vergleicht die beiden Versionen
 20	 */
 21	appl_version * 
 22	checkversions_1(ca, rqstp)
 23	     cl_arch *ca;
 24	     struct svc_req *rqstp;
 25	{
 26	     static appl_version mv;
 27	     static cl_arch ma;
 28	     static char nullstr[] = "\0";
 29	     struct stat sp;
 30	     struct tm *tp;
 31	     char *cp, updatetime[9];
 32	     int i;
 33	     char applsave[32], distname[128];
 34	     static char *applenv;
 35	     SVCXPRT *transp;
 
 36	     /* 
 37	      * Environment-Variablen-Name bestimmen:
 38	      */
 39	     appllen=strlen(ca->appl_name);
 40	     for (i=0,cp=ca->appl_name; i<appllen; i++,cp++) 
 41	          applstr[i] = toupper(*cp);
 42	     applstr[appllen] = '\0';
 
 43	     /*
 44	      * Setzt sich aus dem grossgeschriebenen Anwendungsnamen
 45	      * und der Endungen PATH zusammen:
 46	      */
 47	     ma.appl_version = nullstr;
 48	     if ((cp = getenv(applstr)) == NULL) {
 49	          strcpy(applsave,applstr);
 50	          strcat(applstr,"PATH");
 
 51	          /*
 52	           * Falls Cache definiert:
 53	           */
 54	          if ((cp = getenv(applstr)) != NULL) {
 55	               sprintf(distname,"%s/distfile",cp);
 56	               if (!stat(distname, &sp)) {
 
 57	                    /*
 58	                     *  Aenderungsdatum der Datei distfile holen:
 59	                     */
 60	                    tp = localtime(&sp.st_mtime);
 61	                    sprintf(updatetime, "%.4d%.2d%.2d",
 62	                               1900 + tp->tm_year, 1 + tp->tm_mon, 
 63	                               tp->tm_mday);
 64	                    applenv = (char *)malloc(strlen(applsave) + 10);
 65	                    sprintf(applenv,"%s=%s",applsave,updatetime);
 
 66	                    /*
 67	                     * Cache definieren:
 68	                     */
 69	                    putenv(applenv);
 70	                    ma.appl_version = updatetime;
 71	               }
 72	          }
 73	     } else {
 74	          ma.appl_version = cp;
 75	     }
 76	     ma.appl_name = ca->appl_name;
 77	     ma.cl_architecture = nullstr;
 78	     ma.cl_osrelease = nullstr;
 
 79	     mv.client_arch = ma;
 80	     mv.status = 0;
 
 81	     /*
 82	      * Anwendungen und Versionen vergleichen:     
 83	      */
 84	     if (!strcmp(ma.appl_name,ca->appl_name)) {
 85	          mv.status = !(strcmp(ca->appl_version,ma.appl_version) >= 0);
 86	     }
 87	     return(&mv);
 88	}
 
 89	/*
 90	 * Update_1 aktiviert Rdist:
 91	 */
 92	int *
 93	update_1(mv, rqstp)
 94	     appl_version *mv;
 95	     struct svc_req *rqstp;
 96	{
 97	     static int ret;
 98	     SVCXPRT *transp;
 99	     FILE *fp;
100	     struct sockaddr_in *client_addr;
101	     static char sysstr[160], tmpstr[60];
102	     char *cp;
103	     int i;
 
104	     /* 
105	     .* Anwendungs-Pfad bestimmen:
106	      */
107	     appllen = strlen(mv->client_arch.appl_name);
108	     for (i=0,cp=mv->client_arch.appl_name; i<appllen; i++,cp++)
109	          applstr[i] = toupper(*cp);
110	     applstr[appllen] = '\0';
 
111	     strcat(applstr,"PATH");
112	     if ((cp = getenv(applstr)) != NULL) {
 
113	          /* 
114	           * Client-Adresse bestimmen:
115	           */
116	          transp = rqstp->rq_xprt;
117	          client_addr = svc_getcaller (transp);
 
118	          /*
119	           * Rdist-Aufruf vorbereiten:
120	           */
121	          sprintf(tmpstr,"/tmp/rdist_%d",getpid());
122	          fp = fopen(tmpstr,"w");
123	          fclose(fp);
124	          sprintf(sysstr, 
125	               "cd %s;rdist -f %s/distfile -d HOST='%s' -d TMPFILE=%s",
126	                cp, cp, inet_ntoa(client_addr->sin_addr), tmpstr);
 
127	#ifdef TEST
128	          fprintf(stderr,"system: >%s<\n",sysstr);
129	#endif
130	          ret = 0;
131	          ret = system(sysstr);
132	     } else {
133	          fprintf(stderr,"Environment-Variable %s nicht gesetzt!\n",applstr);
134	          ret = 0;
135	     }
136	     return(&ret);




