/********************************************************************
* wilkinson
* 3.24VMS
* 1995/11/24 12:00
* gopher_root1:[gopher.g2.vms2_13.gopherd]command.c,v
* Exp
*
* Paul Lindner, University of Minnesota CIS.
*
* Copyright 1991, 1992, 1993 by the Regents of the University of Minnesota
* see the file "Copyright" in the distribution for conditions of use.
*********************************************************************
* MODULE: command.c
* Routines to parse commands from the client.
*********************************************************************
* Revision History:
* command.c,v
* Revision 3.24VMS 1995/11/24 12:00 wilkinson
* Use err_ret() and new CMDsetErrored() macro instead of err_quit() when
* "getcommand:readline error" occurs.
*
* Revision 3.24 1995/01/04 17:42:59 lindner
* small renaming
*
* Revision 3.23 1994/12/10 08:24:56 lindner
* Start building HTTP parser
*
* Revision 3.22 1994/12/03 02:14:44 lindner
* Fix predone searches
*
* Revision 3.21 1994/12/02 19:51:14 lindner
* Weird p removed and fix for prespecified searches
*
* Revision 3.20 1994/11/24 08:07:54 lindner
* Fix for command routines with authentication
*
* Revision 3.19 1994/10/19 03:31:59 lindner
* Another NO_AUTH code hack...
*
* Revision 3.18 1994/07/31 04:38:20 lindner
* Add optional pre-specified search string..
*
* Revision 3.17 1994/06/29 05:29:19 lindner
* Remove Admit1, put in cool stuff
*
* Revision 3.16 1994/04/25 20:49:03 lindner
* Fix for debug code
*
* Revision 3.15 1994/04/08 21:08:34 lindner
* Gcc -Wall fix
*
* Revision 3.14 1994/03/30 21:36:34 lindner
* Fix for binary ask data from Don Gilbert
*
* Revision 3.13 1994/03/15 17:57:41 lindner
* Fix for SCO compiler
*
* Revision 3.12 1994/03/08 15:55:25 lindner
* gcc -Wall fixes
*
* Revision 3.11 1994/03/04 23:26:04 lindner
* Fix for changes in strstring.h
*
* Revision 3.10 1994/01/20 06:37:03 lindner
* Addition for 'h' prefix for selector string
*
* Revision 3.9 1993/11/02 05:53:40 lindner
* more docs
*
* Revision 3.8 1993/10/04 06:49:20 lindner
* ASK data stored in core, for a while..
*
* Revision 3.7 1993/09/30 16:56:53 lindner
* Fix for WAIS and $ requests
*
* Revision 3.6 1993/07/29 20:13:32 lindner
* Removed dead variables
*
* Revision 3.5 1993/07/27 05:27:40 lindner
* Mondo Debug overhaul from Mitra
*
* Revision 3.4 1993/07/23 03:10:53 lindner
* Added CMDgetFile() fcn
*
* Revision 3.3 1993/04/09 16:50:24 lindner
* nothing
*
* Revision 3.2 1993/03/24 20:19:40 lindner
* Fixed memory leak
*
* Revision 3.1 1993/03/19 19:56:53 lindner
* New CMD object
*
*
*********************************************************************/
#include "Malloc.h"
#include "String.h"
#include <stdio.h>
#include "util.h"
#include "command.h"
#include "openers.h"
#include "Debug.h"
CMDobj *
CMDnew()
{
CMDobj *temp;
temp = (CMDobj *) malloc(sizeof(CMDobj));
temp->selstr = temp->command = temp->search = NULL;
temp->datafromnet = STRnew();
temp->asklines = STAnew(5);
temp->view = STRnew();
temp->secureuser = STRnew();
temp->ticket = STRnew();
CMDsetGplus(temp, FALSE);
#ifdef VMS_SERVER
CMDsetErrored(temp, FALSE);
#endif
return(temp);
}
void
CMDdestroy(cmd)
CMDobj *cmd;
{
STRdestroy(cmd->datafromnet);
STAdestroy(cmd->asklines);
STRdestroy(cmd->view);
STRdestroy(cmd->ticket);
STRdestroy(cmd->secureuser);
free(cmd);
}
char*
CMDparseHTTP(cmd,cp)
CMDobj *cmd;
char *cp;
{
int len;
if (cp == NULL)
return(NULL);
len = strlen(cp);
if ((len > 5) && ((strncmp(cp, "GET /",5) == 0))) {
;
cp += 5;
Debug("HTML item is %s\n", cp + len -4);
if ((len >14) && (strcmp(cp + len - 14, " HTTP/1.0")==0))
*(cp + len - 14) = '\0';
}
return(cp);
}
void
CMDfromNet(cmd, sockfd)
CMDobj *cmd;
int sockfd;
{
char *cp, *selstr;
char inputline[512];
char *field1=NULL, *field2=NULL, *field3 = NULL;
char *extradata = NULL;
int length;
length = readline(sockfd, inputline, sizeof(inputline));
/** Set the alarm signal for about an hour, just in case.. **/
(void) alarm(60 * 60);
if (length <= 0) {
close(sockfd);
#ifndef VMS_SERVER
err_quit("getcommand: readline error");
#else
err_ret("getcommand: readline error");
CMDsetErrored(cmd, TRUE);
return;
#endif
}
ZapCRLF(inputline);
Debug("Received: %s\n", inputline);
CMDsetData(cmd, inputline);
cp = CMDgetData(cmd);
cp = CMDparseHTTP(cmd, cp);
cp = CMDticketfromLine(cmd, cp);
CMDsetSelstr(cmd, cp);
selstr = cp;
/** Find the first field, if it exists... **/
cp = strchr(selstr, '\t');
if (cp != NULL) {
*cp = '\0';
cp++;
field1 = cp;
/** find the second field, if it exists **/
cp = strchr(cp, '\t');
if (cp != NULL) {
*cp = '\0';
cp++;
field2 = cp;
} else {
/** find the third field, if it exists **/
if (cp != NULL)
cp = strchr(cp, '\t');
if (cp != NULL) {
*cp = '\0';
cp++;
field3 = cp;
}
}
}
/** Okay, now decide which field is the search and
which is the command */
if (*selstr == '7' || strncmp(selstr, "waissrc:",8)==0 ||
strncmp(selstr, "mindex:",7) ==0) {
char *questionmark;
/** If it's a type 7 search, search for a ? mark in the
** selector string. (Yeah, yeah, it's weblike)
**/
questionmark = strrchr(selstr, '?');
if (questionmark != NULL) {
*questionmark = '\0';
CMDsetSearch(cmd, questionmark+1);
CMDsetCommand(cmd, field1);
} else {
CMDsetSearch(cmd, field1);
CMDsetCommand(cmd, field2);
}
} else {
CMDsetCommand(cmd, field1);
CMDsetSearch(cmd, NULL);
}
/** Get the extra data (from an ask block etc.) if we've got
an extra data flag... **/
if (field3 != NULL)
extradata = field3;
else if (CMDgetSearch(cmd) == NULL && field2 != NULL)
extradata = field2;
if (extradata != NULL) {
CMDgetXtra(cmd, sockfd, atoi(extradata));
}
/** Test to see if we've got Gplus behaviour */
if (CMDgetCommand(cmd) != NULL && *CMDgetCommand(cmd) != '\0')
CMDsetGplus(cmd, TRUE);
Debugmsg("Command:: ");
#ifdef VMS_SERVER
if (CMDisErrored(cmd))
Debugmsg("errored, ");
#endif
Debug("selstr %s, ", CMDgetSelstr(cmd));
Debug("command %s, ", CMDgetCommand(cmd));
Debug("search %s, ", CMDgetSearch(cmd));
Debug("user %s, ", CMDgetUser(cmd));
Debug("ticket %s, ", CMDgetTicket(cmd));
}
void
CMDpushAskline(cmd, line)
CMDobj *cmd;
char *line;
{
String *temp = STRnew();
STRset(temp, line);
STApush(cmd->asklines, temp);
STRdestroy(temp);
}
/* dgg need for binary ask data */
void
CMDpushAskBinary(cmd, buf, buflen)
CMDobj *cmd;
char *buf;
long buflen;
{
String *temp = STRnew();
temp->data= buf;
temp->len= buflen;
STApush(cmd->asklines, temp);
temp->data= NULL; /* caller owns buf */
STRdestroy(temp);
}
/*
* Retrieve extra data from the client request.. This stuff is optional
*
*/
void
CMDgetXtra(cmd, fd, extradata)
CMDobj *cmd;
int fd;
int extradata;
{
char inputline[512];
/** Siphon off data if it's there.. **/
/** A ticket? **/
if ((extradata & 0x2) == 0x2) {
;
}
/** An ask block **/
if ((extradata & 0x1) == 0x1) {
/** Okay, the next line is either +-1, or +bytes .. **/
readline(fd, inputline, sizeof(inputline));
Debug("received: %s\n", inputline);
ZapCRLF(inputline);
if (strncmp(inputline, "+-1",3)==0) {
while (readline(fd, inputline, sizeof(inputline))>0) {
ZapCRLF(inputline);
ZapCRLF(inputline);
if (*inputline == '.' && *(inputline+1) == '\0')
break;
CMDpushAskline(cmd, inputline);
}
}
/* dgg: patch for askfile +bytecount or +-2 input forms */
/* dgg++ -- need this to read binary file from client */
else {
/*inputline == "+-2" or "+bytes..." */
long count, nbytes;
nbytes= atol(inputline+1);
if (nbytes == -2) do { /* read til close */
count= readrecvbuf(fd,inputline,sizeof(inputline));
if (count>0) CMDpushAskBinary(cmd, inputline, count);
} while (count>0);
else while (nbytes>0) { /* read til nbytes found */
count= sizeof(inputline);
if (count>nbytes) count= nbytes;
count= readrecvbuf(fd,inputline,count);
if (count>0) CMDpushAskBinary(cmd, inputline, count);
nbytes -= count;
}
}
}
}
char *
CMDticketfromLine(cmd, input)
CMDobj *cmd;
char *input;
{
#ifndef NO_AUTHENTICATION
char *cp;
char *originput = input;
if (*input != '*')
return(originput);
input++;
cp = strchr(input, ' ');
if (cp == NULL)
return(originput);
*cp = '\0';
CMDsetUser(cmd,input);
input = cp+1;
cp = strchr(input, ' ');
if (cp == NULL)
return(originput);
*cp = '\0';
CMDsetTicket(cmd, input);
return(cp+1);
#endif
;
}
/** Find an associated file from the selector string... Yuck! **/
char *
CMDgetFile(cmd)
CMDobj *cmd;
{
char *selstr = CMDgetSelstr(cmd);
char *cp = NULL;
if (strncmp(selstr, "validate ", 9) == 0)
selstr += 9;
switch (*selstr) {
case '0':
case '1':
case '7':
case '9':
case 'h':
case 's':
case 'I':
return(selstr+1);
case 'm':
if (strncmp(selstr,"mindex:",7)==0)
return(selstr+7);
else
return(selstr+1);
case 'R':
cp = strchr(selstr, '-');
if (cp == NULL) break;
cp++;
cp = strchr(cp, '-');
if (cp == NULL) break;
return(cp+1);
/*** Exec: ***/
case 'e':
cp = strrchr(selstr, ':');
if (cp!=NULL)
return(cp+1);
else
return(NULL);
break;
/** WAIS docid **/
case 'w':
if (strncmp(selstr, "waissrc:",8)==0)
return(strchr(selstr, ':')+1);
default:
if (*selstr == '\0') {
return("//");
} else {
return(NULL);
}
}
return(NULL);
;
}
.
Response:
text/plain