/*********************************************************************** Global include files ***********************************************************************/ #include #include #include #include #include #include #include #include /*********************************************************************** Global routine declarations ***********************************************************************/ char *getvalue(); char *lstrstr(); char *decode(); void badconnection(); void badsegviol(); void badtimeout(); char *strdup(); char *GetCoden(); char *GetDirectory(); /*********************************************************************** Defined files for use by program. ***********************************************************************/ #define CODENFILE "/disk2/suitespot/epaps_files/coden_lookup" #define TITLEFILE "/disk2/suitespot/epaps_files/title_lookup" #define HEAD "/disk2/suitespot/epaps_files/head" #define EXTFILE "/disk2/suitespot/epaps_files/ext_includes" #define TAIL "/disk2/suitespot/epaps_files/tail" #define ROOTDIR "/ftp/public/epaps" /* #define CODENFILE "/netscape/src/epaps/coden_lookup" #define TITLEFILE "/netscape/src/epaps/title_lookup" #define HEAD "/netscape/src/epaps/head" #define EXTFILE "/netscape/src/epaps/ext_includes" #define TAIL "/netscape/src/epaps/tail" #define ROOTDIR "/ftp/edir" */ /*********************************************************************** General define statements. ***********************************************************************/ #define MAXSTRLEN 1024 #define TIMEOUT 45 #define HEXLEN 5 /*********************************************************************** Structure declarations ***********************************************************************/ /*********************************************************************** Global variables (yuck) are here. ***********************************************************************/ int skip[5120]; static char query_string[5120]; int main( int argc, char **argv) { int i, len; char *method, *query; char PapId[ MAXSTRLEN], *Coden, *SubDir, Directory[ 1024]; char IdType[ MAXSTRLEN], DoiCoden[MAXSTRLEN], FileName[MAXSTRLEN], *Ptr; /* Close the stderr. */ fclose(stderr); /* Send certain signals to routines so we can catch errors from the * httpd server. */ signal(SIGSEGV, badsegviol); signal(SIGPIPE, badconnection); signal(SIGALRM, badtimeout); /* First, get all the normal environment CGI things... */ method = (char *) getenv("REQUEST_METHOD"); /* If it's a bad method..... */ if (method == NULL) progerr("Unknown method."); /* The POST method */ if (!strncmp(method, "POST", 4)) { len = atoi(getenv("CONTENT_LENGTH")); i = 0; while (len-- && i < MAXSTRLEN) query_string[i++] = fgetc(stdin); query_string[i] = '\0'; } /* The GET method. */ else if (!strncmp(method, "GET", 3)) { query = (char *) getenv("QUERY_STRING"); if (query == NULL) query_string[0] = '\0'; else strcpy(query_string, query); } else progerr("Unknown method."); strncpy( PapId, getvalue( "ID=", ""), MAXSTRLEN); strncpy( IdType, getvalue( "IDTYPE=", ""), MAXSTRLEN); strncpy( DoiCoden, getvalue( "CODEN=", ""), MAXSTRLEN); strncpy( FileName, getvalue( "FILE=", ""), MAXSTRLEN); if( !*PapId) { progerr2(); } if( *IdType && !strcasecmp( IdType, "doi")) { if( !*DoiCoden) progerr2(); Coden = strdup( DoiCoden); Ptr = PapId+8; strcpy( PapId, Ptr); } else Coden = strdup( GetCoden( PapId)); SubDir = strdup( GetDirectory( Coden)); sprintf( Directory, "%s/%s/%s", ROOTDIR, SubDir, PapId); if( access( Directory, R_OK) != 0) progerr2(); if( *FileName) { printf( "Location: ftp://ftp.aip.org/%s/%s\n\n", Directory+12, FileName); exit( 0); } PrintHead(); PrintFile( HEAD); PrintTitle( Coden); ScanFiles( Directory); PrintFile( TAIL); return( 0); } char *GetCoden( char *Id) { char *Temp, *p; if( strncasecmp( Id, "E-", 2)) progerr2(); Temp = strdup( Id); Temp += 2; if( !(p = strchr( Temp, '-'))) progerr2(); *p = '\0'; return( Temp); } char *GetDirectory( char *Coden) { FILE *Inp = NULL; char Temp[ 1024], *Directory = NULL; if( !(Inp = fopen( CODENFILE, "r"))) progerr2(); while( fgets( Temp, 1024, Inp)) { if( Temp[0] == '#') continue; Temp[ strlen( Temp) - 1] = '\0'; if( !strncmp( Temp, Coden, strlen( Coden))) Directory = strdup( Temp+strlen( Coden) + 1); } fclose( Inp); if( !Directory) progerr2(); return( Directory); } PrintTitle( char *Coden) { FILE *Inp = NULL; char Temp[ 1024]; char *p = NULL; if( !(Inp = fopen( TITLEFILE, "r"))) return( 1); while( fgets( Temp, 1024, Inp)) { if( Temp[0] == '#') continue; Temp[ strlen( Temp) - 1] = '\0'; if( !(p = strchr( Temp, ' '))) continue; *p++ = '\0'; if( !strcmp( Temp, Coden)) /* printf( "%s\n", Temp+strlen( Coden) + 1); */ printf( "%s\n", p); } printf( "

