Intial commit
This commit is contained in:
1
prospero/user/menu/.gitignore
vendored
Normal file
1
prospero/user/menu/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Makefile
|
||||
16
prospero/user/menu/FILES
Normal file
16
prospero/user/menu/FILES
Normal 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
87
prospero/user/menu/Makefile.in
Executable 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
253
prospero/user/menu/api.c
Normal 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
75
prospero/user/menu/bub.c
Normal 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
231
prospero/user/menu/comp.c
Normal 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;
|
||||
}
|
||||
40
prospero/user/menu/config.h
Normal file
40
prospero/user/menu/config.h
Normal 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
|
||||
|
||||
144
prospero/user/menu/io_util.c
Normal file
144
prospero/user/menu/io_util.c
Normal 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;
|
||||
}
|
||||
57
prospero/user/menu/item_desc.c
Normal file
57
prospero/user/menu/item_desc.c
Normal 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
52
prospero/user/menu/line.c
Normal 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
104
prospero/user/menu/main.c
Normal 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
327
prospero/user/menu/menu.c
Normal 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
50
prospero/user/menu/menu.h
Normal 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
|
||||
443
prospero/user/menu/objects.c
Normal file
443
prospero/user/menu/objects.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
19
prospero/user/menu/objects.h
Normal file
19
prospero/user/menu/objects.h
Normal 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);
|
||||
32
prospero/user/menu/p_menu.h
Normal file
32
prospero/user/menu/p_menu.h
Normal 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
320
prospero/user/menu/search.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user