Intial commit

This commit is contained in:
Mario Fetka
2024-05-27 16:13:40 +02:00
parent f8dc12b10a
commit d71d446104
2495 changed files with 539746 additions and 0 deletions

1
prospero/user/menu/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
Makefile

16
prospero/user/menu/FILES Normal file
View File

@@ -0,0 +1,16 @@
FILES
Makefile
api.c
bub.c
comp.c
config.h
io_util.c
item_desc.c
line.c
main.c
menu.c
menu.h
objects.c
objects.h
p_menu.h
search.c

87
prospero/user/menu/Makefile.in Executable file
View File

@@ -0,0 +1,87 @@
SOURCEBASE=../..
include $(SOURCEBASE)/Makefile.config
CFILES = api.c menu.c main.c comp.c bub.c item_desc.c line.c io_util.c objects.c search.c
OBJECTS= api.o menu.o main.o comp.o bub.o item_desc.o line.o io_util.o objects.o search.o
MENU_LIB=libmenu.a
PROGS = menu
SPECIAL_OTHERTARGETS = $(MENU_LIB)
all: $(PROGS) $(SPECIAL_OTHERTARGETS)
menu: $(OBJECTS) ${USE_VCACHE_LIBS_DEPENDENCIES}
$(CC) $(CFLAGS) -o menu $(OBJECTS) ${USE_VCACHE_LIBS} ../../../libpsarchie/libpsarchie.a
## This library needs to be more reasonably generated.
## It currently is a melange. At least it's useful.
${MENU_LIB}: ${OBJECTS}
rm -f ${MENU_LIB}
ar r${AR_FLAGS} ${MENU_LIB} ${OBJECTS}
$(RANLIB) ${MENU_LIB}
install:
-${INSTALL} -c -m $(INSTALL_EXE_MODE) -o ${OWNER} -g ${GROUP} menu ${P_BINARIES}/menu${GENERATIONSUFFIX}
-${GENERATION} ${P_BINARIES}/menu
# Dependencies
api.o : p_menu.h ../../include/pfs.h \
../../include/pfs_utils.h ../../include/ardp.h \
../../include/pfs_threads.h \
../../include/list_macros.h \
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
../../include/pmachine.h \
menu.h \
../../include/perrno.h
menu.o : menu.h p_menu.h ../../include/pfs.h \
../../include/pfs_utils.h ../../include/ardp.h \
../../include/pfs_threads.h \
../../include/list_macros.h \
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
../../include/pmachine.h \
config.h ../../include/psite.h ../../include/perrno.h
main.o : menu.h \
p_menu.h ../../include/pfs.h ../../include/pfs_utils.h ../../include/ardp.h \
../../include/pfs_threads.h \
../../include/list_macros.h \
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
../../include/pmachine.h
comp.o : ../../include/pfs.h \
../../include/pfs_utils.h ../../include/ardp.h \
../../include/pfs_threads.h \
../../include/list_macros.h \
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
../../include/pmachine.h
bub.o : ../../include/pfs.h \
../../include/pfs_utils.h ../../include/ardp.h \
../../include/pfs_threads.h \
../../include/list_macros.h \
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
../../include/pmachine.h \
menu.h p_menu.h
item_desc.o : ../../include/pfs.h \
../../include/pfs_utils.h ../../include/ardp.h \
../../include/pfs_threads.h \
../../include/list_macros.h \
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
../../include/pmachine.h
line.o :
io_util.o :
objects.o : \
../../include/pfs.h \
../../include/pfs_utils.h ../../include/ardp.h ../../include/pfs_threads.h \
../../include/list_macros.h \
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
../../include/pmachine.h \
config.h p_menu.h menu.h
search.o : ../../include/pfs.h \
../../include/pfs_utils.h ../../include/ardp.h \
../../include/pfs_threads.h \
../../include/list_macros.h \
../../include/../lib/ardp/flocks.h ../../include/implicit_fixes.h \
../../include/pmachine.h \
menu.h p_menu.h

253
prospero/user/menu/api.c Normal file
View File