\n"); fclose( Inp); } PrintFile( char *Filename) { FILE *Inp = NULL; char Temp[ 1024]; if( !(Inp = fopen( Filename, "r"))) return( 1); while( fgets( Temp, 1024, Inp)) printf( "%s", Temp); fclose( Inp); return( 0); } OutputURL( int Http, char *Directory, char *Name) { struct stat buf; char Temp[1024]; float Size = 0.0; printf( "%s", Http ? "http" : "ftp", Directory+12, Name, Name); sprintf( Temp, "%s/%s", Directory, Name); if( !Http && stat( Temp, &buf) == 0) { Size = buf.st_size / 1024.0; printf( " (%.1f kB)", Size); } } OutputText( char *Name) { FILE *Inp = NULL; char Temp[ 5120]; int Found = 0; char *p, *s; if( !(p = strchr( Name, '.'))) return( 0); if( !(Inp = fopen( EXTFILE, "r"))) return( 0); while( fgets( Temp, 5120, Inp)) { if( Temp[0] == '#') continue; s = strchr( Temp, ' '); *s++ = '\0'; if( !strcmp( Temp, p)) { Found++; printf( " %s", s); } } fclose( Inp); if( Found) printf( "

\n"); return( Found); } GetReadmeLine() { FILE *Inp = NULL; char Temp[ 5120]; if( !(Inp = fopen( EXTFILE, "r"))) return( 0); while( fgets( Temp, 5120, Inp)) { if( Temp[0] == '#') continue; if( !strncasecmp( Temp, "README", 6)) printf( " %s\n

", Temp + 7); } fclose( Inp); return( 1); } ScanFiles( char *Directory) { DIR *dirp; struct dirent *direntp; char Store[500][1024]; int Count = 0, i = 0; if( !(dirp = opendir( Directory))) progerr( "Cannot open directory..."); while(( direntp = readdir( dirp)) != NULL) { if( *direntp->d_name == '.') continue; if( !strncasecmp( direntp->d_name, "index.html", 10)) { printf( "The author has provided an "); printf( "HTML index page", Directory+12, direntp->d_name); printf( " to facilitate the access of these files.

"); } else if( !strncasecmp( direntp->d_name, "index.htm", 9)) { printf( "The author has provided an "); printf( "HTML index page", Directory+12, direntp->d_name); printf( " to facilitate the access of these files.

