home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-14 | 50.4 KB | 1,725 lines |
- Newsgroups: comp.sources.x
- From: ferguson@cs.rochester.edu (George Ferguson)
- Subject: v20i037: xarchie - An X browser interface to Archie, v2.0.6, Part09/24
- Message-ID: <1993Jun15.223304.487@sparky.imd.sterling.com>
- X-Md4-Signature: cc5378f23dad705dff4ca42e79e71845
- Sender: chris@sparky.imd.sterling.com (Chris Olson)
- Organization: Sterling Software
- Date: Tue, 15 Jun 1993 22:33:04 GMT
- Approved: chris@sparky.imd.sterling.com
-
- Submitted-by: ferguson@cs.rochester.edu (George Ferguson)
- Posting-number: Volume 20, Issue 37
- Archive-name: xarchie/part09
- Environment: X11
- Supersedes: xarchie: Volume 14, Issue 82-90
-
- Submitted-by: ferguson@cs.rochester.edu
- Archive-name: xarchie-2.0.6/part09
-
- #!/bin/sh
- # this is Part.09 (part 9 of xarchie-2.0.6)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file xarchie-2.0.6/ftp.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 9; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping xarchie-2.0.6/ftp.c'
- else
- echo 'x - continuing file xarchie-2.0.6/ftp.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'xarchie-2.0.6/ftp.c' &&
- }
- X
- /* - - - - - - - - */
- /* Functions called by ftpProcessReply(): */
- X
- static void
- ftpSendType(ftpc)
- FtpContext *ftpc;
- {
- X char cmd[16];
- X
- X DEBUG2("ftpSendType: ftpc=0x%x, type=%d\n",ftpc,ftpc->type);
- X ftpc->state = FTPS_TYPE;
- X switch (ftpc->type) {
- X case TYPE_A:
- X sprintf(cmd,"TYPE A");
- X break;
- X case TYPE_E:
- X sprintf(cmd,"TYPE E");
- X break;
- X case TYPE_I:
- X sprintf(cmd,"TYPE I");
- X break;
- X default:
- X sprintf(cmd,"TYPE L %d",(char *)ftpc->type);
- X }
- X status0(cmd);
- X ftpSendCmd(ftpc,cmd);
- X DEBUG0("ftpSendType: done\n");
- }
- X
- static void
- ftpSendNextCwd(ftpc)
- FtpContext *ftpc;
- {
- X char *slash,cmd[256];
- X
- X DEBUG2("ftpSendNextCwd: ftpc=0x%x, wd=\"%s\"\n",ftpc,ftpc->wd);
- X if (*(ftpc->wd) == '/') { /* Leading slash treated specially... */
- X ftpc->state = FTPS_CWD;
- X ftpSendCmd(ftpc,"CWD /");
- X ftpc->wd += 1;
- X } else { /* Normal case */
- X if ((slash=index(ftpc->wd,'/')) != NULL) {
- X *slash = '\0';
- X }
- X sprintf(cmd,"CWD %s",ftpc->wd);
- X status0(cmd);
- X ftpc->state = FTPS_CWD;
- X ftpSendCmd(ftpc,cmd);
- X if (slash) {
- X ftpc->wd = slash+1;
- X } else {
- X /* set wd to end of string */
- X while (*(ftpc->wd) != '\0')
- X ftpc->wd += 1;
- X }
- X }
- X DEBUG0("ftpSendNextCwd: done\n");
- }
- X
- /*
- X * Performs the PORT command. The new port is saved in f->port.
- X * Returns < 0 if some local error, otherwise 0 if we got to sending
- X * the command.
- X */
- static int
- ftpSendPort(ftpc)
- FtpContext *ftpc;
- {
- X char cmd[64];
- X struct sockaddr_in addr;
- X int addrlen;
- X
- X DEBUG1("ftpSendPort: ftpc=0x%lx\n",ftpc);
- X if ((ftpc->port=socket(AF_INET,SOCK_STREAM,0)) < 0) {
- X sysError("socket(ftpSendPort)");
- X DEBUG0("ftpSendPort: returning -1\n");
- X return(-1);
- X }
- X DEBUG1("ftpSendPort: socket() returned %d\n",ftpc->port);
- X addr = ftpc->saddr;
- X addr.sin_port = 0;
- X if (bind(ftpc->port,(struct sockaddr *)&addr,
- X sizeof(struct sockaddr_in)) < 0) {
- X sysError("bind(ftpSendPort)");
- X DEBUG1("ftpSendPort: closing port %d\n",ftpc->port);
- X close(ftpc->port);
- X DEBUG0("ftpSendPort: returning -1\n");
- X return(-1);
- X }
- X DEBUG0("ftpSendPort: bind() succeeded\n");
- X if (listen(ftpc->port,1) < 0) {
- X sysError("listen(ftpSendPort)");
- X DEBUG1("ftpSendPort: closing port %d\n",ftpc->port);
- X close(ftpc->port);
- X DEBUG0("ftpSendPort: returning -1\n");
- X return(-1);
- X }
- X DEBUG0("ftpSendPort: listen() succeeded\n");
- X addrlen = sizeof(struct sockaddr_in);
- X if (getsockname(ftpc->port,(struct sockaddr *)&addr,&addrlen) < 0) {
- X sysError("getsockname(ftpSendPort)");
- X DEBUG1("ftpSendPort: closing port %d\n",ftpc->port);
- X close(ftpc->port);
- X DEBUG0("ftpSendPort: returning -1\n");
- X return(-1);
- X }
- X DEBUG2("ftpSendPort: PORT address: %s; port: %d\n",
- X inet_ntoa(addr.sin_addr),addr.sin_port);
- X sprintf(cmd,"PORT %d,%d,%d,%d,%d,%d",
- X (int)((unsigned char *)&addr.sin_addr.s_addr)[0],
- X (int)((unsigned char *)&addr.sin_addr.s_addr)[1],
- X (int)((unsigned char *)&addr.sin_addr.s_addr)[2],
- X (int)((unsigned char *)&addr.sin_addr.s_addr)[3],
- X (int)((unsigned char *)&addr.sin_port)[0],
- X (int)((unsigned char *)&addr.sin_port)[1]);
- X status0(cmd);
- X ftpc->state = FTPS_PORT;
- X ftpSendCmd(ftpc,cmd);
- X DEBUG0("ftpSendPort: returning 0\n");
- X return(0);
- }
- X
- X
- /*
- X * After PORT is ok, send GET or PUT to open the dataconn.
- X */
- static void
- ftpSendGetPut(ftpc)
- FtpContext *ftpc;
- {
- X char cmd[MAXPATHLEN];
- X
- X DEBUG2("ftpSendGetPut: ftpc=0x%x, fcmd=%d\n",ftpc,ftpc->filecmd);
- X ftpc->state = FTPS_GETPUT;
- X switch (ftpc->filecmd) {
- X case FTP_GET:
- X sprintf(cmd,"RETR %s",ftpc->files[ftpc->this_file]);
- X break;
- X case FTP_PUT:
- X sprintf(cmd,"STOR %s",ftpc->files[ftpc->this_file]);
- X break;
- X }
- X status0(cmd);
- X ftpSendCmd(ftpc,cmd);
- X DEBUG0("ftpSendGetPut: done\n");
- }
- X
- /*
- X * After GET/PUT, accepts the connection from the PORT and closes the
- X * the PORT. Returns the dataconn fd (also in ftpc->data).
- X */
- static int
- ftpAcceptDataConn(ftpc)
- FtpContext *ftpc;
- {
- X int datacon,addrlen;
- X struct sockaddr_in addr;
- X
- X DEBUG1("ftpAcceptDataConn: fcmd %d successful\n",ftpc->filecmd);
- X addrlen = sizeof(struct sockaddr_in);
- X if ((datacon=accept(ftpc->port,(struct sockaddr *)&addr,&addrlen)) < 0) {
- X sysError("accept(ftpAcceptDataConn)");
- X DEBUG0("ftpAcceptDataConn: returning -1\n");
- X return(-1);
- X }
- X DEBUG1("ftpAcceptDataConn: closing port %d\n",ftpc->port);
- X close(ftpc->port);
- X ftpc->port = -1;
- X DEBUG1("ftpAcceptDataConn: registering dataconn %d\n",datacon);
- X ftpc->data = datacon;
- X MAKE_NONBLOCKING(ftpc->data);
- X RegisterFtpFd(ftpc,ftpc->data,O_RDONLY,ftpDataCallback);
- X DEBUG1("ftpAcceptDataConn: returning dataconn = %d\n",datacon);
- X return(datacon);
- }
- X
- /*
- X * Once the remote file is ready for transfer through the dataconn, this
- X * function sets up the local end. Returns -1 on error, otherwise 0.
- X */
- static int
- ftpSetupLocalData(ftpc)
- FtpContext *ftpc;
- {
- X char filename[MAXPATHLEN];
- X
- X DEBUG1("ftpSetupLocalData: ftpc=0x%x\n",ftpc);
- X if (ftpc->local_dir && *(ftpc->local_dir)) {
- X sprintf(filename,"%s/%s",ftpc->local_dir,ftpc->files[ftpc->this_file]);
- X } else {
- X strcpy(filename,ftpc->files[ftpc->this_file]);
- X }
- X DEBUG1("ftpSetupLocalData: opening \"%s\"\n",filename);
- X if (ftpc->filecmd == FTP_GET) {
- X ftpc->local_fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0644);
- X } else {
- X ftpc->local_fd = open(filename,O_RDONLY,0);
- X }
- X if (ftpc->local_fd < 0) {
- X sysError(filename);
- X DEBUG0("ftpSetupLocalData: returning -1\n");
- X return(-1);
- X }
- X DEBUG1("ftpSetupLocalData: got local fd = %d\n",ftpc->local_fd);
- X ftpc->num_bytes = 0;
- X DEBUG0("ftpSetupLocalData: returning 0\n");
- X return(0);
- }
- X
- /* - - - - - - - - */
- /* Data connection processing: */
- /*
- X * This function is called whenever the dataconn is ready for read/write.
- X */
- static void
- ftpDataCallback(ftpc)
- FtpContext *ftpc;
- {
- X DEBUG2("ftpDataCallback: ftpc=0x%x, fcmd=%d\n",ftpc,ftpc->filecmd);
- X switch (ftpc->filecmd) {
- X case FTP_GET:
- X ftpReadData(ftpc);
- X break;
- X case FTP_PUT:
- X ftpWriteData(ftpc);
- X break;
- X default:
- X fprintf(stderr,"ftpDataCallback: unknown cmd: %d\n",ftpc->filecmd);
- X abort();
- X }
- X DEBUG0("ftpDataCallback: done\n");
- }
- X
- /*
- X * This function is called to read from the dataconn and write to the
- X * local_fd. On EOF, it sets the state field to FTPS_EOF and calls
- X * ftpInitReply() to continue the session. On error, it calls
- X * ftpSendAbort() and then ftpInitReply(). Otherwise the transfer
- X * is ongoing, so it doesn't do anything.
- X */
- static void
- ftpReadData(ftpc)
- FtpContext *ftpc;
- {
- X char buf[BUFSIZ*4],*s,*t,msg[256];
- X int nread,i;
- X
- X DEBUG0("ftpReadData: reading\n");
- X /* Read one chunk of stuff and write it locally (don't loop or
- X * X won't get a chance to dispatch).
- X */
- X nread = read(ftpc->data,buf,sizeof(buf));
- X if (nread > 0) {
- X /* Strip CR's if necessary */
- X if (ftpc->type == TYPE_A && ftpc->stripcr) {
- X DEBUG0("ftpReadData: stripping <CR>\n");
- X for (s=t=buf,i=nread; i--; ++s) {
- X if (*s != '\r')
- X *t++ = *s;
- X }
- X }
- X /* Write locally */
- X if (write(ftpc->local_fd,buf,nread) != nread) {
- X /* Error when writing */
- X sysError("write(ftpReadData)");
- X ftpCleanupDataConn(ftpc);
- X ftpSendAbort(ftpc);
- X ftpInitReply(ftpc);
- X } else {
- X /* write was ok */
- X ftpc->num_bytes += nread;
- X DEBUG1("ftpReadData: total = %d\n",ftpc->num_bytes);
- X if (ftpc->this_size != 0) {
- X sprintf(msg,"%.200s: %d/%d",ftpc->files[ftpc->this_file],
- X (char *)(ftpc->num_bytes),(char *)(ftpc->this_size));
- X } else {
- X sprintf(msg,"%.200s: %d bytes",ftpc->files[ftpc->this_file],
- X (char *)(ftpc->num_bytes));
- X }
- X status0(msg);
- X }
- X } else if (nread < 0 && errno == ITWOULDBLOCK) {
- X /* Nothing more ready now, keep waiting */
- X DEBUG0("ftpReadData: dataconn would block\n");
- X } else if (nread < 0) {
- X /* Error when reading */
- X sysError("read(ftpReadData)");
- X DEBUG0("ftpReadData: error reading dataconn\n");
- X ftpCleanupDataConn(ftpc);
- X ftpSendAbort(ftpc);
- X ftpInitReply(ftpc);
- X } else if (nread == 0) {
- X /* We got EOF on remote file. */
- X DEBUG0("ftpReadData: EOF on dataconn\n");
- X ftpCleanupDataConn(ftpc);
- X if (ftpc->done1 != NULL)
- X (*(ftpc->done1))(ftpc);
- X ftpc->state = FTPS_EOF;
- X ftpInitReply(ftpc);
- X }
- }
- X
- /*ARGSUSED*/
- static void
- ftpWriteData(ftpc)
- FtpContext *ftpc;
- {
- X /*EMPTY*/
- }
- X
- static void
- ftpCleanupDataConn(ftpc)
- FtpContext *ftpc;
- {
- X /* Note: We may have already unregistered, eg, in ftpAbort(). */
- X if (ftpc->state != FTPS_ABORT2)
- X UnregisterFtpFd(ftpc,ftpc->data);
- X if (ftpc->data != -1) {
- X DEBUG1("ftpCleanupDataConn: closing data %d\n",ftpc->data);
- X close(ftpc->data);
- X ftpc->data = -1;
- X }
- X if (ftpc->local_fd != -1) {
- X DEBUG1("ftpCleanupDataConn: closing local_fd %d\n",ftpc->local_fd);
- X close(ftpc->local_fd);
- X ftpc->local_fd = -1;
- X }
- }
- X
- /* - - - - - - - - */
- /* Sending commands to the server: */
- /*
- X * Adds CRLF and calls to ftpStartSendingCmd().
- X */
- static void
- ftpSendCmd(ftpc,cmd)
- FtpContext *ftpc;
- char *cmd;
- {
- X char buf[MAXPATHLEN];
- X
- X if (ftpc->trace) {
- X (*(ftpc->trace))(ftpc,1,cmd);
- X }
- X sprintf(buf,"%s\r\n",cmd);
- X ftpStartSendingCmd(ftpc,buf);
- }
- X
- /*
- X * Handles abort processing by sending the Telnet abort sequence in the
- X * out-of-band stream of the ctrl conn and the ABOR command on the regular
- X * stream.
- X */
- static void
- ftpSendAbort(ftpc)
- FtpContext *ftpc;
- {
- X char buf[8];
- X int sent;
- X
- X DEBUG1("ftpSendAbort: ftpc=0x%lx\n",ftpc);
- X DEBUG0("ftpSendAbort: sending <IAC><IP><IAC> in OOB\n");
- X sprintf(buf,"%c%c%c",IAC,IP,IAC);
- X do {
- X sent = send(ftpc->ctrl,buf,3,MSG_OOB);
- X } while (sent == -1 && errno == EINTR);
- X if (sent != 3) {
- X sysError("send(ftpSendAbort)");
- X ftpDone(ftpc);
- X }
- X DEBUG0("ftpSendAbort: sending <DM>ABOR\n");
- X sprintf(buf,"%cABOR\r\n",DM);
- X do {
- X sent = write(ftpc->ctrl,buf,strlen(buf));
- X } while (sent == -1 && errno == EINTR);
- X if (sent != strlen(buf)) {
- X sysError("write(ftpSendAbort)");
- X ftpDone(ftpc);
- X }
- X ftpc->state = FTPS_ABORT;
- X ftpInitReply(ftpc);
- X status0("Aborting...");
- X DEBUG0("ftpSendAbort: done\n");
- }
- X
- /*
- X * This function starts sending CMD to the server over the control
- X * connection. The writes can block, hence this has to be able to finish
- X * later, but since they usually don't block, we don't set up to retry
- X * unless we have to. If the command is completely sent, then we call
- X * ftpInitReply() otherwise we setup to finish by registering the ctrlconn
- X * for writing via callback ftpWriteCallback().
- X */
- static void
- ftpStartSendingCmd(ftpc,cmd)
- FtpContext *ftpc;
- char *cmd;
- {
- X int cmdlen,numsent;
- X
- X DEBUG2("ftpStartSendingCmd: ftpc=0x%x: \"%s\"\n",ftpc,cmd);
- X cmdlen = strlen(cmd);
- X numsent = write(ftpc->ctrl,cmd,cmdlen);
- X if (numsent < 0 && errno != ITWOULDBLOCK) {
- X sysError("write(ftpStartSendingCmd)");
- X DEBUG0("ftpStartSendingCmd: error writing ctrlconn\n");
- X ftpDone(ftpc);
- X return;
- X } else if (numsent == cmdlen) {
- X DEBUG0("ftpStartSendingCmd: write all done\n");
- X ftpInitReply(ftpc);
- X return;
- X } else if (errno == ITWOULDBLOCK) {
- X /* Otherwise the write would block, nothing sent */
- X DEBUG0("ftpStartSendingCmd: write would block\n");
- X numsent = 0;
- X } else {
- X /* Incomplete write */
- X DEBUG1("ftpStartSendingCmd: write incomplete (%d bytes sent)\n",numsent);
- X }
- X /* Either way, if we get here there's something left do */
- X cmd += numsent;
- X if ((ftpc->cmd=malloc(strlen(cmd)+1)) == NULL) {
- X sysError("malloc(ftpStartSendingCmd)");
- X ftpDone(ftpc);
- X return;
- X }
- X strcpy(ftpc->cmd,cmd);
- X DEBUG1("ftpStartSendingCmd: pending: \"%s\"\n",ftpc->cmd);
- X RegisterFtpFd(ftpc,ftpc->ctrl,O_WRONLY,ftpWriteCallback);
- }
- X
- /*
- X * This function is called when the ctrlconn is ready for writing.
- X * It sends as much as possible. If that completes the cmd, then it
- X * calls ftpInitReply(), otherwise updates the cmd with what's left
- X * and returns.
- X */
- static void
- ftpWriteCallback(ftpc)
- FtpContext *ftpc;
- {
- X char *cmd;
- X int cmdlen,numsent;
- X
- X cmd = ftpc->cmd;
- X DEBUG2("ftpWriteCallback: ftpc=0x%x: \"%s\"\n",ftpc,cmd);
- X cmdlen = strlen(ftpc->cmd);
- X numsent = write(ftpc->ctrl,cmd,cmdlen);
- X if (numsent < 0 && errno != ITWOULDBLOCK) {
- X sysError("write(ftpWriteCallback)");
- X DEBUG0("ftpWriteCallback: error writing ctrlconn\n");
- X ftpDone(ftpc);
- X return;
- X } else if (numsent == cmdlen) {
- X DEBUG0("ftpWriteCallback: write all done\n");
- X UnregisterFtpFd(ftpc,ftpc->ctrl);
- X free(ftpc->cmd);
- X ftpInitReply(ftpc);
- X return;
- X } else if (errno == ITWOULDBLOCK) {
- X /* Otherwise the write would block, nothing sent */
- X DEBUG0("ftpWriteCallback: write would block\n");
- X numsent = 0;
- X } else {
- X /* Incomplete write */
- X DEBUG1("ftpWriteCallback: write incomplete (%d bytes sent)\n",numsent);
- X }
- X /* Either way, if we get here there's something left do */
- X cmd += numsent;
- X free(ftpc->cmd);
- X if ((ftpc->cmd=malloc(strlen(cmd)+1)) == NULL) {
- X sysError("malloc(ftpWriteCallback)");
- X ftpDone(ftpc);
- X return;
- X }
- X strcpy(ftpc->cmd,cmd);
- X DEBUG1("ftpWriteCallback: pending: \"%s\"\n",ftpc->cmd);
- }
- X
- /* - - - - - - - - */
- /* Printing utilities for debugging */
- X
- #ifdef DEBUG
- char *
- ftpstatestr(state)
- int state;
- {
- X char buf[8];
- X
- X switch (state) {
- X /* state */
- X case FTPS_OPEN: return("OPEN");
- X case FTPS_CONNECT: return("CONNECT");
- X case FTPS_CONNECTED: return("CONNECTED");
- X case FTPS_USER: return("USER");
- X case FTPS_PASS: return("PASS");
- X case FTPS_CWD: return("CWD");
- X case FTPS_TYPE: return("TYPE");
- X case FTPS_READY: return("READY");
- X case FTPS_PORT: return("PORT");
- X case FTPS_GETPUT: return("GETPUT");
- X case FTPS_TRANSFER: return("TRANSFER");
- X case FTPS_EOF: return("EOF");
- X case FTPS_QUIT: return("QUIT");
- X case FTPS_ABORT: return("ABORT");
- X case FTPS_ABORT2: return("ABORT2");
- X /* reply_state */
- X case FTPS_REPLY_CODE: return("CODE");
- X case FTPS_REPLY_CONT: return("CONT");
- X case FTPS_REPLY_LAST: return("LAST");
- X case FTPS_REPLY_MORE: return("MORE");
- X case FTPS_REPLY_CHCK: return("CHCK");
- X case FTPS_REPLY_IAC1: return("IAC1");
- X case FTPS_REPLY_IAC2: return("IAC2");
- X case FTPS_REPLY_IAC3: return("IAC3");
- X default: sprintf(buf,"?%d?",state);
- X return(buf);
- X }
- }
- #endif /* DEBUG */
- X
- X
- /* - - - - - - - - */
- /* Sample code for standalone client */
- X
- #ifdef STANDALONE
- X
- /* This is from Brendan... */
- #include <sys/types.h> /* this may/will define FD_SET etc */
- #ifdef u3b2
- # include <sys/inet.h> /* THIS does FD_SET etc on AT&T 3b2s. */
- #endif
- X
- fd_set readfds,writefds;
- typedef void (*PF)();
- PF funcs[FD_SETSIZE];
- FtpContext *contexts[FD_SETSIZE];
- X
- void
- RegisterFtpFd(ftpc,fd,flags,func)
- FtpContext *ftpc;
- int fd,flags;
- void (*func)();
- {
- X switch (flags) {
- X case O_RDONLY:
- X fprintf(stderr,"REGISTER fd %d, flags=RO\n",fd);
- X FD_SET(fd,&readfds);
- X FD_CLR(fd,&writefds);
- X break;
- X case O_WRONLY:
- X fprintf(stderr,"REGISTER fd %d, flags=WO\n",fd);
- X FD_CLR(fd,&readfds);
- X FD_SET(fd,&writefds);
- X break;
- X case O_RDWR:
- X fprintf(stderr,"REGISTER fd %d, flags=RW\n",fd);
- X FD_SET(fd,&readfds);
- X FD_SET(fd,&writefds);
- X break;
- X }
- X funcs[fd] = func;
- X contexts[fd] = ftpc;
- }
- X
- /*ARGSUSED*/
- void
- UnregisterFtpFd(ftpc,fd)
- FtpContext *ftpc;
- int fd;
- {
- X fprintf(stderr,"UNREGISTER fd %d\n",fd);
- X FD_CLR(fd,&readfds);
- X FD_CLR(fd,&writefds);
- X funcs[fd] = NULL;
- X contexts[fd] = NULL;
- }
- X
- void
- done(ftpc)
- FtpContext *ftpc;
- {
- X fprintf(stderr,"DONE!\n");
- X ftpFreeContext(ftpc);
- X exit(0);
- }
- X
- void
- done1(ftpc)
- FtpContext *ftpc;
- {
- X fprintf(stderr,"DONE1: \"%s\"\n",ftpc->files[ftpc->this_file]);
- }
- X
- /*ARGSUSED*/
- void
- trace(ftpc,who,text)
- FtpContext *ftpc;
- int who; /* 0 => recvd, non-0 => sent */
- char *text;
- {
- X fprintf(stderr,"TRACE: ");
- X if (who) /* non-zero == us */
- X fprintf(stderr,"ftp> ");
- X fprintf(stderr,"%s",text);
- X if (*(text+strlen(text)-1) != '\n')
- X fprintf(stderr,"\n",text);
- }
- X
- char *program;
- X
- main(argc,argv)
- int argc;
- char *argv[];
- {
- X char *host,*cwd;
- X FtpContext *ftpc;
- X fd_set rfds,wfds;
- X int fd;
- X
- X if (argc < 3) {
- X fprintf(stderr,"usage: %s host cwd files...\n",argv[0]);
- X exit(1);
- X }
- X argc -= 1;
- X program = *argv++;
- X argc -= 1;
- X host = *argv++;
- X argc -= 1;
- X cwd = *argv++;
- X FD_ZERO(&rfds);
- X FD_ZERO(&wfds);
- X ftpc = ftpNewContext(host,"anonymous","ferguson@cs.rochester.edu",
- X cwd,TYPE_I,1,1,FTP_GET,argv,argc,trace,done1,done);
- X printf("Calling ftpStart...\n");
- X ftpStart(ftpc);
- X while (1) {
- X bcopy((char *)&readfds,(char *)&rfds,sizeof(fd_set));
- X bcopy((char *)&writefds,(char *)&wfds,sizeof(fd_set));
- X fprintf(stderr,"select(): R=");
- X for (fd=0; fd < FD_SETSIZE; fd++) {
- X if (FD_ISSET(fd,&rfds))
- X fprintf(stderr,"%d,",fd);
- X }
- X fprintf(stderr," W=");
- X for (fd=0; fd < FD_SETSIZE; fd++) {
- X if (FD_ISSET(fd,&wfds))
- X fprintf(stderr,"%d,",fd);
- X }
- X fprintf(stderr,"\n");
- X if (select(FD_SETSIZE,&rfds,&wfds,NULL,NULL) < 0) {
- X perror(program);
- X exit(1);
- X }
- X for (fd=0; fd < FD_SETSIZE; fd++) {
- X if (FD_ISSET(fd,&rfds) || FD_ISSET(fd,&wfds)) {
- X fprintf(stderr,"selected fd %d...\n",fd);
- X (*(funcs[fd]))(contexts[fd]);
- X }
- X }
- X }
- }
- X
- void
- sysError(s)
- char *s;
- {
- X extern int errno;
- X extern char *sys_errlist[];
- X fprintf(stderr,"SYSERR: %s: %s\n",s,sys_errlist[errno]);
- }
- X
- void
- alert0(s)
- char *s;
- {
- X fprintf(stderr,"ALERT: %s\n",s);
- }
- X
- void
- status0(s)
- char *s;
- {
- X fprintf(stderr,"STATUS: %s\n",s);
- }
- X
- int
- ftpPrompt(ftpc)
- FtpContext *ftpc;
- {
- X char c;
- X
- X fprintf(stderr,"CONFIRM: %s %s [ynaq]",
- X ftpfilecmdstr(ftpc->filecmd),ftpc->files[ftpc->this_file]);
- X c = getchar();
- X if (c != '\n')
- X (void)getchar();
- X switch (c) {
- X case 'y': return(1);
- X case 'n': return(0);
- X case 'a': ftpc->prompt = 0;
- X return(1);
- X case 'q': ftpc->this_file = ftpc->num_files;
- X return(0);
- X default: return(1);
- X }
- }
- #endif /*STANDALONE*/
- SHAR_EOF
- echo 'File xarchie-2.0.6/ftp.c is complete' &&
- chmod 0644 xarchie-2.0.6/ftp.c ||
- echo 'restore of xarchie-2.0.6/ftp.c failed'
- Wc_c="`wc -c < 'xarchie-2.0.6/ftp.c'`"
- test 46597 -eq "$Wc_c" ||
- echo 'xarchie-2.0.6/ftp.c: original size 46597, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= xarchie-2.0.6/ftp.h ==============
- if test -f 'xarchie-2.0.6/ftp.h' -a X"$1" != X"-c"; then
- echo 'x - skipping xarchie-2.0.6/ftp.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting xarchie-2.0.6/ftp.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/ftp.h' &&
- /*
- X * ftp.h : Definitions for the asynchronous FTP client
- X *
- X * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
- X * 28 Apr 1993: Changed constant from _FTP_H to _XA_FTP_H.
- X */
- X
- #ifndef _XA_FTP_H
- #define _XA_FTP_H_
- X
- #include <sys/types.h>
- #include <netinet/in.h>
- X
- #if NeedFunctionPrototypes
- struct _FtpContext;
- #endif
- X
- typedef void (*FtpCallbackProc)(
- #if NeedFunctionPrototypes
- X struct _FtpContext* ftpc
- #endif
- );
- X
- typedef void (*FtpTraceProc)(
- #if NeedFunctionPrototypes
- X struct _FtpContext* ftpc,
- X int who, /* 0 => recvd, non-0 => sent */
- X char *text
- #endif
- );
- X
- typedef struct _FtpContext {
- X /* Connection parameters */
- X char *hostname; /* hostname to contact */
- X unsigned short servport; /* port of ftp service */
- X char **h_addr_list; /* list of host addresses to try */
- X char **this_addr; /* which address are we trying */
- X struct sockaddr_in saddr; /* address of the control connection */
- X /* Connection state */
- X int state; /* state of FTP process */
- X int iostate; /* connecting, reading, writing, or ready */
- X int reply_state; /* sub-state during reply parsing */
- X int saved_state; /* saved sub-state during IAC parsing */
- X char *cmd; /* pending part of cmd to send */
- X /* Control connection */
- X int ctrl; /* file descriptor of control connection */
- X int retcode; /* code of last reply */
- X int tmpcode; /* scratchpad for continuation lines */
- X char reply[BUFSIZ<<4]; /* text of last reply */
- X int reply_len; /* length of reply (so far) */
- X /* User transfer params */
- X char *user; /* usually anonymous */
- X char *pass; /* usually user@host.dom */
- X char *cwd; /* remote directory */
- X char *wd; /* the part of cwd remaining to do */
- X char *local_dir; /* directory for local files */
- X int type; /* current transfer mode */
- X int stripcr; /* 1 if want to remove CR from ASCII files */
- X int prompt; /* 1 to prompt during transfers */
- X int filecmd; /* FTP_GET or FTP_PUT */
- X char **files; /* array of files to GET or PUT */
- X int num_files; /* how many files */
- X int this_file; /* which file are we working on */
- X int this_size; /* how big is it (if we know) */
- X FtpTraceProc trace; /* called to trace transactions */
- X FtpCallbackProc done; /* called when connection finished */
- X FtpCallbackProc done1; /* called when each file transfer finished */
- X /* Data connection */
- X int port; /* the socket on which we will acccept(2) */
- X int data; /* a data connection established */
- X int local_fd; /* fd for local copy of file (read or write) */
- X int num_bytes; /* bytes transferred this file */
- } FtpContext;
- X
- extern FtpContext *ftpNewContext(
- #if NeedFunctionPrototypes
- X char *hostname, char *user, char *pass, char *cwd, char *local_dir,
- X int type, int stripcr, int prompt,
- X int filecmd, char **files, int num_files,
- X FtpTraceProc trace, FtpCallbackProc done1, FtpCallbackProc done
- #endif
- );
- X
- extern void ftpStart(
- #if NeedFunctionPrototypes
- X FtpContext *ftpc
- #endif
- );
- X
- extern void ftpAbort(
- #if NeedFunctionPrototypes
- X FtpContext *ftpc
- #endif
- );
- X
- extern void ftpFreeContext(
- #if NeedFunctionPrototypes
- X FtpContext *ftpc
- #endif
- );
- X
- /*
- X * Filecmd codes
- X */
- #define FTP_GET 1
- #define FTP_PUT 2
- X
- /* Values for state field of FtpContext */
- #define FTPS_OPEN 10
- #define FTPS_CONNECT 11
- #define FTPS_CONNECTED 12
- #define FTPS_USER 13
- #define FTPS_PASS 14
- #define FTPS_CWD 15
- #define FTPS_TYPE 16
- #define FTPS_READY 17
- #define FTPS_PORT 18
- #define FTPS_GETPUT 19
- #define FTPS_TRANSFER 20
- #define FTPS_EOF 21
- #define FTPS_QUIT 22
- #define FTPS_ABORT 23
- #define FTPS_ABORT2 24
- X
- /* Values for reply_state field of FtpContext */
- #define FTPS_REPLY_CODE 101
- #define FTPS_REPLY_CONT 102
- #define FTPS_REPLY_LAST 103
- #define FTPS_REPLY_MORE 104
- #define FTPS_REPLY_CHCK 105
- #define FTPS_REPLY_IAC1 106
- #define FTPS_REPLY_IAC2 107
- #define FTPS_REPLY_IAC3 108
- X
- /*
- X * Telnet codes
- X */
- #ifndef NO_ARPA_H
- # include <arpa/ftp.h>
- # include <arpa/telnet.h>
- #else
- X /* <arpa/ftp.h>
- # define TYPE_A 1 /* ASCII */
- # define TYPE_E 2 /* EBCDIC */
- # define TYPE_I 3 /* image */
- # define TYPE_L 4 /* local byte size */
- X /* <arpa/telnet.h> */
- # define IAC 255 /* interpret as command: */
- # define DONT 254 /* you are not to use option */
- # define DO 253 /* please, you use option */
- # define WONT 252 /* I won't use option */
- # define WILL 251 /* I will use option */
- # define IP 244 /* interrupt process--permanently */
- # define DM 242 /* data mark--for connect. cleaning */
- #endif /* !NO_ARPA_H */
- X
- /*
- X * FTP reply codes, per RFC 959
- X */
- X
- /* First digit */
- #define FTP_REPLY_TYPE(X) (X/100)
- #define FTP_REPLY_PRELIM(X) (FTP_REPLY_TYPE(X) == 1) /* +ve preliminary */
- #define FTP_REPLY_COMPLETE(X) (FTP_REPLY_TYPE(X) == 2) /* +ve complete */
- #define FTP_REPLY_CONTINUE(X) (FTP_REPLY_TYPE(X) == 3) /* +ve intermediate */
- #define FTP_REPLY_TRANSIENT(X) (FTP_REPLY_TYPE(X) == 4) /* -ve transient */
- #define FTP_REPLY_ERROR(X) (FTP_REPLY_TYPE(X) == 5) /* -ve permanent */
- #define FTP_REPLY_OK(X) (X < 400)
- #define FTP_REPLY_ERR(X) (X >= 400)
- X
- /* Second digit */
- #define FTP_REPLY_FUNCTION(X) ((X%100)/10)
- #define FTP_REPLY_SYNTAX(X) (FTP_REPLY_FUNCTION(X) == 0) /* syntax */
- #define FTP_REPLY_INFO(X) (FTP_REPLY_FUNCTION(X) == 1) /* information */
- #define FTP_REPLY_CONN(X) (FTP_REPLY_FUNCTION(X) == 2) /* connections */
- #define FTP_REPLY_AUTH(X) (FTP_REPLY_FUNCTION(X) == 3) /*authentication*/
- #define FTP_REPLY_UNSPEC(X) (FTP_REPLY_FUNCTION(X) == 4) /* unspecified */
- #define FTP_REPLY_FILE(X) (FTP_REPLY_FUNCTION(X) == 5) /* file system */
- X
- /* Third digit */
- #define FTP_REPLY_SPECIFIC(X) (X%10)
- X
- /* Reply Codes by Function Groups (comment text from RFC959) */
- #define FTP_COMMAND_OK 200 /* Command okay. */
- #define FTP_SYNTAX_ERROR 500 /* Syntax error, command unrecognized.
- X This may include errors such as
- X command line too long. */
- #define FTP_PARM_SYNTAX_ERROR 501 /* Syntax error in parameters or
- X arguments. */
- #define FTP_CMD_NOT_NEEDED 202 /* Command not implemented, superfluous
- X at this site. */
- #define FTP_CMD_NOT_IMPL 502 /* Command not implemented. */
- #define FTP_BAD_CMD_SEQ 503 /* Bad sequence of commands. */
- #define FTP_CMD_PARM_NOT_IMPL 504 /* Command not implemented for that
- X parameter. */
- X
- #define FTP_RESTART_MARKER 110 /* Restart marker reply.
- X In this case, the text is exact and not
- X left to the particular implementation;
- X it must read:
- X MARK yyyy = mmmm
- X Where yyyy is User-process data stream
- X marker, and mmmm server's equivalent
- X marker (note the spaces between markers
- X and "="). */
- #define FTP_SYS_STATUS 211 /* System status, or system help reply. */
- #define FTP_DIR_STATUS 212 /* Directory status. */
- #define FTP_FILE_STATUS 213 /* File status. */
- #define FTP_HELP_MSG 214 /* Help message.
- X On how to use the server or the meaning
- X of a particular non-standard command.
- X This reply is useful only to the human
- X user. */
- #define FTP_SYS_NAME 215 /* NAME system type.
- X Where NAME is an official system name
- X from the list in the Assigned Numbers
- X document. */
- #define FTP_SERVICE_RDY_TIME 120 /* Service ready in nnn minutes. */
- #define FTP_SERVICE_RDY_USER 220 /* Service ready for new user. */
- #define FTP_SERVICE_CLOSING 221 /* Service closing control connection.
- X Logged out if appropriate. */
- #define FTP_SERVICE_UNAVAILABLE 421 /* Service not available, closing control
- X connection. This may be a reply to any
- X command if the service knows it must
- X shut down. */
- #define FTP_TRANSFER_STARTING 125 /* Data connection already open; transfer
- X starting. */
- #define FTP_DATA_OPEN 225 /* Data connection open; no transfer in
- X progress. */
- #define FTP_DATA_FAILED 425 /* Can't open data connection. */
- #define FTP_DATA_CLOSE_OK 226 /* Closing data connection.
- X Requested file action successful (for
- X example, file transfer or file abort).*/
- #define FTP_DATA_CLOSE_ABORT 426 /* Connection closed; transfer aborted. */
- #define FTP_ENTERING_PASSIVE 227 /* Entering Passive Mode
- X (h1,h2,h3,h4,p1,p2). */
- X
- #define FTP_LOGIN_OK 230 /* User logged in, proceed. */
- #define FTP_LOGIN_ERR 530 /* Not logged in. */
- #define FTP_LOGIN_NEED_PASSWD 331 /* User name okay, need password. */
- #define FTP_LOGIN_NEED_ACCT 332 /* Need account for login. */
- #define FTP_FILE_NEED_ACCT 532 /* Need account for storing files. */
- X
- #define FTP_DATACONN_OPEN 150 /* File status okay; about to open data
- X connection. */
- #define FTP_FILE_ACTION_OK 250 /* Requested file action okay, completed.*/
- #define FTP_PATHNAME_CREATED 257 /* "PATHNAME" created. */
- #define FTP_FILE_ACTION_PENDING 350 /* Requested file action pending further
- X information. */
- #define FTP_FILE_UNAVAILABLE 450 /* Requested file action not taken.
- X File unavailable (e.g., file busy). */
- #define FTP_ACTION_NOT_TAKEN 550 /* Requested action not taken.
- X File unavailable (e.g., file not found,
- X no access). */
- #define FTP_ABORTED_LOCAL_ERR 451 /* Requested action aborted. Local error
- X in processing. */
- #define FTP_ABORTED_PAGE_TYPE 551 /* Requested action aborted. Page type
- X unknown. */
- #define FTP_INSUFFICIENT_SPACE 452 /* Requested action not taken.
- X Insufficient storage space in system.*/
- #define FTP_EXCEEDED_ALLOCATION 552 /* Requested file action aborted.
- X Exceeded storage allocation (for
- X current directory or dataset). */
- #define FTP_BAD_FILENAME 553 /* Requested action not taken.
- X File name not allowed. */
- X
- #endif /* !_XA_FTP_H */
- SHAR_EOF
- chmod 0644 xarchie-2.0.6/ftp.h ||
- echo 'restore of xarchie-2.0.6/ftp.h failed'
- Wc_c="`wc -c < 'xarchie-2.0.6/ftp.h'`"
- test 10022 -eq "$Wc_c" ||
- echo 'xarchie-2.0.6/ftp.h: original size 10022, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= xarchie-2.0.6/get_pauth.c ==============
- if test -f 'xarchie-2.0.6/get_pauth.c' -a X"$1" != X"-c"; then
- echo 'x - skipping xarchie-2.0.6/get_pauth.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting xarchie-2.0.6/get_pauth.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/get_pauth.c' &&
- /*
- X * Copyright (c) 1989, 1990 by the University of Washington
- X *
- X * For copying and distribution information, please see the file
- X * <copyright.h>.
- X *
- X * gf: xarchie v2.0 - Sync with archie v1.4.1 - changes marked with "gf"
- X */
- X
- #include <copyright.h>
- #include <stdio.h>
- #include "config.h" /* gf */
- #include "stringdefs.h" /* gf */
- X
- #ifndef VMS
- # if defined(MSDOS) && !defined(OS2) && !defined(PCNFS)
- # ifndef CUTCP
- # include <rwconf.h>
- # endif
- # else
- # include <pwd.h>
- # endif
- #else
- # include <jpidef.h>
- # include <vms.h>
- #endif
- X
- #include <pcompat.h>
- #include <pauthent.h>
- X
- /*gf*/
- /*ARGSUSED*/
- PAUTH
- get_pauth(type)
- X int type;
- X {
- X static PAUTH_ST no_auth_st;
- X static PAUTH no_auth = NULL;
- #if !defined(VMS) && !defined(MSDOS) || defined(OS2) || defined(PCNFS)
- X struct passwd *whoiampw;
- #else
- X char username[13];
- X unsigned short usernamelen;
- X struct {
- X unsigned short buflen;
- X unsigned short itmcod;
- X char *bufadr;
- X unsigned short *retlenadr;
- X unsigned long null;
- X } jpi_itemlist;
- #endif
- X
- X if(no_auth == NULL) {
- X no_auth = &no_auth_st;
- X strcpy(no_auth->auth_type,"UNAUTHENTICATED");
- X
- X /* find out who we are */
- #ifndef VMS
- #if defined(MSDOS) && !defined(OS2) && !defined(PCNFS)
- #ifndef CUTCP
- X if (!getconf("general", "user", no_auth->authenticator, 250)
- X || (strlen (no_auth->authenticator) == 0))
- #endif
- X strcpy(no_auth->authenticator,"nobody");
- #else /* not MSDOS */
- X DISABLE_PFS(whoiampw = getpwuid(getuid()));
- X if (whoiampw == 0) strcpy(no_auth->authenticator,"nobody");
- X else strcpy(no_auth->authenticator, whoiampw->pw_name);
- #endif /* not MSDOS */
- #else
- X jpi_itemlist.buflen = sizeof(username);
- X jpi_itemlist.itmcod = JPI$_USERNAME;
- X jpi_itemlist.bufadr = &username;
- X jpi_itemlist.retlenadr = &usernamelen;
- X jpi_itemlist.null = 0;
- X if (SYS$GETJPI(0, 0, 0, &jpi_itemlist, 0, 0, 0) & 0x1)
- X {
- X username[usernamelen] = 0;
- X strcpy(no_auth->authenticator, username);
- X } else
- X strcpy(no_auth->authenticator, "nobody");
- #endif
- X }
- X return(no_auth);
- X }
- SHAR_EOF
- chmod 0644 xarchie-2.0.6/get_pauth.c ||
- echo 'restore of xarchie-2.0.6/get_pauth.c failed'
- Wc_c="`wc -c < 'xarchie-2.0.6/get_pauth.c'`"
- test 2068 -eq "$Wc_c" ||
- echo 'xarchie-2.0.6/get_pauth.c: original size 2068, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= xarchie-2.0.6/get_vdir.c ==============
- if test -f 'xarchie-2.0.6/get_vdir.c' -a X"$1" != X"-c"; then
- echo 'x - skipping xarchie-2.0.6/get_vdir.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting xarchie-2.0.6/get_vdir.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/get_vdir.c' &&
- /*
- X * Copyright (c) 1989, 1990, 1991 by the University of Washington
- X *
- X * For copying and distribution information, please see the file
- X * <copyright.h>.
- X */
- X
- #include <copyright.h>
- #include <stdio.h>
- X
- #include <pfs.h>
- #include <pprot.h>
- #include <perrno.h>
- #include <pcompat.h>
- #include <pauthent.h>
- X
- #include "config.h" /* gf */
- #include "stringdefs.h" /* gf */
- X
- #ifdef DEBUG
- extern int pfs_debug;
- #endif
- X
- extern int pwarn;
- extern char p_warn_string[];
- extern int perrno;
- extern char p_err_string[];
- X
- /*
- X * get_vdir - Get contents of a directory given its location
- X *
- X * GET_VDIR takes a directory location, a list of desired
- X * components, a pointer to a directory structure to be
- X * filled in, and flags. It then queries the appropriate
- X * directory server and retrieves the desired information.
- X *
- X * ARGS: dhost - Host on which directory resides
- X * dfile - Directory on that host
- X * components - The names from the directory we want
- X * dir - Structure to be filled in
- X * flags - Options. See FLAGS
- X * filters - filters to be applied to result
- X * acomp - Pointer to remaining components
- X *
- X * FLAGS: GVD_UNION - Do not expand union links
- X * GVD_EXPAND - Expand union links locally
- X * GVD_REMEXP - Request remote expansion (& local if refused)
- X * GVD_LREMEXP - Request remote expansion of local union links
- X * GVD_VERIFY - Only verify that args are for a directory
- X * GVD_ATTRIB - Request attributes from directory server
- X * GVD_NOSORT - Do not sort links when adding to directory
- X *
- X * RETURNS: PSUCCESS (0) or error code
- X * On some codes addition information in p_err_string
- X *
- X * NOTES: If acomp is non-null the string it points to might be modified
- X *
- X * If the directory passed as an argument already has
- X * links or union links, then those lists will be freed
- X * before the new contents are filled in.
- X *
- X * If a filter is passed to the procedure, and application of
- X * the filter results in additional union link, then those links
- X * will (or will not) be expanded as specified in the FLAGS field.
- X *
- X * If the list of components in NULL, or the null string, then
- X * get_vdir will return all links in the requested directory.
- X *
- X * BUGS: Doesn't process union links yet
- X * Doesn't process errors returned from server
- X * Doesn't expand union links if requested to
- X */
- int
- get_vdir(dhost,dfile,components,dir,flags,filters,acomp)
- X char *dhost; /* Host on which directory resides */
- X char *dfile; /* Name of file on that host */
- X char *components; /* Component name (wildcards allowed) */
- X PVDIR dir; /* Structure to be filled in */
- X long flags; /* Flags */
- X VLINK filters; /* Filters to be applied to result */
- X char *acomp; /* Components left to be resolved */
- X {
- X PTEXT request; /* Text of request to dir server */
- X PTEXT resp; /* Response from dir server */
- X
- X char ulcomp[MAX_VPATH];/* Work space for new current component */
- X char *comp = components;
- X
- X VLINK cur_link = NULL;/* Current link being filled in */
- X VLINK exp = NULL; /* The current ulink being expanded */
- X VLINK pul = NULL; /* Prev union link (insert new one after it) */
- X VLINK l; /* Temp link pointer */
- X int mcomp; /* Flag - check multiple components */
- X int unresp; /* Flag - received unresolved response */
- X int getattrib = 0; /* Get attributes from server */
- X int vl_insert_flag; /* Flags to vl_insert */
- X
- X int fwdcnt = MAX_FWD_DEPTH;
- X
- X int no_links = 0; /* Count of number of links found */
- X
- X char options[40]; /* LIST option */
- X char *opt; /* After leading + */
- X
- X PAUTH authinfo;
- X
- X /* Treat null string like NULL (return entire directory) */
- X if(!components || !*components) comp = NULL;
- X
- X if(acomp && !filters) mcomp = 1;
- X else mcomp = 0;
- X
- X if(flags&GVD_ATTRIB) {
- X getattrib++;
- X flags &= (~GVD_ATTRIB);
- X }
- X
- X if(flags&GVD_NOSORT) vl_insert_flag = VLI_NOSORT;
- X else vl_insert_flag = VLI_ALLOW_CONF;
- X flags &= (~GVD_NOSORT);
- X
- X if(filters) comp = NULL;
- X
- X perrno = 0;
- X
- X authinfo = get_pauth(PFSA_UNAUTHENTICATED);
- X
- X *options = '\0';
- X
- X if(getattrib) {
- X strcat(options,"+ATTRIBUTES");
- X flags &= (~GVD_ATTRIB);
- X }
- X
- X if(!filters) { /* Can't do remote expansion if filters to be applied */
- X if(flags == GVD_REMEXP) strcat(options,"+EXPAND");
- X if(flags == GVD_LREMEXP) strcat(options,"+LEXPAND");
- X }
- X
- X /* If all we are doing is verifying that dfile is a directory */
- X /* then we do not want a big response from the directory */
- X /* server. A NOT-FOUND is sufficient. */
- X if(flags == GVD_VERIFY)
- #ifdef NEWVERIFYOPT
- X strcat(options,"+VERIFY");
- #else
- X comp = "%#$PRobably_nOn_existaNT$#%";
- #endif
- X
- X if(*options) opt = options+1;
- X else opt = "''";
- X
- X startover:
- X request = ptalloc();
- X
- X sprintf(request->start,
- X "VERSION %d %s\nAUTHENTICATOR %s %s\nDIRECTORY ASCII %s\nLIST %s COMPONENTS %s%s%s\n",
- X VFPROT_VNO, PFS_SW_ID, authinfo->auth_type,
- X authinfo->authenticator, dfile, opt,
- X (comp ? comp : ""), (mcomp ? "/" : ""),
- X (mcomp ? acomp : ""));
- X
- X request->length = strlen(request->start);
- X
- #ifdef DEBUG
- X if(pfs_debug > 2)
- X fprintf(stderr,"Sending message to dirsrv:\n%s",request->start);
- #endif
- X
- #if defined(MSDOS)
- X resp = dirsend(request,dhost,0L);
- #else
- X resp = dirsend(request,dhost,0);
- #endif
- X
- #ifdef DEBUG
- X if(pfs_debug && (resp == NULL)) {
- X fprintf(stderr,"Dirsend failed: %d\n",perrno);
- X }
- #endif
- X
- X /* If we don't get a response, then if the requested */
- X /* directory, return error, if a ulink, mark it unexpanded */
- X if(resp == NULL) {
- X if(exp) exp->expanded = FAILED;
- X else return(perrno);
- X }
- X
- X unresp = 0;
- X
- X /* Here we must parse reponse and put in directory */
- X /* While looking at each packet */
- X while(resp) {
- X PTEXT vtmp;
- X char *line;
- X
- X vtmp = resp;
- #ifdef DEBUG
- X if(pfs_debug > 3) fprintf(stderr,"%s\n",resp->start);
- #endif
- X /* Look at each line in packet */
- X for(line = resp->start;line != NULL;line = nxtline(line)) {
- X switch (*line) {
- X
- X /* Temporary variables to hold link info */
- X char l_linktype;
- X char l_name[MAX_DIR_LINESIZE];
- X char l_type[MAX_DIR_LINESIZE];
- X char l_htype[MAX_DIR_LINESIZE];
- X char l_host[MAX_DIR_LINESIZE];
- X char l_ntype[MAX_DIR_LINESIZE];
- X char l_fname[MAX_DIR_LINESIZE];
- X int l_version;
- X char t_unresolved[MAX_DIR_LINESIZE];
- X int l_magic;
- X int tmp;
- X
- X case 'L': /* LINK or LINK-INFO */
- X if(strncmp(line,"LINK-INFO",9) == 0) {
- X PATTRIB at;
- X PATTRIB last_at;
- X at = parse_attribute(line);
- X if(!at) break;
- X
- X /* Cant have link info without a link */
- X if(!cur_link) {
- X perrno = DIRSRV_BAD_FORMAT;
- X atfree(at);
- X break;
- X }
- X
- X if(cur_link->lattrib) {
- X last_at = cur_link->lattrib;
- X while(last_at->next) last_at = last_at->next;
- X at->previous = last_at;
- X last_at->next = at;
- X }
- X else {
- X cur_link->lattrib = at;
- X at->previous = NULL;
- X }
- X break;
- X }
- X
- X /* Not LINK-INFO, must be LINK - if not check for error */
- X if(strncmp(line,"LINK",4) != 0) goto scanerr;
- X
- X /* If only verifying, don't want to change dir */
- X if(flags == GVD_VERIFY) {
- X break;
- X }
- X /* If first link and some links in dir, free them */
- X if(!no_links++) {
- X if(dir->links) vllfree(dir->links); dir->links=NULL;
- X if(dir->ulinks) vllfree(dir->ulinks); dir->ulinks=NULL;
- X }
- X
- X cur_link = vlalloc();
- X
- X /* parse and insert file info */
- X tmp = sscanf(line,"LINK %c %s %s %s %s %s %s %d %d", &l_linktype,
- X l_type, l_name, l_htype, l_host,
- X l_ntype, l_fname, &(cur_link->version),
- X &(cur_link->f_magic_no));
- X
- X if(tmp != 9) {
- X perrno = DIRSRV_BAD_FORMAT;
- X vlfree(cur_link);
- X break;
- X }
- X
- X cur_link->linktype = l_linktype;
- X cur_link->type = stcopyr(l_type,cur_link->type);
- X cur_link->name = stcopyr(unquote(l_name),cur_link->name);
- X cur_link->hosttype = stcopyr(l_htype,cur_link->hosttype);
- X cur_link->host = stcopyr(l_host,cur_link->host);
- X cur_link->nametype = stcopyr(l_ntype,cur_link->nametype);
- X cur_link->filename = stcopyr(l_fname,cur_link->filename);
- X
- X /* Double check to make sure we don't get */
- X /* back unwanted components */
- X /* OK to keep if special (URP) links */
- X /* or if mcomp specified */
- X if(!mcomp && (cur_link->linktype == 'L') &&
- X (!wcmatch(cur_link->name,comp))) {
- X vlfree(cur_link);
- X break;
- X }
- X
- X /* If other optional info was sent back, it must */
- X /* also be parsed before inserting link *** */
- X
- X
- X if(cur_link->linktype == 'L')
- X vl_insert(cur_link,dir,vl_insert_flag);
- X else {
- X tmp = ul_insert(cur_link,dir,pul);
- X
- X /* If inserted after pul, next one after cur_link */
- X if(pul && (!tmp || (tmp == UL_INSERT_SUPERSEDING)))
- X pul = cur_link;
- X }
- X
- X break;
- X
- X case 'F': /* FILTER, FAILURE or FORWARDED */
- X /* FORWARDED */
- X if(strncmp(line,"FORWARDED",9) == 0) {
- X if(fwdcnt-- <= 0) {
- X ptlfree(resp);
- X perrno = PFS_MAX_FWD_DEPTH;
- X return(perrno);
- X }
- X /* parse and start over */
- X
- X tmp = sscanf(line,"FORWARDED %s %s %s %s %d %d",
- X l_htype,l_host,l_ntype,l_fname,
- X &l_version, &l_magic);
- X
- X dhost = stcopy(l_host);
- X dfile = stcopy(l_fname);
- X
- X if(tmp < 4) {
- X perrno = DIRSRV_BAD_FORMAT;
- X break;
- X }
- X
- X ptlfree(resp);
- X goto startover;
- X }
- X if(strncmp(line,"FILTER",6) != 0) goto scanerr;
- X break;
- X
- X
- X case 'M': /* MULTI-PACKET (processed by dirsend) */
- X case 'P': /* PACKET (processed by dirsend) */
- X break;
- X
- X case 'N': /* NOT-A-DIRECTORY or NONE-FOUND */
- X /* NONE-FOUND, we just have no links to insert */
- X /* It is not an error, but we must clear any */
- X /* old links in the directory arg */
- X if(strncmp(line,"NONE-FOUND",10) == 0) {
- X /* If only verifying, don't want to change dir */
- X if(flags == GVD_VERIFY) {
- X break;
- X }
- X
- X /* If first link and some links in dir, free them */
- X if(!no_links++) {
- X if(dir->links) vllfree(dir->links);
- X if(dir->ulinks) vllfree(dir->ulinks);
- X dir->links = NULL;
- X dir->ulinks = NULL;
- X }
- X break;
- X }
- X /* If NOT-A-DIRECTORY or anything else, scan error */
- X goto scanerr;
- X
- X case 'U': /* UNRESOLVED */
- X if(strncmp(line,"UNRESOLVED",10) != 0) {
- X goto scanerr;
- X }
- X tmp = sscanf(line,"UNRESOLVED %s", t_unresolved);
- X if(tmp < 1) {
- X perrno = DIRSRV_BAD_FORMAT;
- X break;
- X }
- X /* If multiple components were resolved */
- X if(strlen(t_unresolved) < strlen(acomp)) {
- X strcpy(ulcomp,acomp);
- X /* ulcomp is the components that were resolved */
- X *(ulcomp+strlen(acomp)-strlen(t_unresolved)-1) = '\0';
- X /* Comp gets the last component resolved */
- X comp = (char *) rindex(ulcomp,'/');
- X if(comp) comp++;
- X else comp = ulcomp;
- X /* Let rd_vdir know what remains */
- X strcpy(acomp,t_unresolved);
- X }
- X unresp = 1;
- X break;
- X
- X case 'V': /* VERSION-NOT-SUPPORTED */
- X if(strncmp(line,"VERSION-NOT-SUPPORTED",21) == 0) {
- X perrno = DIRSRV_BAD_VERS;
- X return(perrno);
- X }
- X goto scanerr;
- X
- X scanerr:
- X default:
- X if(*line && (tmp = scan_error(line))) {
- X ptlfree(resp);
- X return(tmp);
- X }
- X break;
- X }
- X }
- X
- X resp = resp->next;
- X
- X ptfree(vtmp);
- X }
- X
- X /* We sent multiple components and weren't told any */
- X /* were unresolved */
- X if(mcomp && !unresp) {
- X /* ulcomp is the components that were resolved */
- X strcpy(ulcomp,acomp);
- X /* Comp gets the last component resolved */
- X comp = (char *) rindex(ulcomp,'/');
- X if(comp) comp++;
- X else comp = ulcomp;
- X /* If we have union links to resolve, only one component remains */
- X mcomp = 0;
- X /* Let rd_vdir know what remains */
- X *acomp = '\0';
- X }
- X
- X /* If only verifying, we already know it is a directory */
- X if(flags == GVD_VERIFY) return(PSUCCESS);
- X
- X /* Don't return if matching was delayed by the need to filter */
- X /* if FIND specified, and dir->links is non null, then we have */
- X /* found a match, and should return. */
- X if((flags & GVD_FIND) && dir->links && (!filters))
- X return(PSUCCESS);
- X
- X /* If expand specified, and ulinks must be expanded, making sure */
- X /* that the order of the links is maintained properly */
- X
- expand_ulinks:
- X
- X if((flags != GVD_UNION) && (flags != GVD_VERIFY)) {
- X
- X l = dir->ulinks;
- X
- X /* Find first unexpanded ulink */
- X while(l && l->expanded && (l->linktype == 'U')) l = l->next;
- X
- X /* Only expand if a FILE or DIRECTORY - Mark as */
- X /* failed otherwise */
- X /* We must still add support for symbolic ulinks */
- X if(l) {
- X if ((strcmp(l->type,"DIRECTORY") == 0) ||
- X (strcmp(l->type,"FILE") == 0)) {
- X l->expanded = TRUE;
- X exp = l;
- X pul = l;
- X dhost = l->host;
- X dfile = l->filename;
- X goto startover; /* was get_contents; */
- X }
- X else l->expanded = FAILED;
- X }
- X }
- X
- X /* Double check to make sure we don't get */
- X /* back unwanted components */
- X /* OK to keep if special (URP) links */
- X if(components && *components) {
- X l = dir->links;
- X while(l) {
- X VLINK ol;
- X if((l->linktype == 'L') && (!wcmatch(l->name,components))) {
- X if(l == dir->links)
- X dir->links = l->next;
- X else l->previous->next = l->next;
- X if(l->next) l->next->previous = l->previous;
- X ol = l;
- X l = l->next;
- X vlfree(ol);
- X }
- X else l = l->next;
- X }
- X }
- X
- X return(PSUCCESS);
- X }
- SHAR_EOF
- chmod 0644 xarchie-2.0.6/get_vdir.c ||
- echo 'restore of xarchie-2.0.6/get_vdir.c failed'
- Wc_c="`wc -c < 'xarchie-2.0.6/get_vdir.c'`"
- test 14086 -eq "$Wc_c" ||
- echo 'xarchie-2.0.6/get_vdir.c: original size 14086, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= xarchie-2.0.6/help-text1.h ==============
- if test -f 'xarchie-2.0.6/help-text1.h' -a X"$1" != X"-c"; then
- echo 'x - skipping xarchie-2.0.6/help-text1.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting xarchie-2.0.6/help-text1.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'xarchie-2.0.6/help-text1.h' &&
- "\n",
- NULL,
- "NAME\n",
- " xarchie - X11 browser interface to\n",
- " archie, version 2.0.6\n",
- "\n",
- NULL,
- "SYNOPSIS\n",
- " xarchie [X Toolkit options]\n",
- " [-host host]\n",
- " [-search type|-e|-c|-s|-r|-ec|-es|-er]\n",
- " [-sort type|-t|-w]\n",
- " [-maxhits num]\n",
- " [-offset num] [-nice\n",
- " lev|-N lev] [-noscroll]\n",
- " [-mono|-gray|-color]\n",
- " [-debug num|-D num]\n",
- " [-help|-?]\n",
- "\n",
- NULL,
- "DESCRIPTION\n",
- " Xarchie is an X11 browser interface\n",
- " to the Archie Internet information\n",
- " system using the Prospero virtual\n",
- " filesystem protocol. Archie pro-\n",
- " vides information about files\n",
- " available for ftp anywhere on the\n",
- " Internet; Xarchie displays this\n",
- " information using an easy-to-use,\n",
- " point-and-click interface. Xarchie\n",
- " allows you to further explore ftp\n",
- " sites by examining directories\n",
- " returned as query matches, and\n",
- " allows you to retrieve files\n",
- " located this way. Xarchie is\n",
- " designed (like most X applications)\n",
- " to be highly customizable, allowing\n",
- " you to tailor the look-and-feel of\n",
- " the tool to your own preferences.\n",
- "\n",
- " This document is broken into two\n",
- " parts. First, the USER'S GUIDE\n",
- " describes Archie and Xarchie, and\n",
- " covers both Basic and Advanced Xar-\n",
- " chie usage. Second, the REFERENCE\n",
- " MANUAL provides all the information\n",
- " needed to customize Xarchie. You\n",
- " can also browse this document using\n",
- " the Xarchie Help facility.\n",
- "\n",
- " To report problems or bugs, please\n",
- " see the section \"Reporting Bugs\" in\n",
- " the REFERENCE MANUAL section.\n",
- "\n",
- NULL,
- "USER'S GUIDE\n",
- " The User's Guide section of this\n",
- " manual describes the Archie ser-\n",
- " vice, the Xarchie client, and how\n",
- " to use Xarchie to access resources\n",
- SHAR_EOF
- true || echo 'restore of xarchie-2.0.6/help-text1.h failed'
- fi
- echo 'End of xarchie-2.0.6 part 9'
- echo 'File xarchie-2.0.6/help-text1.h is continued in part 10'
- echo 10 > _shar_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
- --
- // chris@IMD.Sterling.COM | Send comp.sources.x submissions to:
- \X/ Amiga - The only way to fly! | sources-x@imd.sterling.com
- "It's intuitively obvious to the |
- most casual observer..." | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
-