/* * download.c - version 1 - copies a.out file to backend mach * * Author: Jim Griffioen * Dept. of Computer Sciences * Purdue University * Date: Wed Mar 2 11:08:01 1988 * * Copyright (c) 1988 Jim Griffioen */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sgtty.h> #include <signal.h> #include <sys/stat.h> #include <sys/file.h> #include <setjmp.h> #include <errno.h> #include "../h/utils.h" #include "../h/bed.h" #include "../h/bmutils.h" #include "../h/netutils.h" #include "../h/downloadd.h" extern char *getlogin(); /* get user id */ jmp_buf env; /* used to return from read time-outs */ int errno; /* error number when system err */ #ifndef TRUE #define TRUE 1 #define FALSE 0 typedef int Bool; #endif /* *--------------------------------------------------------------------------- * main (csb, rgsb) *--------------------------------------------------------------------------- */ main (csb, rgsb) int csb; char *rgsb[]; { int i; int sock; struct bm bm; int fdTcp; int len; char *sb; int remoteport; char class[16]; /* class of machine desired */ char femachine[MAXMACHINENAME]; /* front end machine to use */ char bemachine[MAXMACHINENAME]; /* back end machine to use */ char filename[256]; /* file to download */ struct genericreq *dnreq; /* download request struct */ char unspecifiedclass; /* user specified class? */ if (csb > 4) { fprintf(stderr, "usage: download [-cCLASS] [-mBACKENDMACHINE] file\n"); exit(1); } strcpy(class, DEFAULTCLASS); strcpy(femachine, ""); strcpy(bemachine, ""); unspecifiedclass = TRUE; for (i = 1; i < csb; i++) { if (strncmp(rgsb[i], "-c", 2) == 0) { strcpy(class, (char *) (rgsb[i]+2)); unspecifiedclass = FALSE; } else if (strncmp(rgsb[i], "-m", 2) == 0) { strcpy(bemachine, (char *) (rgsb[i]+2)); } else if (i != (csb-1)) { fprintf(stderr,"unexpected arguement '%s'\n", rgsb[i]); exit(1); } } if (obtainlock(class,femachine,bemachine,unspecifiedclass) != SYSOK) { if (strlen(bemachine) > 0) fprintf(stderr, "machine %s is unavailable\n", bemachine); else if (strlen(class) > 0) fprintf(stderr, "no machines in class %s available\n", class); exit(1); } printf("using front end '%s': Using backend '%s'\n", femachine, bemachine); bm.ver = CURVER; sprintf(bm.cmd, "%d", REQ_DNLD_CONNECT); dnreq = (struct genericreq *) bm.detail; sb = getlogin(); strcpy(dnreq->uid, sb); if (gethostname(dnreq->hostid, MAXMACHINENAME) != 0) { strcpy(dnreq->hostid, "dunno"); fprintf(stderr, "error getting local host name\n"); } strcpy(dnreq->bename, bemachine); sock = ConnectUdp (femachine, KNOWN_UDP_PORT); if (bmsend (sock, &bm, lbm, 0) <= 0) { fprintf(stderr,"error sending connection request\n"); exit(1); } len = bmrecv (sock, &bm, lbm, 0); if (len<=0) { fprintf(stderr, "receive error: trying to establish a connection\n"); exit(1); } if (atoi(bm.cmd) != RESP_OK) { fprintf(stderr, "recv(): bad response (%s) from daemon: '%s'\n",bm.cmd,bm.detail); exit(1); } /* get the TCP port to use */ remoteport = atoi(bm.detail); fdTcp = ConnectTcp(femachine, remoteport); if ((*(rgsb[csb-1]) == '-') || (csb == 1)) { strcpy(filename, "a.out"); } else { strcpy(filename, rgsb[csb-1]); } printf("downloading file: %s\n", filename); download(fdTcp, filename); printf("download completeted\n"); exit(0); } /* *--------------------------------------------------------------------------- * download * this routine sends the a.out file to the front end machine so that * it can store it in /tftpboot/a.out for the backend machine to boot * with *--------------------------------------------------------------------------- */ download(fdTcp, aoutfile) int fdTcp; char *aoutfile; { int fdaout; /* file descriptor of a.out file */ char buff[BIGBUFSIZE]; /* big buffer to read into and out of */ char sblen[SMALLSTR]; /* string form of length */ struct stat statbuf; /* file status structure */ long aoutsize; /* size of a.out file */ int packetnum; /* number of packets sent */ long bytessent; /* number of bytes sent */ if ((fdaout=open(aoutfile, O_RDONLY, 0400)) < 0) { fprintf(stderr, "error opening file %s\n", aoutfile); exit(1); } /* Get name of the machine you are using */ if (sockgetstr(fdTcp, buff, STIMEOUT) == NULL) { fprintf(stderr, "Error reading machine name during downloading"); exit(1); } if (fstat(fdaout,&statbuf) != 0) { fprintf(stderr, "error finding status info about %s\n", aoutfile); exit(1); } aoutsize = (long) statbuf.st_size; sprintf(sblen,"%ld", (long) aoutsize); if (write(fdTcp, sblen, strlen(sblen)+1) != (strlen(sblen)+1)) { fprintf(stderr, "error writing file len to front end machine\n"); exit(1); } bytessent = 0; packetnum = 1; while (aoutsize > sizeof(buff)) { if (read(fdaout, buff, sizeof(buff)) != sizeof(buff)) { fprintf(stderr, "error read from %s\n", aoutfile); exit(1); } if (write(fdTcp, buff, sizeof(buff)) != sizeof(buff)) { fprintf(stderr, "error writing to front end\n"); exit(1); } packetnum++; bytessent += sizeof(buff); aoutsize -= sizeof(buff); printf("Sent %ldk bytes\r", bytessent/1000); } if (read(fdaout, buff, aoutsize) != aoutsize) { fprintf(stderr, "error read from %s\n", aoutfile); exit(1); } if (write(fdTcp, buff, aoutsize) != aoutsize) { fprintf(stderr, "error writing to front end\n"); exit(1); } bytessent += aoutsize; printf("Sent %ldk bytes\n", bytessent/1000); close(fdTcp); close(fdaout); } /* *--------------------------------------------------------------------------- * sockgetstr(sock, str, timeout) - get str from tcp socket-ret NULL if error *--------------------------------------------------------------------------- */ char *sockgetstr(sock, str, timeout) int sock; /* socket descriptor handle */ char *str; int timeout; { char *sb; settimer(timeout); if (setjmp(env) == EINTR) { canceltimer(); return(NULL); } sb = str; if (recv(sock, sb, 1, 0) < 1) { canceltimer(); return(NULL); } while (*sb++ != '\0') { if (recv(sock, sb, 1, 0) <1) { canceltimer(); return(NULL); } } canceltimer(); return(str); }