@@ -0,0 +1,253 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include "p_menu.h"
#include "menu.h" /* auxiliary functions */
#include <stdlib.h>
#include <sys/file.h>
#ifdef AIX
#include <fcntl.h> /* SCO UNIX needs O_RDONLY*/
#else
#include <sys/fcntl.h> /* SCO UNIX needs O_RDONLY*/
#endif
#include <pfs.h>
#include <perrno.h>
char *m_error = NULL;
static char error_buffer[300]; /* This is really kludgy, but it'll be fixed
soon. */
VLINK
m_top_menu(void) {
VLINK temp;
temp = rd_vlink(".");
if (temp == NULL) {
m_error = error_buffer;
sperrmesg(error_buffer,"ERROR: ",perrno,NULL);
return NULL;
}
m_error = NULL;
return temp;
}
VLINK
m_get_menu(VLINK vl)
{
VDIR_ST dir_st;
VDIR dir = &dir_st;
VLINK list;
vdir_init(dir);
/* As soon as p_get_dir returns specific attributes, we want
MENU-ITEM-DESCRIPTION+COLLATION-ORDER+ACCESS-METHOD to be returned.
*/
if (p_get_dir(vl,"*", dir,GVD_REMEXP|GVD_ATTRIB|GVD_NOSORT,NULL) != 0) {
m_error = error_buffer;
sperrmesg(error_buffer,"ERROR: ",0,NULL);
vdir_freelinks(dir);
return NULL;
}
list = dir->links; dir->links = NULL;
vdir_freelinks(dir);
m_error = NULL;
return vlink_list_sort(list);
}
/*
int m_is_menu(VLINK vl) {
static char * err_msg_1 = "A NULL link was sent to m_is_menu()";
static char * err_msg_2 = "A link with a NULL target was sent to m_is_menu()";
if (vl == NULL) {
m_error = err_msg_1;
return 0;
}
if (vl->target == NULL) {
m_error = err_msg_2;
return 0;
}
m_error = NULL;
return (strequal(vl->target,"DIRECTORY"));
}
int m_is_text_file(VLINK vl) {
static char * err_msg_1 = "A NULL link was sent to m_is_text_file()";
static char * err_msg_2 =
"A link with a NULL target was sent to m_is_text_file()";
if (vl == NULL) {
m_error = err_msg_1;
return 0;
}
if (vl->target == NULL) {
m_error = err_msg_2;
return 0;
}
m_error = NULL;
return
((strequal(vl->target,"FILE")) || (strequal(vl->target,"EXTERNAL")));
}
*/
int
m_open_file(VLINK vl) {
int temp;
temp = pfs_open(vl,O_RDONLY);
if (temp == -1) {
m_error = error_buffer;
sperrmesg(error_buffer,"ERROR: ",perrno,NULL);
return -1;
}
m_error = NULL;
return temp;
}
FILE *
m_fopen_file(VLINK vl)
{
FILE *temp;
temp = pfs_fopen(vl,"r");
if (temp == NULL) {
m_error = error_buffer;
sperrmesg(error_buffer,"ERROR: ",perrno,NULL);
return NULL;
}
m_error = NULL;
return temp;
}
char *
m_item_description(VLINK vl)
{
char *temp;
char *get_item_desc(VLINK);
static char *buf = NULL;
static char * err_msg_1 = "NULL link sent to m_item_description()";
static char * err_msg_2 =
"m_item_description could not find any description or name for the given link";
if (vl == NULL) {
m_error = err_msg_1;
return NULL;
}
temp = get_item_desc(vl);
if (temp != NULL) {
buf = stcopy(temp);
m_error = NULL;
return buf;
}
m_error = err_msg_2;
return NULL;
}
#include <string.h> /* need strrchr() */
/* Does 'name' have the suffix 'suf' ? Suffices all start with a '.' which is
not passed to this function. */
static int
hassuffix(char *name, char *suf)
{
char *lastdot = strrchr(name, '.');
if (lastdot) return strequal(lastdot + 1, suf); /* 1 if true */
else return 0; /* false */
}
int
m_class(VLINK vl)
{
TOKEN type = m_interpretation(vl);
char *name;
if (vl == NULL) return M_CLASS_UNKNOWN;
if (type == NULL) {
if (strequal("DIRECTORY",vl->target))
return M_CLASS_MENU;
else if (strequal("FILE",vl->target) ||
strequal("EXTERNAL",vl->target)) {
char *n = vl->name; /* file name */
/* If the file has no OBJECT-INTERPRETATION attribute, try
to pick an class for it based upon the last component of the
file name or upon the contents. This is a transitional
measure, since at the moment many files lack
OBJECT-INTERPRETATION attributes. */
if (!n
|| hassuffix(n, "a") /* UNIX library archives */
|| hassuffix(n, "com") /* MS-DOS executables */
|| hassuffix(n, "exe") /* executables from some systems */
|| hassuffix(n, "gif") /* you know :) */
|| hassuffix(n, "gz") /* gnuzip */
|| hassuffix(n, "hqx") /* MAC binary encoding format */
|| hassuffix(n, "jpeg") /* an image format */
|| hassuffix(n, "jpg") /* JPEG from MS-DOS :) */
|| hassuffix(n, "mpeg") /* video format :) */
|| hassuffix(n, "mpg") /* MPEG from ms-dos :) */
|| hassuffix(n, "o") /* Unix .o (object) file. */
|| hassuffix(n, "tar") /* Unix TAR format (tape archive) */
|| hassuffix(n, "tif") /* TIFF files from MS-DOS */
|| hassuffix(n, "tiff") /* TIFF */
|| hassuffix(n, "pbm") /* portable bitmaps */
|| hassuffix(n, "xbm") /* x bit maps */
|| hassuffix(n, "Z") /* compress */
|| hassuffix(n, "z") /* old gnuzip */
/* A few common cases. */
|| strequal(n, "core") || strequal(n, "a.out"))
return M_CLASS_DATA;
else
return M_CLASS_DOCUMENT;
} else
return M_CLASS_UNKNOWN;
} /* type == NULL */
if (strequal(elt(type,0),"PORTAL")) return M_CLASS_PORTAL;
if (strequal(elt(type,0),"SEARCH")) return M_CLASS_SEARCH;
if (length(type) >= 3 && strequal(elt(type,0), "DOCUMENT")
&& strequal(elt(type, 1), "TEXT") && strequal(elt(type, 2), "ASCII"))
return M_CLASS_DOCUMENT;
if (strequal(elt(type,0),"DIRECTORY")) return M_CLASS_MENU;
if (strequal(elt(type,0),"DATA")) return M_CLASS_DATA;
if (strequal(elt(type,0),"EXECUTABLE")) return M_CLASS_DATA;
if (strequal(elt(type,0),"AGGREGATE")) return M_CLASS_DATA;
if (strequal(elt(type,0),"IMAGE")) return M_CLASS_DATA;
if (strequal(elt(type,0),"SOUND")) return M_CLASS_DATA;
if (strequal(elt(type,0),"VIDEO")) return M_CLASS_DATA;
if (strequal(elt(type,0),"VIRTUAL-SYSTEM")) return M_CLASS_MENU;
if (strequal(elt(type,0),"EMBEDDED")) return M_CLASS_DATA;
if (length(type) >= 2 && strequal(elt(type,0), "DOCUMENT")
&& strequal(elt(type, 1), "MIME"))
return M_CLASS_DOCUMENT;
if (strequal(elt(type,0),"SOURCE-CODE")) return M_CLASS_DOCUMENT;
if (strequal(elt(type,0),"PROGRAM")) return M_CLASS_DOCUMENT;
/* Any documents this implementation can't display using a standard
text display program are M_CLASS_DATA. */
if (strequal(elt(type,0),"DOCUMENT")) return M_CLASS_DATA;
/* Unrecognized */
return M_CLASS_UNKNOWN;
}
TOKEN
m_interpretation(VLINK vl)
{
return get_token(vl, "OBJECT-INTERPRETATION");
}

75
prospero/user/menu/bub.c Normal file
View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include <pfs.h>
#include "menu.h"
static VLINK swap(VLINK,VLINK);
/* This prototype of the function performs a bubble sort; this will soon be
changed. */
VLINK
vlink_list_sort(VLINK list)
{
VLINK temp;
int compare_collation_ord(VLINK,VLINK);
VLINK head = list; /* use the variable 'list' to do final
rearranging. */
VLINK next; /* used to do final rearranging. --swa */
int all_in_order = 0;
if (!head || !head->next) all_in_order = 1; /* singleton or empty list is
always in order. */
while (!all_in_order) {
all_in_order = 1;
if (compare_collation_ord(head,head->next) == -1)
head = swap(head,head->next);
temp = head;
all_in_order = 1;
while (temp->next->next != NULL) {
if (compare_collation_ord(temp -> next,temp -> next -> next) == -1) {
all_in_order = 0;
temp -> next = swap(temp->next,temp->next->next);
}
temp = temp -> next;
}
}
/* We now have a singly-linked list of VLINKs rooted at 'head'. */
/* Now reorder the list of links, so that it meets the standard
doubly-linked-list conventions. --swa */
list = NULL;
for (temp = head ; temp; temp = next) {
next = temp->next;
APPEND_ITEM(temp, list);
}
return list;
}
static VLINK
swap(VLINK vl1,VLINK vl2) {
vl1 -> next = vl2 -> next;
vl2 -> next = vl1;
vl1 -> previous = vl2;
vl2 -> previous = vl1 -> previous;
return vl2;
}

231
prospero/user/menu/comp.c Normal file
View File

