/********************************************************************
* wilkinson
* 3.18VMS
* 1995/09/25 14:40
* gopher_root1:[gopher.g2.vms2_13.gopherd]special.c,v
* Exp
*
* Paul Lindner, University of Minnesota CIS.
*
* Copyright 1991, 1992 by the Regents of the University of Minnesota
* see the file "Copyright" in the distribution for conditions of use.
*********************************************************************
* MODULE: special.c
* routines to deal with special types of files, compressed, scripts, etc.
*********************************************************************
* Revision History:
* special.c,v
* Revision 3.18VMS 1995/09/25 14:40 wilkinson
* Consolodate VMS/Unix source code for server as well as client
*
* Revision 3.18 1994/07/21 04:08:29 lindner
* Bulletproofing for shell scripts
*
* Revision 3.17 1994/04/25 20:49:11 lindner
* Fix for debug code
*
* Revision 3.16 1994/04/14 15:48:54 lindner
* Fix for files with single quotes
*
* Revision 3.15 1993/11/03 03:32:52 lindner
* Test shell scripts for exec bit
*
* Revision 3.14 1993/08/19 20:52:30 lindner
* Mitra comments
*
* Revision 3.13 1993/08/11 22:47:11 lindner
* Don't let the security stuff trap ask blocks
*
* Revision 3.12 1993/08/06 14:30:49 lindner
* Fixes for better security logging
*
* Revision 3.11 1993/08/04 22:14:54 lindner
* Mods to use Gpopen
*
* Revision 3.10 1993/08/04 22:12:51 lindner
* Mods to use Gpopen
*
* Revision 3.9 1993/07/27 05:27:59 lindner
* Mondo Debug overhaul from Mitra
*
* Revision 3.8 1993/07/25 02:56:51 lindner
* Fixed iscompressed() to return NULL
*
* Revision 3.7 1993/07/23 03:18:13 lindner
* Mods for using decoder:'s
*
* Revision 3.6 1993/07/07 19:35:36 lindner
* removed extra args to popen()
*
* Revision 3.5 1993/06/22 06:58:53 lindner
* Added a little debug code..
*
* Revision 3.4 1993/06/11 16:46:50 lindner
* Support for gzipped files
*
* Revision 3.3 1993/04/09 15:00:19 lindner
* Fixes for ask shell scripts, ensure that they're run in the current
* directory of the script.
*
* Revision 3.2 1993/03/24 20:24:23 lindner
* Addition for compressed file support rfopenz()
*
* Revision 3.1.1.1 1993/02/11 18:02:53 lindner
* Gopher+1.2beta release
*
* Revision 1.3 1993/02/09 22:15:36 lindner
* additions for askfile
*
* Revision 1.2 1993/01/30 23:57:44 lindner
* Additions for ASK block support.
*
* Revision 1.1 1992/12/10 23:13:27 lindner
* gopher 1.1 release
*
*
*********************************************************************/
#ifdef VMS_SERVER
#define GSGOPHEROBJ_C
/* Right now, DEC C v5.0 seems to ignore the angle brackets and
pull in [-.object]string.h instead of the system
version of string.h, which we need here. But all we
need it for is a prototype of strchr(), so we'll put
that in by hand to get around this for now */
#include <string.h> /* */
/* char *strchr (const char *__s, int __c); /* */
#endif
#include "gopherd.h"
#ifdef VMS_SERVER
#undef GSGOPHEROBJ_C
#include "serverutil.h"
#endif
#include "ext.h"
#include "Debug.h"
char *iscompressed();
/* Check to see if this file needs special treatment before heading
* back to the client... We will check for:
* Encoded files execute decoder...
* Shellscript if so, "do it"
* (add ask block params if exists..)
* Note: it would be somewhat non-portable to check of a binary
* (we'd need to check for so many different magic numbers; the
* shell script designation should be sufficient, since the script
* can call an executable anyway
* Recognized elsewhere:
* .snd needs special processing on client
* uuencoded needs special processing on client
* Other filetypes we could check for:
* GIF -> Bring up GIF previewer
* Postscript -> Bring up Postscript previewer
*/
static int ispipe;
#ifdef VMS_SERVER
/* Provide a VMS way of doing popen() */
FILE *
vms_popen(char *cmd, char *mode)
{
int vms_pipe_status;
FILE *fopen_VMSopt(char *, char *, char *, char *);
if (((vms_pipe_status = VMS$system(cmd)) &1)==1)
return(fopen_VMSopt(vms_pipe_file,mode,"",""));
if (access(vms_pipe_file, 0) == 0)
unlink(vms_pipe_file);
vms_pipe_file[0] = '\0';
return((FILE *)(0));
}
/* Provide a VMS way of doing pclose() */
int
vms_pclose(FILE *fp)
{
int vms_pipe_status;
vms_pipe_status = fclose(fp);
if (strlen(vms_pipe_file)!=0)
unlink(vms_pipe_file);
vms_pipe_file[0] = '\0';
return(vms_pipe_status);
}
#endif
FILE *
specialfile(sockfd, fp, pathname)
int sockfd;
FILE *fp;
char *pathname;
{
FILE *pp;
static char buf[256];
char s[256], *cp;
long i;
char *decoder;
#ifdef VMS_SERVER
char *VMS$Validate_Filespec(char *);
#endif
ispipe = 0;
/* Keep track of where we are */
i = ftell(fp);
rewind(fp);
/* Grab the first line or 254 bytes, and rewind */
if (fgets(s, 255, fp) == NULL)
return (FILE *)0;
fseek(fp, i, 0);
/* Compressed? */
if ((decoder = iscompressed(pathname)) != NULL) {
#ifndef VMS_SERVER
dequote1(pathname);
if (dochroot)
sprintf(buf, "%s '%s'", decoder, pathname);
else
sprintf(buf, "%s '%s/%s'", decoder, Data_Dir, pathname);
#else
/* Need to set up buf & vms_pipe_file for VMS decoding here */
#endif
Debug("Executing decoder %s\n",buf);
pp = popen(buf, "r");
if (!pp)
return (FILE *)0;
ispipe = 1;
return pp;
}
/* Script? */
#ifndef VMS_SERVER
if (isshellscript(s) && isexec(fileno(fp))) {
dequote1(pathname);
s[strlen(s)-1] = '\0';
if (dochroot)
sprintf(buf, "\"%s\" %s", pathname, (EXECargs == NULL) ? "" : EXECargs);
else
sprintf(buf, "\"%s/%s\" %s", Data_Dir, pathname, (EXECargs == NULL) ? "" : EXECargs);
if (ASKfile != NULL) { /* Ick this is a global*/
strcat(buf, " < ");
strcat(buf, ASKfile);
}
else
strcat(buf, " < /dev/null ");
/*
* Okay, let's change our working directory for the benefit of
* shell script writers everywhere :-)
*/
strcpy(s, pathname);
cp = strrchr(s, '/');
if (cp != NULL && cp > s) {
*cp = '\0';
;
} else
strcpy(s, "/");
rchdir(s);
#else
if (isshellscript(s, pathname)) {
strcpy(vms_pipe_file, pathname);
if ((cp=strchr(vms_pipe_file,' '))!=NULL)
*cp = '\0';
if (VMS$Validate_Filespec(vms_pipe_file)==NULL) {
vms_pipe_file[0] = '\0';
return (FILE *)(ispipe=0);
}
strcpy(vms_pipe_file, cp=tempnam(GDCgetScratchDir(Config),NULL));
free(cp);
sprintf(buf, "$ @%s/output=%s", pathname, vms_pipe_file);
if (ASKfile != NULL) {
strcat(buf, "/input="); /** JLW - I know this won't work */
strcat(buf, ASKfile); /** just a placeholder, really **/
}
if (EXECargs != NULL) {
strcat(buf, " \"");
strcat(buf, EXECargs);
strcat(buf, "\"");
}
#endif
Debug("Executing %s\n", buf);
if (EXECargs) {
if (! (pp = Gpopen(sockfd, buf, "r")))
return (FILE *)0;
}
else {
if (! (pp = popen(buf, "r")))
return (FILE *)0;
}
ispipe = 1;
Debugmsg("Zcat/popen is okay\n");
return pp;
}
return (FILE *)0;
}
char *
iscompressed(pathname)
char *pathname;
{
static Extobj *ext = NULL;
if (pathname == NULL || strlen(pathname)==0)
return(NULL);
if (ext == NULL)
ext = EXnew();
if (EXAcasedSearch(Config->Extensions, ext, pathname, EXT_DECODER))
return(EXgetDecoder(ext));
return(NULL);
}
/*
* Is this a shell script?
*/
#ifndef VMS_SERVER
int
isshellscript(s)
char *s;
{
if (! strncmp(s, "#!", 2))
return 1;
else
return 0;
}
#else
int
isshellscript(char *s, char *path)
{
if (strncasecmp(path+strlen(path)-strlen(".SCRIPT"),".SCRIPT")!=0)
return 0;
if (! strncmp(s, "$!", 2))
return 1;
else
return 0;
}
#endif
#ifndef VMS_SERVER
/*
* Are the exec bits set?
*/
int
isexec(fd)
int fd;
{
STATSTR sb;
if (fstat(fd, &sb) == -1)
return 0;
if (sb.st_mode & S_IXUSR)
return 1;
else
return 0;
}
#endif
int
Specialclose(fp)
FILE *fp;
{
if (ASKfile != NULL) /* Ick this is a global*/
unlink(ASKfile);
if (ispipe)
return(pclose(fp));
else
return(fclose(fp));
}
.
Response:
text/plain