"); } } rewinddir( dirp); while(( direntp = readdir( dirp)) != NULL) { if( *direntp->d_name == '.') continue; if( !strncasecmp( direntp->d_name, "README", 6)) { OutputURL( 1, Directory, direntp->d_name); GetReadmeLine(); } else if( !strncasecmp( direntp->d_name, "index.html", 10)) continue; else if( !strncasecmp( direntp->d_name, "index.htm", 9)) continue; else strcpy( Store[Count++], direntp->d_name); } closedir( dirp); for( i=0; i < Count; i++) { OutputURL( 0, Directory, Store[ i]); if( !OutputText( Store[ i])) printf( "

\n"); } } /* The NEW getvalue routine. * 2/27/96 - James T. Wonder * The old getvalue routine had some problems with dealing with multiple * null variable pairs. This stemed from it's use of the Boyer-Moore * algorithm from Sedgewick. I removed this from the program and am using * the much faster strtok routine. Most systems should now have strtok * included in the standard library. This was the only reason for * Sedgewick :-). */ char *getvalue(var, def) char *var; char *def; { char String[MAXSTRLEN], *Token, *Ptr; static char tmpstr[MAXSTRLEN]; strcpy( String, query_string); for( Token = strtok( String, "&"); Token; Token = strtok( NULL, "&")) { /* Found it! Yeah! */ if( !strncasecmp( Token, var, strlen( var))) { Ptr = Token + strlen( var); if( !Ptr || !*Ptr) { if( strlen(def) <= 1) return "\0"; strcpy(tmpstr, decode(def)); return tmpstr; } strcpy(tmpstr, decode(Ptr)); return tmpstr; } } if( strlen(def) <= 1) return "\0"; strcpy(tmpstr, decode(def)); return tmpstr; } PrintHead() { /* Do the content type. */ printf( "Content-type: text/html\n\n"); printf( "\n"); printf( "\n"); printf( "EPAPS\n"); printf( "\n"); } /* Whoops, caught a problem! */ progerr(errstring) char *errstring; { PrintHead(); printf("

Error

\n"); printf("This program encountered an error:

\n"); printf("

%s\n

\n", errstring); exit(0); } progerr2() { /* printf( "Location: http://scitation.aip.org/error/noepaps.html\n\n"); */ printf( "Location: http://scitation.aip.org/error/noepaps.jsp\n\n"); exit( 0); } /* Decodes URL-encoded strings. */ char *decode(s) char *s; { int i, j, ascint; char firstnum, secondnum; static char newstr[MAXSTRLEN]; for (i = j = 0; s[i]; i++) { if (s[i] == '%') { firstnum = s[++i]; secondnum = s[++i]; ascint = (getascii(firstnum) * 16) + getascii(secondnum); if (ascint == 10 || ascint == 13) ascint = 32; newstr[j++] = (char) ascint; continue; } else if (s[i] == '+') newstr[j++] = ' '; else newstr[j++] = s[i]; } newstr[j] = '\0'; return newstr; } /* Encodes strings so they can be put in URLs. */ char *encode(s) char *s; { int i; char hexstr[HEXLEN]; static char line[MAXSTRLEN]; for (i = 0; *s; s++) if (*s == ' ') line[i++] = '+'; else if (isdigit(*s) || isalpha(*s)) line[i++] = *s; else { sprintf(hexstr, "%0X", *s); line[i++] = '%'; line[i++] = hexstr[0]; line[i] = hexstr[1]; if (line[i] == '\0') { line[i] = line[i - 1]; line[i - 1] = '0'; } i++; } line[i] = '\0'; return line; } /* Returns the right ASCII code for a hex value. */ int getascii(hex) char hex; { if ((int) hex >= 48 && (int) hex <= 57) return (hex - 48); else return (hex - 65 + 10); } /* Error messages for broken pipes, SIGSEGV, and timing out. */ void badconnection() { progerr("Can't connect to this server (it is probably down)."); } void badsegviol() { progerr("Caught a memory violation (probably a parsing error)."); } void badtimeout() { char message[MAXSTRLEN]; sprintf(message, "This service timed out (%d seconds) - it may be too busy.", TIMEOUT); progerr(message); }