home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE0.TAR / xarchie.c.bug < prev    next >
Encoding:
Text File  |  1991-08-29  |  16.4 KB  |  590 lines

  1. /*
  2.  * xarchie : An X browser interface to Archie
  3.  *
  4.  * This file is sort of a mishmash of functions, some of which might get
  5.  * sorted out later. Its primary purpose is to establish the X connection,
  6.  * create the application's widgets, call any other other necessary
  7.  * initialization routines, and enter XtAppMainLoop(). It also provides
  8.  * the callback procedure selectItem() that makes the List widgets work
  9.  * like a browser (in collaboration with the display routines in db.c).
  10.  * Finally, it provides the generic setText(), setLabel(), and status*()
  11.  * routines which could go just about anywhere.
  12.  *
  13.  * George Ferguson, ferguson@cs.rochester.edu, 21 Aug 1991.
  14.  *
  15.  */
  16. #include <stdio.h>
  17. #include <signal.h>
  18. #include <sys/time.h>
  19. #include <X11/Intrinsic.h>
  20. #include <X11/StringDefs.h>
  21. #include <X11/Shell.h>    
  22. #include <X11/Xaw/Paned.h>    
  23. #include <X11/Xaw/Viewport.h>    
  24. #include <X11/Xaw/List.h>    
  25. #include <X11/Xaw/Form.h>    
  26. #include <X11/Xaw/Box.h>
  27. #include <X11/Xaw/Label.h>    
  28. #include <X11/Xaw/AsciiText.h>    
  29. #include <X11/Xaw/Command.h>    
  30. #include <X11/Xaw/Cardinals.h>    
  31. #include "types.h"
  32. #include "appres.h"
  33. #include "classnames.h"
  34. #include "db.h"
  35. #include "actions.h"
  36. #include "patchlevel.h"
  37.  
  38. /*    -    -    -    -    -    -    -    -    */
  39. /*
  40.  * Functions defined in this file:
  41.  */
  42. int main();
  43. void doPendingEvents();
  44. void initWidgetsFromString();
  45. void displayHostInfo(), clearHostInfo();
  46. void displayLocationInfo(), clearLocationInfo();
  47. void displayFileInfo(), clearFileInfo();
  48. void setText(), setLabel();
  49. void status0(), status1(), status2();
  50. void fail0(), fail1();
  51.  
  52. static void initGraphics(), initWidgets();
  53. static void selectItem();
  54. static void syntax();
  55.  
  56. /*
  57.  * Global graphics data
  58.  */
  59. Display *display;
  60. Screen *screen;
  61. Window root;
  62.  
  63. /*
  64.  * Global widget data
  65.  */
  66. XtAppContext appContext;
  67. Widget toplevel;
  68. Widget hostList,locationList,fileList;
  69. Widget searchText;
  70.  
  71. static Widget statusText;
  72. static Widget hostText,locationText,fileText,sizeText,modesText,dateText;
  73.  
  74. /*
  75.  * Other global data
  76.  */
  77. Database *db;
  78. char *progname;
  79.  
  80. /*
  81.  * The application resources
  82.  */
  83. AppResources appResources;
  84.  
  85. /*
  86.  * Non-widget resources obtained from resource manager
  87.  */
  88. static XtResource resources[] = {
  89.     { "widgets", "Widgets", XtRString, sizeof(String),
  90.       XtOffset(AppResources *,widgets), XtRImmediate, "" },
  91. #ifdef DEC_MIPS_BUG
  92. /* If we're handling the buggy Dec/MIPS thing, then we make the "searchType"
  93.  * and "sortType" resources set string values, and convert them by hand
  94.  * after they have been read by XtGetApplicationResources().
  95.  */
  96.     { "searchType", "SearchType", XtRString, sizeof(String),
  97.       XtOffset(AppResources *,searchTypeStr), XtRImmediate,
  98.                             (XtPointer)"exact" },
  99.     { "sortType", "SortType", XtRString, sizeof(String),
  100.       XtOffset(AppResources *,sortTypeStr), XtRImmediate,
  101.                             (XtPointer)"default" },
  102. #else /* !defined(DEC_MIPS_BUG) */
  103. /* Otherwise, we let the built-in converter handle them during the initial
  104.  * XtGetApplicationResources() call.
  105.  */
  106.     { "searchType", "SearchType", GfRSearchType, sizeof(SearchType),
  107.       XtOffset(AppResources *,searchType), XtRImmediate, (XtPointer)GfExact },
  108.     { "sortType", "SortType", GfRSortType, sizeof(SortType),
  109.       XtOffset(AppResources *,sortType), XtRImmediate, (XtPointer)GfDefault },
  110. #endif /* DEC_MIPS_BUG */
  111.     { "archieHost", "ArchieHost", XtRString, sizeof(String),
  112.       XtOffset(AppResources *,archieHost), XtRImmediate, "archie.mcgill.ca" },
  113.     { "maxHits", "MaxHits", XtRInt, sizeof(int),
  114.       XtOffset(AppResources *,maxHits), XtRImmediate, (XtPointer)99 },
  115.     { "offset", "Offset", XtRInt, sizeof(int),
  116.       XtOffset(AppResources *,offset), XtRImmediate, (XtPointer)0 },
  117.     { "timeout", "Timeout", XtRInt, sizeof(int),
  118.       XtOffset(AppResources *,timeout), XtRImmediate, (XtPointer)0 },
  119.     { "retries", "Retries", XtRInt, sizeof(int),
  120.       XtOffset(AppResources *,retries), XtRImmediate, (XtPointer)0 },
  121.     { "niceLevel", "NiceLevel", XtRInt, sizeof(int),
  122.       XtOffset(AppResources *,niceLevel), XtRImmediate, (XtPointer)0 },
  123.     { "debugLevel", "DebugLevel", XtRInt, sizeof(int),
  124.       XtOffset(AppResources *,debugLevel), XtRImmediate, (XtPointer)0 },
  125.     { "settingsWidgets", "SettingsWidgets", XtRString, sizeof(String),
  126.       XtOffset(AppResources *,settingsWidgets), XtRImmediate, "" },
  127. };
  128.  
  129. /*
  130.  * Non-widget resources set on command line.
  131.  */
  132. static XrmOptionDescRec options[] = {
  133.     { "-search",  ".searchType", XrmoptionSepArg, (XtPointer)"exact" },
  134.     { "-e",      ".searchType", XrmoptionNoArg,  (XtPointer)"exact" },
  135.     { "-s",      ".searchType", XrmoptionNoArg,  (XtPointer)"substr" },
  136.     { "-c",      ".searchType", XrmoptionNoArg,  (XtPointer)"subcase" },
  137.     { "-r",      ".searchType", XrmoptionNoArg,  (XtPointer)"regexp" },
  138.     { "-es",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactSubstr" },
  139.     { "-ec",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactSubcase" },
  140.     { "-er",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactRegexp" },
  141.     { "-sort",    ".sortType",     XrmoptionSepArg, (XtPointer)"default" },
  142.     { "-t",      ".sortType",     XrmoptionNoArg,  (XtPointer)"invdate" },
  143.     { "-host",      ".archieHost", XrmoptionSepArg,
  144.                     (XtPointer)"archie.mcgill.ca" },
  145.     { "-maxhits", ".maxHits",     XrmoptionSepArg, (XtPointer)"99" },
  146.     { "-offset",  ".offset",     XrmoptionSepArg, (XtPointer)"0" },
  147.     { "-nice",    ".niceLevel",     XrmoptionSepArg, (XtPointer)"0" },
  148.     { "-N",       ".niceLevel",     XrmoptionSepArg, (XtPointer)"0" },
  149.     { "-debug",      ".debugLevel", XrmoptionNoArg,  (XtPointer)"1" },
  150.     { "-D",      ".debugLevel", XrmoptionSepArg, (XtPointer)"1" },
  151. };
  152.  
  153. /*
  154.  * Widget and non-widget resources if the application defaults
  155.  * file can't be found.
  156.  * Generated automatically from Xarchie.ad by "ad2c".
  157.  * Comment out the include line (but not the NULL) if you don't want
  158.  * any resources compiled in.
  159.  */
  160. static String fallbackResources[] = {
  161. #include "Xarchie.ad.h"
  162.     NULL
  163. };
  164.  
  165. /*    -    -    -    -    -    -    -    -    */
  166.  
  167. main(argc,argv)
  168. int argc;
  169. char **argv;
  170. {
  171.     char buf[32];
  172.  
  173.     progname = argv[0];
  174.     initGraphics(&argc,argv);
  175.     if (argc > 1) {
  176.     syntax(argc,argv);
  177.     XtDestroyApplicationContext(appContext);
  178.     exit(1);
  179.     }
  180.     initWidgets();
  181.     XtRealizeWidget(toplevel);
  182.     /* Set window title to indicate version */
  183.     sprintf(buf,"xarchie %d.%d",xarchieMajorVersion,xarchieMinorVersion);
  184.     XStoreName(display,XtWindow(toplevel),buf);
  185.     sprintf(buf,"Welcome to xarchie %d.%d",xarchieMajorVersion,
  186.                             xarchieMinorVersion);
  187.     status0(buf);
  188.     /* get the data structure for responses */
  189.     db = newDb();
  190.     /* do it */
  191.     XtAppMainLoop(appContext);
  192.     /*NOTREACHED*/
  193. }
  194.  
  195. void
  196. doPendingEvents()
  197. {
  198.     while (XtAppPending(appContext))
  199.     XtAppProcessEvent(appContext,XtIMAll);
  200. }
  201.  
  202. static void
  203. initGraphics(argcp,argv)
  204. int *argcp;
  205. char **argv;
  206. {
  207.     toplevel = XtAppInitialize(&appContext, "Xarchie",
  208.                    options, XtNumber(options),
  209.                    argcp,argv,fallbackResources,NULL,ZERO);
  210.     initConverters(appContext);
  211.     XawSimpleMenuAddGlobalActions(appContext);
  212.     XtAppAddActions(appContext,actionTable,XtNumber(actionTable));
  213.     XtGetApplicationResources(toplevel,(XtPointer)&appResources,
  214.                               resources,XtNumber(resources),NULL,ZERO);
  215.     display = XtDisplay(toplevel);
  216.     screen = XtScreen(toplevel);
  217.     root = RootWindowOfScreen(screen);
  218. #ifdef DEC_MIPS_BUG
  219. /* If we're handling the buggy Dec/MIPS thing, then we need to convert
  220.  * the string forms of the searchType and sortType resources to their
  221.  * proper forms.
  222.  */
  223.     {
  224.     XrmValue from,to;
  225.  
  226.     from.addr = appResources.searchTypeStr;
  227.     from.size = strlen(from.addr)+1;
  228.     to.addr = NULL;
  229.     XtConvertAndStore(toplevel,XtRString,&from,GfRSearchType,&to);
  230.     if (to.addr != NULL)
  231.         appResources.searchType = ((SearchType)(*(to.addr)));
  232.     from.addr = appResources.sortTypeStr;
  233.     from.size = strlen(from.addr)+1;
  234.     to.addr = NULL;
  235.     XtConvertAndStore(toplevel,XtRString,&from,GfRSortType,&to);
  236.     if (to.addr != NULL)
  237.         appResources.sortType = ((SortType)(*(to.addr)));
  238.     }
  239. #endif /* DEC_MIPS_BUG */
  240. }
  241.  
  242. /*
  243.  * initWidgets: Initialize the widgets given in the .widgets resource,
  244.  *    check for required widgets, and set globals vars.
  245.  */
  246. static void
  247. initWidgets()
  248. {
  249.     initWidgetsFromString(appResources.widgets,".widgets");
  250.     /* check for the necessary widgets and set the global variables */
  251.     if ((hostList=XtNameToWidget(toplevel,"*hostList")) == NULL)
  252.     fail0("didn't create widget \"hostList\"");
  253.     if ((locationList=XtNameToWidget(toplevel,"*locationList")) == NULL)
  254.     fail0("didn't create widget \"locationList\"");
  255.     if ((fileList=XtNameToWidget(toplevel,"*fileList")) == NULL)
  256.     fail0("didn't create widget \"fileList\"");
  257.     if ((searchText=XtNameToWidget(toplevel,"*searchText")) == NULL)
  258.     fail0("didn't create widget \"searchText\"");
  259.     /* set globals for optional widgets */
  260.     statusText = XtNameToWidget(toplevel,"*statusText");
  261.     hostText = XtNameToWidget(toplevel,"*hostText");
  262.     locationText = XtNameToWidget(toplevel,"*locationText");
  263.     fileText = XtNameToWidget(toplevel,"*fileText");
  264.     sizeText = XtNameToWidget(toplevel,"*sizeText");
  265.     modesText = XtNameToWidget(toplevel,"*modesText");
  266.     dateText = XtNameToWidget(toplevel,"*dateText");
  267.     /* make the lists behave like a browser should */
  268.     XtAddCallback(hostList,XtNcallback,selectItem,(XtPointer)1);
  269.     XtAddCallback(locationList,XtNcallback,selectItem,(XtPointer)2);
  270.     XtAddCallback(fileList,XtNcallback,selectItem,(XtPointer)3);
  271.     /* since Xaw is so bloody stupid... */
  272.     clearList(hostList);
  273.     clearList(locationList);
  274.     clearList(fileList);
  275. }
  276.  
  277. #define ISSPACE(c)    ((c) == ' ' || (c) == '\t' || (c) == '\n')
  278. #define NUL        '\0'
  279.  
  280. /*
  281.  * initWidgetsFromString : Create the widgets specified in resourceStr as
  282.  *    "parent class name" triples. The resourceName is used for
  283.  *    error messages.
  284.  */
  285. void
  286. initWidgetsFromString(resourceStr,resourceName)
  287. char *resourceStr,*resourceName;
  288. {
  289.     char name[32],class[32],parent[256];
  290.     char *s,*t;
  291.     Boolean isShell;
  292.     WidgetClass wc;
  293.     Widget pw;
  294.  
  295.     if ((s=resourceStr) == NULL)
  296.     fail1("no widgets specified in %s resource!",resourceName);
  297.     while (*s) {
  298.     /* skip leading whitespace */
  299.         while (ISSPACE(*s))
  300.             s += 1;
  301.     if (!*s)
  302.         break;
  303.     /* Gather the parent widget name */
  304.         t = parent;
  305.         while (*s && !ISSPACE(*s))
  306.             *t++ = *s++;
  307.         *t = NUL;
  308.     /* skip whitespace */
  309.         while (isspace(*s))
  310.             s += 1;
  311.     if (!*s)
  312.         fail1("missing widget class and name in %s resource",resourceName);
  313.     /* Gather the class name */
  314.         t = class;
  315.         while (*s && !ISSPACE(*s))
  316.             *t++ = *s++;
  317.         *t = NUL;
  318.     /* skip whitespace */
  319.         while (isspace(*s))
  320.             s += 1;
  321.     if (!*s)
  322.         fail1("missing widget name in %s resource",resourceName);
  323.     /* Gather the widget's name */
  324.         t = name;
  325.         while (*s && !ISSPACE(*s))
  326.             *t++ = *s++;
  327.         *t = NUL;
  328.     /* convert class name to WidgetClass */
  329.         if ((wc=classNameToWidgetClass(class,&isShell)) == NULL)
  330.         fail1("can't convert string \"%s\" to widgetClass",class);
  331.     /* convert parent name to Widget */
  332.     if (strcmp(parent,"toplevel") == 0)
  333.         pw = toplevel;
  334.     else if ((pw=XtNameToWidget(toplevel,parent)) == NULL)
  335.         fail1("can't convert string \"%s\" to widget",parent);
  336.     /* finally create the widget */
  337.     if (isShell)
  338.             (void)XtCreatePopupShell(name,wc,pw,NULL,ZERO);
  339.         else
  340.             (void)XtCreateManagedWidget(name,wc,pw,NULL,ZERO);
  341.     }
  342. }
  343.  
  344. /*    -    -    -    -    -    -    -    -    */
  345. /* Callback procedures */
  346.  
  347. /*ARGSUSED*/
  348. static void
  349. selectItem(w,closure,call_data)
  350. Widget w;
  351. XtPointer closure,call_data;
  352. {
  353.     XawListReturnStruct *item = (XawListReturnStruct*)call_data;
  354.  
  355.     switch ((int)closure) {
  356.     case 1 :
  357.         if (selectedHostEntry &&
  358.         findHostIndexFromEntry(selectedHostEntry) == item->list_index) {
  359.         XawListUnhighlight(hostList);
  360.         clearFileInfo();
  361.         clearList(fileList);
  362.         clearLocationInfo();
  363.         clearList(locationList);
  364.         clearHostInfo();
  365.         selectedHostEntry = HOST_NULL;
  366.         } else {
  367.         selectedHostEntry = findHostEntryFromIndex(item->list_index,
  368.                                db);
  369.         displayHostInfo(selectedHostEntry);
  370.         displayLocs(selectedHostEntry);
  371.         }
  372.         break;
  373.     case 2 :
  374.         if (selectedLocEntry &&
  375.         findLocIndexFromEntry(selectedLocEntry) == item->list_index) {
  376.         XawListUnhighlight(locationList);
  377.         clearFileInfo();
  378.         clearList(fileList);
  379.         clearLocationInfo();
  380.         selectedLocEntry = LOC_NULL;
  381.         } else {
  382.         selectedLocEntry = findLocEntryFromIndex(item->list_index,
  383.                              selectedHostEntry);
  384.         displayLocationInfo(selectedLocEntry);
  385.         displayFiles(selectedLocEntry);
  386.         }
  387.         break;
  388.     case 3 :
  389.         if (selectedFileEntry &&
  390.         findFileIndexFromEntry(selectedFileEntry) == item->list_index) {
  391.         XawListUnhighlight(fileList);
  392.         clearFileInfo();
  393.         selectedFileEntry = FILE_NULL;
  394.         } else {
  395.         selectedFileEntry = findFileEntryFromIndex(item->list_index,
  396.                                selectedLocEntry);
  397.         displayFileInfo(selectedFileEntry);
  398.         }
  399.         break;
  400.     }
  401. }
  402.  
  403. /*    -    -    -    -    -    -    -    -    */
  404.  
  405. void
  406. displayHostInfo(hostp)
  407. HostEntry *hostp;
  408. {
  409.     if (hostText != NULL)
  410.     setText(hostText,hostp->hostname);
  411. }
  412.  
  413. void
  414. clearHostInfo()
  415. {
  416.     if (hostText != NULL)
  417.     setText(hostText,"");
  418. }
  419.  
  420. void
  421. displayLocationInfo(locp)
  422. LocEntry *locp;
  423. {
  424.     if (locationText != NULL)
  425.     setText(locationText,locp->linkpath);
  426. }
  427.  
  428. void
  429. clearLocationInfo()
  430. {
  431.     if (locationText != NULL)
  432.     setText(locationText,"");
  433. }
  434.  
  435. void
  436. displayFileInfo(filep)
  437. FileEntry *filep;
  438. {
  439.     char buf[16];
  440.  
  441.     if (fileText != NULL)
  442.     setText(fileText,filep->name);
  443.     if (sizeText != NULL) {
  444.     sprintf(buf,"%d",filep->size);
  445.     setText(sizeText,buf);
  446.     }
  447.     if (modesText != NULL)
  448.     setText(modesText,filep->modes);
  449.     if (sizeText != NULL)
  450.     setText(dateText,filep->date);
  451. }
  452.  
  453. void
  454. clearFileInfo()
  455. {
  456.     if (fileText != NULL)
  457.     setText(fileText,"");
  458.     if (sizeText != NULL)
  459.     setText(sizeText,"");
  460.     if (modesText != NULL)
  461.     setText(modesText,"");
  462.     if (dateText != NULL)
  463.     setText(dateText,"");
  464. }
  465.  
  466. /*    -    -    -    -    -    -    -    -    */
  467. /*
  468.  * setText() : Set the given Text item's value to the given string.
  469.  */
  470. void
  471. setText(item,text)
  472. Widget item;
  473. char *text;
  474. {
  475.     Arg args[1];
  476.  
  477.     if (item != NULL) {
  478.     XtSetArg(args[0],XtNstring,text);
  479.     XtSetValues(item,args,ONE);
  480.     }
  481. }
  482.  
  483. /*
  484.  * setLabel() : Set the given Label item's value to the given string.
  485.  */
  486. void
  487. setLabel(item,text)
  488. Widget item;
  489. char *text;
  490. {
  491.     Arg args[1];
  492.  
  493.     if (item != NULL) {
  494.     XtSetArg(args[0],XtNlabel,text);
  495.     XtSetValues(item,args,ONE);
  496.     }
  497. }
  498.  
  499. /*    -    -    -    -    -    -    -    -    */
  500.  
  501. void
  502. status0(str)
  503. char *str;
  504. {
  505.     if (statusText != NULL)
  506.     setText(statusText,str);
  507.     doPendingEvents();
  508. }
  509.  
  510. void
  511. status1(fmt,arg)
  512. char *fmt,*arg;
  513. {
  514.     char buf[256];
  515.  
  516.     sprintf(buf,fmt,arg);
  517.     status0(buf);
  518. }
  519.  
  520. void
  521. status2(fmt,arg1,arg2)
  522. char *fmt,*arg1,*arg2;
  523. {
  524.     char buf[256];
  525.  
  526.     sprintf(buf,fmt,arg1,arg2);
  527.     status0(buf);
  528. }
  529.  
  530. /*    -    -    -    -    -    -    -    -    */
  531.  
  532. void
  533. fail0(str)
  534. char *str;
  535. {
  536.     fprintf(stderr,"%s: %s\n",progname,str);
  537.     XtDestroyApplicationContext(appContext);
  538.     exit(1);
  539. }
  540.  
  541. void
  542. fail1(fmt,arg)
  543. char *fmt,*arg;
  544. {
  545.     char buf[256];
  546.  
  547.     sprintf(buf,fmt,arg);
  548.     fail0(buf);
  549. }
  550.  
  551. /*    -    -    -    -    -    -    -    -    */
  552. /*
  553.  * syntax() : Print whatever caused the error and the usage message.
  554.  */
  555. static void
  556. syntax(argc,argv)
  557. int argc;
  558. char **argv;
  559. {
  560.     char *program;
  561.  
  562.     program = *argv;
  563.     argv += 1;
  564.     if (argc > 2 || (strcmp(*argv,"-help") != 0 && strcmp(*argv,"-?") != 0)) {
  565.     fprintf(stderr,"%s: bad argument(s): ",program);
  566.     while (--argc)
  567.         fprintf(stderr,"%s ",*argv++);
  568.     fprintf(stderr,"\n");
  569.     }
  570.     fprintf(stderr,"Valid options (in addition to X Toolkit options) are:\n");
  571.     fprintf(stderr,"  -search type\tset query type\n");
  572.     fprintf(stderr,"  -e\t\tset query type to exact\n");
  573.     fprintf(stderr,"  -c\t\tset query type to subcase\n");
  574.     fprintf(stderr,"  -s\t\tset query type to substr\n");
  575.     fprintf(stderr,"  -r\t\tset query type to regexp\n");
  576.     fprintf(stderr,"  -ec\t\tset query type to exactSubcase\n");
  577.     fprintf(stderr,"  -es\t\tset query type to exactSubstr\n");
  578.     fprintf(stderr,"  -er\t\tset query type to exactRegexp\n");
  579.     fprintf(stderr,"  -sort type\tset sort mode\n");
  580.     fprintf(stderr,"  -t\t\tset sort mode to invdate\n");
  581.     fprintf(stderr,"  -host host\tconnect to Archie at host\n");
  582.     fprintf(stderr,"  -maxHits num\tset maximum number of matches per query\n");
  583.     fprintf(stderr,"  -offset off\tset Prospero offset\n");
  584.     fprintf(stderr,"  -[nice|N] level\tset query niceness\n");
  585.     fprintf(stderr,"  -[debug|D] level\tset Prospero debugging level\n");
  586.     fprintf(stderr,"  -help\t\tprint this message\n");
  587.     fprintf(stderr,"  -xrm 'resource: value'  pass arbitrary resources\n");
  588.     fprintf(stderr,"Options can be abbreviated to their shortest unique prefix.\n");
  589. }
  590.