@@ -0,0 +1,231 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include <pfs.h>
int compare_collation_ord(VLINK v1,VLINK v2) {
struct pattrib *get_high_coll_ord(PATTRIB);
PATTRIB coll1 = get_high_coll_ord(v1->lattrib);
PATTRIB coll2 = get_high_coll_ord(v2->lattrib);
int temp;
int compare_name(VLINK,VLINK);
struct token *seq_1;
struct token *seq_2;
/* Excluding ASCII and "LAST" (not implemented yet), there are three
possible states for each link -- NO-COLL-ATTRIB, LAST, or what I'll
call "first" (i.e. not LAST). There are three states for each of the
two links, so there are six possible combinations. Here is a table of
them. I have represented NO-COLLATION-ATTRIBUTE with "___",
LAST with 'L', and "first" with 'F'.
Possible combinations of COLLATION-ATTRIBUTES for two links
1: ___ ___
2: L ___
3: F ___
4: L F
5: L L
6: F F
*/
if ((coll1 == NULL) && (coll2 == NULL)) return compare_name(v1,v2);
/* there goes case #1 */
if (coll1 == NULL) return
(!strcmp(coll2->value.sequence->token,"LAST")) ? 1 : -1;
if (coll2 == NULL) return
(!strcmp(coll1->value.sequence->token,"LAST")) ? -1 : 1;
/* there go #2 and #3 */
/* Now we no that neither of the collation pointers are NULL. */
seq_1 = coll1->value.sequence;
seq_2 = coll2->value.sequence;
/* Now there's the degenerate case of a non-NULL COLL-ATTRIB with a
NULL value.sequence. The spec says that this should be treated just
like a NULL COLL-ATTRIB.
Now we repeat the above performance, replacing "coll"'s with "seq"'s
*/
if ((seq_1 == NULL) && (seq_2 == NULL)) return compare_name(v1,v2);
if (seq_1 == NULL) return
(!strcmp(seq_2->token,"LAST")) ? 1 : -1;
if (seq_2 == NULL) return
(!strcmp(seq_1->token,"LAST")) ? -1 : 1;
/* This code determines if EITHER the COLL-ATTRIBS are BOTH "FIRST"
or both "LAST". If not, then one of them is last (case #4), and
we return that as lower. Note that those are the only three
cases left.
*/
if (
(temp = (!(strcmp(seq_1->token,"LAST"))))
!= (!(strcmp(seq_2->token,"LAST")))
) return temp ? -1 : 1;
/* Now we're down to BOTH LAST's and both FIRST's. The process for
comparing these is the same. However, with LAST we must move
beyond the word "LAST" to get to "NUMERIC" or "ASCII".
So we advance the pointer.
*/
if (!strcmp(seq_1->token,"LAST")) {
seq_1 = seq_1 -> next;
seq_2 = seq_2 -> next;
/* This is the case of LAST with no arguments. If both are of type "LAST",
then they remain in the former order (1 comes before 2).
*/
if (seq_1 == NULL && seq_2 == NULL) return 1;
/* If one is "LAST" and the other is "LAST ASCII" or "LAST NUMERIC", then
the one that is "LAST" goes last;
*/
if ((temp = (seq_1 == NULL)) || (seq_2 == NULL))
temp ? -1 : 1;
}
/* Now we are down to NUMERIC or ASCII */
/* If one's ASCII and one's NUMERIC, the NUMERIC comes first */
if ((temp = (!strcmp(seq_1->token,"NUMERIC")))
!= (!strcmp(seq_1->token,"NUMERIC"))
) return temp ? 1 : -1;
/* After that we know that we have both NUMERIC or both ASCII */
/* We know that they're both NUMERIC or BOTH ASCII. Whether they're LAST
NUMERIC or LAST ASCII or "FIRST" NUMERIC and "FIRST" ASCII makes no
difference.
*/
if (!strcmp(seq_1->token,"ASCII")) {
/* Move past the word ASCII */
seq_1 = seq_1 -> next;
seq_2 = seq_2 -> next;
while((seq_1 != NULL) && (seq_2 != NULL)) {
if (temp = strcmp(seq_1->token,seq_2->token)) break;
seq_1 = seq_1 -> next;
seq_2 = seq_2 -> next;
}
if ((seq_1 == NULL) && (seq_2 == NULL))
return compare_name(v1,v2);
/* If one was NULL, the one that ends first is first */
if ((seq_1 == NULL) || (seq_2 == NULL))
return (seq_1 == NULL) ? 1: -1;
/* seq_1 and seq_2 were both non-NULL and non-equal. Determine
the inequality and return. */
return ((temp < 0) ? 1:-1);
}
/* We now assume that only NUMERIC is left. If this isn't the case,
something's very wrong. Perhaps the attribute is malformed */
/* Move past the word NUMERIC */
seq_1 = seq_1 -> next;
seq_2 = seq_2 -> next;
/* Compare numbers until there are no more or they are unequal */
while ((seq_1 != NULL) && (seq_2 != NULL)) {
if (!((atoi(seq_1->token) == atoi(seq_2->token)))) break;
seq_1 = seq_1 -> next;
seq_2 = seq_2 -> next;
}
if ((seq_1 == NULL) && (seq_2 == NULL))
return compare_name(v1,v2);
/* If one was NULL, the one that ends first is first */
if ((seq_1 == NULL) || (seq_2 == NULL))
return (seq_1 == NULL) ? 1: -1;
/* If the loop above ended due to an inequality, determine it. */
return (atoi(seq_1->token) > atoi(seq_2->token)) ? -1: 1;
}
PATTRIB get_high_coll_ord(PATTRIB head) {
int compare_precedence(char,char);
PATTRIB temp = head;
PATTRIB highest = NULL;
while (temp != NULL) {
if (!strcmp(temp->aname,"COLLATION-ORDER")) {
if (highest == NULL) highest = temp;
else if
(compare_precedence(highest->precedence,temp->precedence) == -1)
highest = temp;
}
temp = temp->next;
}
return highest;
}
int compare_name(VLINK a,VLINK b) {
int cnt;
for (cnt=0;
((a->name[cnt]) == (b->name[cnt]))
&& (a->name[cnt] != '\0') && (b->name[cnt] != '\0');
cnt++) /* NULL loop body */
;
return (b->name[cnt] < a->name[cnt]) ? -1:1;
}
int compare_precedence(char p1,char p2) {
if (p1 == ATR_PREC_LINK ) return 1;
if (p2 == ATR_PREC_LINK ) return -1;
if (p1 == ATR_PREC_REPLACE) return 1;
if (p2 == ATR_PREC_REPLACE) return -1;
if (p1 == ATR_PREC_OBJECT ) return 1;
if (p2 == ATR_PREC_OBJECT ) return -1;
if (p1 == ATR_PREC_CACHED ) return 1;
if (p2 == ATR_PREC_CACHED ) return -1;
if (p1 == ATR_PREC_ADD ) return 1;
if (p2 == ATR_PREC_ADD ) return -1;
return 1;
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
/* You can define these to be a root host and directory to retrieve by default
if you are not running your own Prospero site. We expect these options to
be frequently used in small and medium sized CWIS systems based on this
browser. */
/* These definitions are commented out since the browser by default retrieves
the root menu by looking at the prototype virtual system at ISI. */
#if 0 /* UNCOMMENT HERE TO USE THESE */
#ifndef MENU_DEFAULT_HOST
#define MENU_DEFAULT_HOST "PROSPERO.ISI.EDU"
#endif
#ifndef MENU_DEFAULT_HSONAME
#define MENU_DEFAULT_HSONAME "/pfs/pfsdat/guest/local_vsystems/prototype/MENU"
#endif
#endif
#ifndef PRINT_PROGRAM
#define PRINT_PROGRAM "lpr"
#endif
#ifndef TELNET_PROGRAM
#define TELNET_PROGRAM "telnet"
#endif
#ifndef MAIL_SENDING_PROGRAM
#define MAIL_SENDING_PROGRAM "mail"
#endif

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include <stdio.h>
int
get_top_level_answer()
{
int temp = 'A';
char digits_buf[10];
int cnt;
int q_or_u;
int temp_digit;
void really_quit(int);
while (isspace(temp = getchar())) ;
if (temp == EOF) {
really_quit(temp);
return -1;
} else if (temp == 'q' || temp == 'u') {
q_or_u = temp;
while (!(temp == '\n' || temp == EOF))
temp = getchar();
if (temp == EOF) {
clearerr(stdin);
return -1;
}
if (q_or_u == 'q') {
really_quit(q_or_u);
return -1;
} else
return 0;
} else if (!isdigit(temp)) {
while (!(temp == '\n' || temp == EOF))
temp = getchar();
if (temp == EOF)
clearerr(stdin);
return -1;
}
digits_buf[0] = temp;
cnt = 1;
while (isdigit(temp = getchar()) && cnt < 10)
digits_buf[cnt++] = temp;
while (!(temp == '\n' || temp == EOF))
temp = getchar();
if (temp == EOF) {
clearerr(stdin);
return -1;
}
digits_buf[cnt] = '\0';
temp_digit = atoi(digits_buf);
if (temp_digit == 0)
return -1;
return temp_digit;
}
int
query_save_data()
{
char option = ' ';
char temp;
fputs("\n\nViewing, mailing, and printing of many additional file types will\n\
come in later versions of this program. For now, the only thing we can do\n\
with this data file is save it to a local file. Would you like to save (y/n) ?",
stdout);
fflush(stdout);
while (isspace(option) && option != '\n')
option = getchar();
temp = option;
while (!(temp == '\n' || temp == EOF))
temp = getchar();
if (temp == EOF) {
clearerr(stdin);
return 0; /* Must mean no */
}
if (option == 'y')
return 1;
else
return 0; /* anything else means no */
}
void
really_quit(int quit_char)
{
char really_quit_ch;
char temp = 'a';
if (quit_char == EOF)
clearerr(stdin);
printf("\nReally quit (y/n) ? ");
really_quit_ch = getchar();
while (!(temp == '\n' || temp == EOF))
temp = getchar();
if (temp == EOF)
clearerr(stdin);
if (really_quit_ch == 'y' || really_quit_ch == EOF) {
if (really_quit_ch == EOF)
printf("\n");
exit(0);
}
return;
}
int
get_option()
{
int option = ' ';
int temp = 'a';
while (isspace(option) && option != '\n')
option = getchar();
temp = option;
while (!(temp == '\n' || temp == EOF))
temp = getchar();
if (temp == EOF) {
clearerr(stdin);
return -1;
}
if (!(option == 'p' || option == 'm' || option == 's'))
return -1;
else
return option;
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include <pfs.h>
char *
get_item_desc(VLINK vl)
{
PATTRIB highest = NULL;
PATTRIB temp;
int compare_precedence(char,char);
struct token *temp_tok;
/* int invisible_interp = 0; OOPS - not used - Mitra*/
if (vl == NULL) return NULL;
if ((temp = vl->lattrib) == NULL) return vl->name;
while (temp != NULL) {
if (!strcmp("MENU-ITEM-DESCRIPTION",temp->aname))
if (highest == NULL) highest = temp;
else if (
compare_precedence(highest->precedence,temp->precedence) == -1
)
highest = temp;
temp = temp->next;
} /* while temp != NULL */
if (highest == NULL) return vl->name;
if ((temp_tok = highest->value.sequence) != NULL) {
if (temp_tok->token != NULL)
return temp_tok->token;
else return NULL;
}
else return NULL;
/* Oops - no way to get to this next line - Mitra*/
return vl->name;
} /* end get_item_desc() */

52
prospero/user/menu/line.c Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include <stdio.h>
char *recursive_get_line(int *is_eof, int count) {
char *temp_string;
int temp_char;
temp_char = getchar();
if (temp_char == EOF) {
clearerr(stdin);
*is_eof = 1;
return NULL;
}
if (temp_char == '\n') {
temp_string = (char *) stalloc(sizeof(char) * (count + 1));
temp_string[count] = '\0';
return temp_string;
}
temp_string = recursive_get_line(is_eof,count + 1) ;
if (temp_string != NULL)
temp_string[count] = temp_char;
else return NULL;
return temp_string;
}
char *get_line() {
char *temp;
int is_eof = 0;
temp = recursive_get_line(&is_eof,0);
if (is_eof) {
clearerr(stdin);
return NULL;
}
return temp;
}

104
prospero/user/menu/main.c Normal file
View File

@@ -0,0 +1,104 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-license.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
* Hacked on a bit for robustness by Steven Augart (swa@isi.edu)
*/
#include <usc-license.h>
#include "menu.h"
#include <string.h>
#include <pfs.h> /* for p_initialize() and VLINK */
void
main(int argc,char *argv[])
{
int choice;
VLINK temp;
MCS mcstruct_ptr;
extern int pfs_debug;
MCS *mc = &mcstruct_ptr;
char *cp; /* scratch char ptr. */
int tmp; /* return value from call to subfunc. */
/* Set the software ID for this client. */
/* If you are developing a Prospero client, please send email to
info-prospero@isi.edu to get your own software ID. */
p_initialize("mPtb", 0, (struct p_initialize_st *) NULL);
printf("\n\nProspero Menu Browser\n\n");
argc--; argv++;
while (argc > 0) {
#if 0
if (!strncmp(argv[0], "-D", 2)) {
pfs_debug = 9;
argc--;argv++;
}
#else
tmp = qsscanf(argv[0], "-D%r%d", &cp, &pfs_debug);
if (tmp == 1 || tmp == 2) {
argc--,argv++;
if (tmp == 1) pfs_debug = 1;
continue;
}
tmp = qsscanf(argv[0], "-N%r%d", &cp, &ardp_priority);
if (tmp == 1 || tmp == 2) {
argc--,argv++;
if (tmp == 1) pfs_debug = ARDP_MAX_PRI;
if(ardp_priority > ARDP_MAX_SPRI)
ardp_priority = ARDP_MAX_PRI;
if(ardp_priority < ARDP_MIN_PRI)
ardp_priority = ARDP_MIN_PRI;
continue;
}
#endif
}
init_menu(mc,set_environ(argc,argv));
while (1) {
print_current_menu(mc);
choice = query_choice(mc);
if (choice == -1) continue;
/* if (choice == -1) {
really_quit();
}
else if (choice == -2) printf("\nINVALID CHOICE. TRY AGAIN.\n");
*/
/*else*/ if (choice == 0) {
if (!top_menu(mc)) up_menu(mc);
else printf("\nThere are no higher menus.\n");
}
else {
temp = return_choice(choice,mc);
if (temp == NULL) printf("\nINVALID CHOICE. TRY AGAIN.\n");
else if (m_class(temp) == M_CLASS_MENU
|| m_class(temp) == M_CLASS_SEARCH) {
if (m_class(temp) == M_CLASS_MENU) get_menu(mc,temp);
else get_search(mc,temp);
if (is_empty(mc)) {
up_menu(mc);
if (m_class(temp) == M_CLASS_MENU)
printf("\nNO FILES IN %s! REPEATING PREVIOUS MENU...\n",
m_item_description(temp));
else
printf("No files were found as a result of the search %s. \
Repeating previous menu.\n", m_item_description(temp));
} /* if empty */
} /* if menu */
else if (m_class(temp) == M_CLASS_DOCUMENT) open_and_display(temp);
else if (m_class(temp) == M_CLASS_PORTAL) open_telnet(temp);
else if (m_class(temp) == M_CLASS_DATA) open_data(temp);
else printf("\nThis type is not implemented yet.\n");
} /* if choice > * */
} /* infinite loop */
} /* main() */

327
prospero/user/menu/menu.c Normal file
View File

@@ -0,0 +1,327 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include "menu.h"
#include "config.h"
#include <stdio.h>
#include <psite.h>
#include <perrno.h>
extern char *m_error;
static char error_buffer[300]; /* XXX Will have to replace this with the
flexible-length general Prospero string
handling routines. */
#define ck_fatal_err if ((m_error) != NULL) { fprintf(stderr,"%s",m_error); exit(1);}
VLINK set_environ(int argc,char *argv[]) {
int err;
VLINK vl,vl2,vl3,vl4;
VDIR_ST dir_st;
VDIR dir = &dir_st;
char *err_msg_1 = "\nNo initial directory is available\n\n";
if (argc == 0) {
vl = rd_vlink("/MENU");
if (vl != NULL) return vl;
#ifdef MENU_DEFAULT_HOST
#ifdef MENU_DEFAULT_DIRECTORY
vl = vlalloc();
vl->hsoname = stcopy(MENU_DEFAULT_DIRECTORY);
vl->host = stcopy(MENU_DEFAULT_HOST);
return vl;
#endif
#endif
#ifndef P_SITE_DIRECTORY
fprintf(stderr,"%s",err_msg_1);
return NULL;
#endif
#ifndef P_SITE_HOST
fprintf(stderr,"%s",err_msg_1);
return NULL;
#endif
vl = vlalloc();
vl->hsoname = stcopy(P_SITE_DIRECTORY);
vl->host = stcopy(P_SITE_HOST);
vdir_init(dir);
if (p_get_dir(vl,P_SITE_MASTER_VSLIST,dir,GVD_FIND,NULL)
!= PSUCCESS)
{
fprintf(stderr,"%s",err_msg_1);
return NULL;
}
vllfree(vl);
vl2 = dir->links;
if (vl2 == NULL) return NULL;
if (p_get_dir(vl2,P_PROTOTYPE_VS,dir,GVD_FIND,NULL)
!= PSUCCESS)
{
fprintf(stderr,"%s",err_msg_1);
return NULL;
}
/* vllfree(vl2); */
vl3 = dir->links;
if (vl3 == NULL) return NULL;
if (p_get_dir(vl3,"ROOT",dir,GVD_FIND,NULL) != PSUCCESS) {
fprintf(stderr,"%s",err_msg_1);
return NULL;
}
/* vllfree(vl3); */
vl4 = dir->links;
if (vl4 == NULL) return NULL;
if (p_get_dir(vl4,"MENU",dir,GVD_FIND,NULL) != PSUCCESS) {
fprintf(stderr,"%s",err_msg_1);
return NULL;
}
/* vllfree(vl4); */
if (dir->links != NULL) return (dir->links);
return NULL;
}
else if (argc == 1) {
vl = rd_vlink(argv[0]);
if (vl == NULL) {
m_error = error_buffer;
sperrmesg(error_buffer,"ERROR: ", 0 ,NULL);
return NULL;
}
return vl;
}
else if (argc == 3) {
argc--;argv++;
vl = vlalloc();
vl -> host = stcopy(argv[0]);
vl -> hsoname = stcopy(argv[1]);
return vl;
}
return NULL;
}
void init_menu(MCS *mc,VLINK first_link) {
VLINK temp;
MCS mcs = (MCS) stalloc(sizeof(struct menu_control_struct));;
if (mcs == NULL) {
fprintf(stderr,"\nOUT OF MEMORY!!!\n\n");
exit(1);
}
temp = first_link;
if (temp == NULL) {
fprintf(stderr,"\nNo initial menu could be found\n\n");
exit(1);
}
mcs->warning = NULL;
*p_warn_string = '\0';
mcs->current = m_get_menu(temp);
if (*p_warn_string)
mcs->warning = tkappend(p_warn_string, mcs->warning);
p_warn_string[0] = '\0';
ck_fatal_err;
mcs->earlier = mcs->later = NULL;
mcs->name_of_parent = stcopy(m_item_description(temp));
ck_fatal_err;
vlfree(temp);
(*mc) = mcs;
}
void get_menu(MCS *mcs,VLINK parent) {
MCS new = (MCS) stalloc(sizeof(struct menu_control_struct));
if (new == NULL) {
fprintf(stderr,"\nOUT OF MEMORY!!!\n\n");
exit(1);
}
(*mcs)->later = new;
new->earlier = (*mcs);
new->name_of_parent = stcopy(m_item_description(parent));
new->later = NULL;
new->warning = NULL;
*p_warn_string = '\0';
new->current = m_get_menu(parent);
if (*p_warn_string)
new->warning = tkappend(p_warn_string, new->warning);
p_warn_string[0] = '\0';
(*mcs) = new;
if (m_error != NULL) {
fprintf(stderr,"%s\n",m_error);
printf("\n\nRepeating previous menu\n");
m_error = NULL; /* clear error flag */
up_menu(mcs);
}
}
void get_search(MCS *mcs,VLINK parent)
{
MCS new = (MCS) stalloc(sizeof(struct menu_control_struct));
if (new == NULL) {
fprintf(stderr,"\nOUT OF MEMORY!!!\n\n");
exit(1);
}
(*mcs)->later = new;
new->warning = NULL;
new->earlier = (*mcs);
new->name_of_parent = stcopy(m_item_description(parent));
new->later = NULL;
new->warning = NULL;
*p_warn_string = '\0';
new->current = open_search(parent);
if (*p_warn_string)
new->warning = tkappend(p_warn_string, (new)->warning);
(*mcs) = new;
p_warn_string[0] = '\0';
if (m_error != NULL) {
fprintf(stderr,"%s\n",m_error);
printf("\n\nRepeating previous menu\n");
m_error = NULL; /* clear error flag */
up_menu(mcs);
}
}
/* Read value from user and return */
int query_choice(MCS *mcs) {
printf("\nPress a number to select a menu item, q to Quit");
if (!top_menu(mcs)) printf(", u to go up a menu");
printf(": ");
return get_top_level_answer();
/*
if (answer[0] == 'q') return -1;
if (answer[0] == 'u') return 0 ;
*/
/*
for (cnt=0;
(isdigit(answer[cnt]))
&& (answer[cnt] != '\0')
&& (answer[cnt]!= '\n')
;
cnt++);
if (answer[cnt] == '\n') answer[cnt] = '\0';
temp = atoi(answer);
if (temp == 0) return -2;
*/
/* If the answer string got to the end that means that all components were
digits and it's a valid number (values that are too high are handled
in return_choice().
*/
/* if (answer[cnt] == '\0') return atoi(answer); */
/* If it ended because there were no digits, then it's invalid. */
/* else return -2; */
}
int top_menu(MCS *mcs) {
if ((*mcs)->earlier == NULL) return 1;
else return 0;
}
void up_menu(MCS *mcs) {
if ((*mcs)->current != NULL) {
vllfree((*mcs)->current);
}
stfree((*mcs)->name_of_parent);
(*mcs) = (*mcs)->earlier;
stfree((*mcs)->later);
(*mcs)->later = NULL;
}
void print_current_menu(MCS *mcs) {
int cnt = 0;
VLINK trans = (*mcs)->current;
char *temp;
int temp_cl;
printf("\n\nMenu for %s\n",(*mcs)->name_of_parent);
if ((*mcs)->warning) {
TOKEN tk;
puts("Got the following warning(s) from Prospero:");
for (tk = (*mcs)->warning; tk; tk = tk->next)
puts(tk->token);
tkfree((*mcs)->warning); (*mcs)->warning = NULL;
}
putchar('\n');
while (trans != NULL) {
temp = m_item_description(trans);
if (!(temp == NULL || trans->linktype == 'I')) {
printf("%4d",++cnt);
if ((temp_cl = m_class(trans)) == M_CLASS_MENU) printf("> ");
else if (temp_cl == M_CLASS_PORTAL) printf("] ");
else if (temp_cl == M_CLASS_SEARCH) printf(": ");
else printf(". ");
printf("%s\n",temp);
}
trans = trans -> next;
}
}
/* Walks linked list of VLINKS and returns link 'ch' (first is 1) */
VLINK return_choice(int ch,MCS *mcs) {
int cnt = 0;
VLINK temp = (*mcs)->current;
do {
if (!(get_item_desc(temp) == NULL || temp->linktype == 'I')) cnt++;
if (cnt != ch) temp = temp -> next;
} while (cnt != ch && temp != NULL);
return temp;
}
int is_empty(MCS *to_check) {
if ((*to_check)->current == NULL) return 1;
else return 0;
}
/* These are not yet implemented; they will soon replace the current
calls to stalloc(). */
#if 0
MCS
mcsalloc(void)
{
}
void
mcsfree(MCS mcs)
{
}
#endif

50
prospero/user/menu/menu.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include "p_menu.h"
struct menu_control_struct {
VLINK current;
char *name_of_parent;
TOKEN warning; /* warning messages received (if any) */
struct menu_control_struct *earlier;
struct menu_control_struct *later;
};
typedef struct menu_control_struct *MCS;
VLINK set_environ(int, char *[]);
void init_menu(MCS *, VLINK);
void print_current_menu(MCS *);
int query_choice(MCS *);
int top_menu(MCS *);
void up_menu(MCS *);
VLINK return_choice(int, MCS *);
void get_menu(MCS *, VLINK);
void get_search(MCS *, VLINK);
int is_empty(MCS *);
/* Files that display data or otherwise deal with it. */
void open_and_display(VLINK);
void open_telnet(VLINK);
VLINK open_search(VLINK);
extern TOKEN get_token(VLINK, char *); /* get_token is defined in objects.c */
extern VLINK vlink_list_sort(VLINK);
extern int get_top_level_answer();
extern MCS mcsalloc(void);
extern void mcsfree(MCS);
#if 0
/* in objects.c. Not currently used, but appears in the library. */
int m_file_has_more_than_95_percent_printing_chars(int fd);
#endif

View File

@@ -0,0 +1,443 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
/*
* Future directions: this code needs to change so that it's internally
* consistent. It should always use popen() or always fork, etc.
Noted. Partially done. See my message. -buess
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h> /* for lseek() */
#include <unistd.h> /* for lseek() */
#include <pfs.h>
#include <stdlib.h> /* For malloc and free */
#include "config.h"
#include "p_menu.h"
#include "menu.h"
char *getenv();
/* We include <pmachine.h> which, on SOLARIS, will make up for deficiencies in
stdio.h (fdopen() undeclared, popen() undeclared. */
#include <pmachine.h>
static void save_file(int fd);
static void mail_file(int fd);
static void pipe_output_to_subprogram(int fd, char *subprogram, char *error_msg);
static void run_subsystem_with_fd_as_stdin(int fd, char *subprogram, char *error_msg);
static int retrieve_link(VLINK vl);
void
open_and_display(VLINK vl)
{
int fd;
int fd_dup;
int get_option();
int option;
static char *pager; /* pager to use */
if (!pager) {
pager = getenv("PAGER");
if (!pager)
pager = "more";
}
fd = retrieve_link(vl); /* retrieve link, print error messages if
failure. */
if (fd < 0) return;
run_subsystem_with_fd_as_stdin(fd,pager,"unable to display file");
/* Finish work after display. */
if(lseek(fd, (off_t) 0, SEEK_SET)) {
fprintf(stderr, "lseek failed: this should never happen.\n");
return;
}
for (;;) {
printf("\n\nPress <RETURN> to continue, <m> to mail, <s> to save, or <p> to print:");
option = get_option();
if (option == -1)
break;
if (option == 's') {
save_file(fd);
break;
} else if (option == 'm') {
mail_file(fd);
break;
} else if (option == 'p') {
run_subsystem_with_fd_as_stdin(fd,PRINT_PROGRAM,
"Unable to print file");
break;
} else
continue;
}
close(fd);
}
/* Pass it an open file descriptor.
It might close it internally (due to the way fdopen() works), but caller
should also run close() just to be sure. */
/* Pass it an open file descriptor.
Caller takes responsibility for closing it.
*/
static
void
save_file(int fd)
{
char *name;
FILE *org_fp;
FILE *save_fp;
int temp = 25;
char *get_line();
printf("\n\nEnter save file name: ");
name = get_line();
if (name == NULL)
return;
save_fp = fopen(name, "w");
while (save_fp == NULL) {
printf("Error opening : Enter new name or <Enter> to cancel: ");
stfree(name);
name = get_line();
save_fp = fopen(name, "w");
}
org_fp = fdopen(fd, "r");
if (org_fp == NULL) {
fprintf(stderr, "\nError retrieving file\n");
return;
}
while (fgetc(org_fp) != EOF) {
if (fputc(temp, save_fp) == EOF) {
fprintf(stderr, "\nError while writing to output file\n");
break;
}
}
/* done; cleanup. */
fclose(save_fp);
fclose(org_fp);
}
/* Pass it an open file descriptor.
It might close it internally (due to the way fdopen() works), but caller
should also run close() just to be sure. */
static
void
mail_file(int fd)
{
char *address;
char *get_line();
static char *command = NULL;
printf("\n\nMail document to:");
fflush(stdout);
address = get_line();
if (address == NULL)
return;
command = qsprintf_stcopyr(command, "%s %s", MAIL_SENDING_PROGRAM, address);
run_subsystem_with_fd_as_stdin(fd,command,"Unable to mail");
}
void
open_telnet(VLINK vl)
{
TOKEN args; /* Used to get access method args. */
char *paren; /* used during parsing. */
char *endparen; /* Used during parsing. */
char *hostpart; /* HOST breaks into host part & port part. */
char *portpart; /* Either NULL or the start of a string whose
numeric interpretation is the appropriate
port. */
int ch_par; /* Used for fork(). */
int tmp; /* Return from subfunctions */
if (pget_am(vl, &args, P_AM_TELNET) != P_AM_TELNET) {
cant_find_am:
fprintf(stderr, "Unable to find an appropriate access method to use \
this portal -- sorry.\n");
return;
}
/* ARGS are guaranteed to be a safe copy for us to work with. */
/* Length guaranteed by pget_am to be at least 5 elements. */
tmp = qsscanf(elt(args, 2), "%r%*[^(]%r(%r%*d%r)", &hostpart, &paren,
&portpart, &endparen);
if (tmp < 1)
goto cant_find_am;
if (tmp >= 2)
*paren = '\0';
if (tmp < 4)
portpart = NULL;
else
*endparen = '\0';
/* HOSTPART and PORTPART are now both correctly set. */
/* display prompt if present and not just the empty string. */
if (elt(args, 5) && *elt(args, 5))
puts(elt(args, 5));
/* Now fork. */
ch_par = fork();
if (ch_par == -1) {
perror("menu: fork() failed");
return;
} else if (ch_par == 0) {
/* CHILD */
if (portpart)
execlp(TELNET_PROGRAM, TELNET_PROGRAM, hostpart, portpart, (char *) 0);
else
execlp(TELNET_PROGRAM, TELNET_PROGRAM, hostpart, (char *) NULL);
/* Only get here if the execlp() failed. */
fprintf(stderr,
"Couldn't run the telnet program \"%s\" -- sorry!\n",
TELNET_PROGRAM);
_exit(1);
} else {
/* Parent */
wait((int *) NULL);
}
}
void
open_data(VLINK vl)
{
/*
int query_save_data();
int fd = retrieve_link(vl);
int fd_dup;
char *n = vl->name;
char *command;
char *tn;
char *to_free;
static int hassuffix(char *,char *);
pid_t pid;
char *dummy_argv[3];
if (hassuffix(n,"Z")) {
tn = tmpnam(NULL);
to_free = (char *)malloc(sizeof(char) * (9+strlen(tn)));
strcpy(to_free,"zcat > ");
strcat(to_free,tn);
pipe_output_to_subprogram(fd,to_free,"Unable to zcat");
stfree(to_free);
close(fd);
}
pid = fork();
if (pid == -1) {
fprintf(stderr, "%s: fork() failed.\n", "Unable to run gs");
return;
}
if (pid == 0) {
dummy_argv[0] = "gs";
dummy_argv[1] = tn;
dummy_argv[2] = NULL;
if (execvp(dummy_argv[0], dummy_argv) == -1) {
fprintf(stderr, "couldn't execute the program %s.\n",
"gs");
_exit(1);
}
_exit(0);
} else {
wait((int *) NULL);
}
*/
/* Original function... */
if (query_save_data()) {
int fd = retrieve_link(vl);
if (fd >= 0) save_file(fd);
}
}
static int
hassuffix(char *name, char *suf)
{
char *lastdot = strrchr(name, '.');
if (lastdot) return strequal(lastdot + 1, suf); /* 1 if true */
else return 0; /* false */
}
#if 0
/* Returns 1 if a file descriptor refers to a file that has more than 95%
printing characters. Note that this code is broken, since it gobbles up the
file you give it and since it is never used and has never been tested.
So we comment it out for now. --swa */
int
m_file_has_more_than_95_percent_printing_chars(int fd)
{
FILE *fp = fdopen(fd,"r");
int num_printing_chars = 0;
int tot_cnt = 0;
int retval;
do {
retval = fgetc(fp);
if (isprint(retval)) num_printing_chars++;
tot_cnt++;
} while (retval != -1 && tot_cnt < 1000);
if (((float) num_printing_chars / tot_cnt) > 0.95)
return 1;
else
return 0;
}
#endif
TOKEN
get_token(VLINK vl, char *which_token)
{
PATTRIB temp;
PATTRIB highest = NULL;
int compare_precedence(char, char); /* defined in comp.c */
TOKEN temp_tok;
if (vl == NULL)
return NULL;
if ((temp = vl->lattrib) == NULL)
return NULL;
while (temp != NULL) {
if (!strcmp(which_token, temp->aname))
if (highest == NULL)
highest = temp;
else if (compare_precedence(highest->precedence, temp->precedence)
== -1)
highest = temp;
temp = temp->next;
} /* while temp != NULL */
if (highest == NULL)
return NULL;
return highest->value.sequence;
}
static
void
pipe_output_to_subprogram(int fd, char *subprogram, char *error_msg)
{
FILE *org_fp;
FILE *output_fp;
int temp = 25;
org_fp = fdopen(fd, "r");
if (org_fp == NULL) {
fprintf(stderr,error_msg);
return;
}
output_fp = popen(subprogram, "w");
if (output_fp == NULL) {
fprintf(stderr,error_msg);
fclose(org_fp);
return;
}
while(fgetc(org_fp) != EOF) {
int err = fputc(temp, output_fp);
if (err == EOF) {
fprintf(stderr,error_msg);
break;
}
}
pclose(output_fp); /* This was corrected from fclose. */
}
static
void
run_subsystem_with_fd_as_stdin(int fd, char *subprogram, char *error_msg)
{
/* char *dummy_argv[2];*/
char *execvp_argv[30]; /* Over 30 parameters would be nuts! */
int argc = 0;
pid_t pid;
int retval;
char *progcopy = stcopy(subprogram);
char *org_pc = progcopy;
memset(execvp_argv,0,sizeof(char *) * 30);
while (qsscanf(progcopy,"%&s",&(execvp_argv[argc]))==1) {
progcopy += strlen(execvp_argv[argc]);
while (isspace(*progcopy)) progcopy++;
argc++;
}
stfree(org_pc);
execvp_argv[argc] = NULL;
pid = fork();
if (pid == -1) {
fprintf(stderr, "%s: fork() failed.\n", error_msg);
return;
}
if (pid == 0) {
/* Child process */
assert(P_IS_THIS_THREAD_MASTER()); /* SOLARIS: dup2 MT-Unsafe */
if (dup2(fd, 0) == -1) {
fprintf(stderr,
"%s: dup2(fd,0) failed. This should *never* happen.\n",
error_msg);
_exit(1);
}
/* dummy_argv[0] = subprogram;
dummy_argv[1] = NULL;
*/
if (execvp(execvp_argv[0], execvp_argv) == -1) {
fprintf(stderr, "%s: couldn't execute the program %s.\n",
error_msg, subprogram);
_exit(1);
}
_exit(0);
} else {
wait((int *) NULL); /* wait for child */
}
}
static
int
retrieve_link(VLINK vl)
{
int fd; /* return value */
printf("\nRetrieving %s...", m_item_description(vl));
fflush(stdout);
fd = m_open_file(vl);
if (fd < 0) {
puts("retrieval failed.");
} else {
puts("done.");
}
return fd;
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
void open_and_display(VLINK);
void save_file (VLINK);
void print_file (VLINK);
void mail_file (VLINK);
void open_telnet(VLINK);
void open_search(VLINK);

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 1993 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-copyr.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
*/
#include <usc-copyr.h>
#include <pfs.h>
#define M_CLASS_UNKNOWN 0
#define M_CLASS_MENU 1
#define M_CLASS_DOCUMENT 2
#define M_CLASS_PORTAL 4
#define M_CLASS_SEARCH 8
#define M_CLASS_DATA 16
#define M_CLASS_IMAGE 32
VLINK m_top_menu(void);
VLINK m_get_menu(VLINK);
int m_open_file(VLINK);
FILE *m_fopen_file(VLINK);
char *m_item_description(VLINK);
TOKEN m_interpretation(VLINK);
int m_class(VLINK);
extern char *m_error;

320
prospero/user/menu/search.c Normal file
View File

@@ -0,0 +1,320 @@
/*
* Copyright (c) 1991-1994 by the University of Southern California
*
* For copying and distribution information, please see the file
* <usc-license.h>.
*
* The menu API and client were written by Kwynn Buess (buess@isi.edu)
* Extensive modifications by Steven Augart (swa@ISI.EDU)
*/
#include <usc-license.h>
#include <usc-copyr.h>
#include <pfs.h>
#include <string.h>
#include "menu.h"
#include "p_menu.h"
struct q_arg_list {
char *name;
char *value;
struct q_arg_list *next;
};
typedef struct q_arg_list *QAL;
void display_query_doc(char*,PATTRIB);
char *return_arg_default(PATTRIB);
static TOKEN replace_args(TOKEN,QAL);
static char *replace_arg(TOKEN,QAL);
/* Returns a linked list of VLINKs. In case of error, display a message and
return null. */
VLINK
open_search(VLINK vl)
{
TOKEN q_tok = get_token(vl,"QUERY-METHOD");
QAL alist;
QAL get_query_args(TOKEN);
void fill_query_args(QAL,PATTRIB);
VDIR_ST dir_st;
VDIR dir = &dir_st;
TOKEN acomp;
VLINK retval; /* value to return. */
int tmp; /* return from p_get_dir() */
m_error = NULL; /* no error right now. */
if(q_tok && (q_tok->token)) display_query_doc(q_tok->token,vl->lattrib);
alist = get_query_args(q_tok);
fill_query_args(alist,vl->lattrib);
acomp = replace_args((q_tok->next ? q_tok->next->next : NULL),alist);
vdir_init(dir);
tmp = p_get_dir(vl,replace_arg(q_tok->next,alist),dir,0,&acomp);
if (tmp) {
perrmesg("Couldn't complete search:", 0, (char *) NULL);
printf("\n\nRepeating previous menu\n");
vdir_freelinks(dir);
retval = NULL;
goto cleanup;
}
retval = dir->links; dir->links = NULL;
vdir_freelinks(dir);
/* alist is a list of QAL's not freed on exit !!*/
cleanup:
tklfree(acomp); /* Was a nasty memory leak */
return retval;
}
static TOKEN
replace_args(TOKEN fill, QAL alist)
{
TOKEN ttok;
char *tstr;
if(!fill) return(NULL);
tstr = replace_arg(fill, alist);
ttok = tkalloc(NULL);
ttok->token = tstr;
ttok->next = replace_args(fill->next, alist);
return(ttok);
}
static char *
replace_arg(TOKEN fill, QAL alist)
{
TOKEN temp_fill_next;
QAL temp_al;
int size = 0;
char *the_arg;
int cnt_the,cnt_fill;
int done = 0;
char *close_br;
char *temp_value;
char *get_value(char *,QAL);
TOKEN new_token;
char *copy, *startcopy;
char *head;
if (fill == NULL) return(NULL);
if (fill->token == NULL) return(NULL);
startcopy = copy = stcopy(fill->token);
temp_al = alist;
while (temp_al != NULL) {
size += strlen(temp_al->value) + 1;
temp_al = temp_al->next;
}
size += strlen(copy);
head = the_arg = (char *)stalloc(sizeof(char) * size);
cnt_the = cnt_fill = 0;
while (!done) {
if (*copy == '$') {
if (*(copy +cnt_fill + 1) == '{'
&& *(copy + cnt_fill - 1) != '$')
{
copy += 2;
close_br = strchr(copy,'}');
*close_br = '\0';
temp_value = get_value(copy,alist);
*the_arg = '\0';
strcat(the_arg,temp_value);
the_arg += strlen(temp_value);
copy = close_br + 1;
continue;
}
else {
*the_arg++ = *copy++;
if (*(the_arg - 1) == '\0') done = 1;
}
}
else {
*the_arg++ = *copy++;
if (*(the_arg - 1) == '\0') done = 1;
}
}
/* Nasty memory leak - copy is at the end of the string*/
stfree(startcopy);
return(head);
}
char *
get_value(char *to_cmp, QAL list)
{
QAL temp = list;
while (temp != NULL) {
if (!strcmp(to_cmp,temp->name)) return temp->value;
temp = temp->next;
}
return NULL;
}
/* Interact with user to fill arguments to query */
void fill_query_args(QAL to_fill,PATTRIB all_attribs) {
QAL temp_tok = to_fill; /* Note temp_tok is not a TOKEN */
PATTRIB temp_atr = all_attribs;
char *get_line();
if (temp_tok == NULL) return;
if (all_attribs == NULL) return;
while (temp_tok != NULL) { /* Over all the to_fill structure */
temp_atr = all_attribs; /* Reset to look at head of pattribs */
/* Redundantly set at end of loop as well */
while (temp_atr != NULL) {
if (!strcmp(temp_atr->aname,"QUERY-ARGUMENT")) {
/* If attribute is QUERT-ARGUMENT matching this temp_tok */
if ((temp_atr->value.sequence != NULL) &&
(!strcmp(temp_atr->value.sequence->token,temp_tok->name))) {
enter_again: /* Lazy code - should be a while loop with break*/
printf("%s: ",temp_atr->value.sequence->next->token);
temp_tok->value = get_line();
if(!temp_tok->value || !*(temp_tok->value)) {
char *defval;
if(temp_tok->value) stfree(temp_tok->value);
/* Get default or tryagain */
defval = return_arg_default(temp_atr);
if(!defval) {
display_query_doc(temp_atr->value.sequence->token,
all_attribs);
goto enter_again;
}
temp_tok->value = stcopy(defval);
}
else if(strequal(temp_tok->value,"?")) {
display_query_doc(temp_atr->value.sequence->token,all_attribs);
stfree(temp_tok->value); temp_tok->value = NULL;
goto enter_again;
}
else if(*(temp_tok->value) == '\\') {
char *tptr;
tptr = stcopy((temp_tok->value)+1);
stfree(temp_tok->value);
temp_tok->value = tptr;
}
}
}
temp_atr = temp_atr -> next;
}
temp_tok = temp_tok->next;
temp_atr = all_attribs;
}
}
void display_query_doc(char *which,PATTRIB all_attribs)
{
PATTRIB temp_atr = all_attribs;
char *paren = strchr(which,'(');
while (temp_atr != NULL) {
if (!strcmp(temp_atr->aname,"QUERY-DOCUMENTATION"))
if (temp_atr->value.sequence != NULL)
if((paren && !strncmp(temp_atr->value.sequence->token,which,
paren - which)) ||
(!paren && !strcmp(temp_atr->value.sequence->token,which))){
printf("\n%s\n\n",temp_atr->value.sequence->next->token);
}
temp_atr = temp_atr -> next;
}
}
char *return_arg_default(PATTRIB qarg)
{
TOKEN element;
int count = 1;
if(!qarg) return(NULL);
if (!strequal(qarg->aname,"QUERY-ARGUMENT")) return (NULL);
element = qarg->value.sequence;
while(element) {
if(count++ == 6) return(element->token);
element = element->next;
}
return(NULL);
}
QAL get_query_args(TOKEN seq) {
char *func;
char *t_comma;
char *t2;
int done_loop = 0;
int args;
char *end_arg;
QAL head,current,chaser;
if (seq == NULL) return NULL;
if (seq->token == NULL) return NULL;
func = stcopy(seq->token);
t_comma = strchr(func,'(');
if (t_comma == NULL) return NULL;
else t_comma++;
if (strchr(t_comma,',') == NULL) { /* Determine whether there are any args */
done_loop = 0;
args = 0;
t2 = t_comma;
while (!done_loop) {
t2++;
if (*t2 == '\0' || *t2 == ')' || args) done_loop = 1;
if (!done_loop)
if (!(isspace(*t2) || *t2 == ')' || *t2 == '\0')) args = 1;
}
if (!args) return NULL;
}
head = (QAL) stalloc(sizeof(struct q_arg_list));
head->next = NULL;
head->value = NULL;
end_arg = strchr(t_comma,',');
if (end_arg == NULL) end_arg = strchr(t_comma,')');
*end_arg = '\0';
head->name = stcopy(t_comma);
t_comma = end_arg + 1;
chaser = head;
while (!done_loop) {
end_arg = strchr(t_comma,',');
if (end_arg == NULL) {
end_arg = strchr(t_comma,')');
done_loop = 1;
}
current = (QAL) stalloc(sizeof(struct q_arg_list));
current->next = NULL;
current->value = NULL;
*end_arg = '\0';
current->name = stcopy(t_comma);
chaser->next = current;
chaser = current;
t_comma = end_arg + 1;
}
stfree(func);
return head;
}