home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE0.TAR / xarchie.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-29  |  15.0 KB  |  552 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.     { "searchType", "SearchType", GfRSearchType, sizeof(SearchType),
  92.       XtOffset(AppResources *,searchType), XtRImmediate, (XtPointer)GfExact },
  93.     { "sortType", "SortType", GfRSortType, sizeof(SortType),
  94.       XtOffset(AppResources *,sortType), XtRImmediate, (XtPointer)GfDefault },
  95.     { "archieHost", "ArchieHost", XtRString, sizeof(String),
  96.       XtOffset(AppResources *,archieHost), XtRImmediate, "archie.mcgill.ca" },
  97.     { "maxHits", "MaxHits", XtRInt, sizeof(int),
  98.       XtOffset(AppResources *,maxHits), XtRImmediate, (XtPointer)99 },
  99.     { "offset", "Offset", XtRInt, sizeof(int),
  100.       XtOffset(AppResources *,offset), XtRImmediate, (XtPointer)0 },
  101.     { "timeout", "Timeout", XtRInt, sizeof(int),
  102.       XtOffset(AppResources *,timeout), XtRImmediate, (XtPointer)0 },
  103.     { "retries", "Retries", XtRInt, sizeof(int),
  104.       XtOffset(AppResources *,retries), XtRImmediate, (XtPointer)0 },
  105.     { "niceLevel", "NiceLevel", XtRInt, sizeof(int),
  106.       XtOffset(AppResources *,niceLevel), XtRImmediate, (XtPointer)0 },
  107.     { "debugLevel", "DebugLevel", XtRInt, sizeof(int),
  108.       XtOffset(AppResources *,debugLevel), XtRImmediate, (XtPointer)0 },
  109.     { "settingsWidgets", "SettingsWidgets", XtRString, sizeof(String),
  110.       XtOffset(AppResources *,settingsWidgets), XtRImmediate, "" },
  111. };
  112.  
  113. /*
  114.  * Non-widget resources set on command line.
  115.  */
  116. static XrmOptionDescRec options[] = {
  117.     { "-search",  ".searchType", XrmoptionSepArg, (XtPointer)"exact" },
  118.     { "-e",      ".searchType", XrmoptionNoArg,  (XtPointer)"exact" },
  119.     { "-s",      ".searchType", XrmoptionNoArg,  (XtPointer)"substr" },
  120.     { "-c",      ".searchType", XrmoptionNoArg,  (XtPointer)"subcase" },
  121.     { "-r",      ".searchType", XrmoptionNoArg,  (XtPointer)"regexp" },
  122.     { "-es",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactSubstr" },
  123.     { "-ec",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactSubcase" },
  124.     { "-er",      ".searchType", XrmoptionNoArg,  (XtPointer)"exactRegexp" },
  125.     { "-sort",    ".sortType",     XrmoptionSepArg, (XtPointer)"default" },
  126.     { "-t",      ".sortType",     XrmoptionNoArg,  (XtPointer)"invdate" },
  127.     { "-host",      ".archieHost", XrmoptionSepArg,
  128.                     (XtPointer)"archie.mcgill.ca" },
  129.     { "-maxhits", ".maxHits",     XrmoptionSepArg, (XtPointer)"99" },
  130.     { "-offset",  ".offset",     XrmoptionSepArg, (XtPointer)"0" },
  131.     { "-nice",    ".niceLevel",     XrmoptionSepArg, (XtPointer)"0" },
  132.     { "-N",       ".niceLevel",     XrmoptionSepArg, (XtPointer)"0" },
  133.     { "-debug",      ".debugLevel", XrmoptionNoArg,  (XtPointer)"1" },
  134.     { "-D",      ".debugLevel", XrmoptionSepArg, (XtPointer)"1" },
  135. };
  136.  
  137. /*
  138.  * Widget and non-widget resources if the application defaults
  139.  * file can't be found.
  140.  * Generated automatically from Xarchie.ad by "ad2c".
  141.  * Comment out the include line (but not the NULL) if you don't want
  142.  * any resources compiled in.
  143.  */
  144. static String fallbackResources[] = {
  145. #include "Xarchie.ad.h"
  146.     NULL
  147. };
  148.  
  149. /*    -    -    -    -    -    -    -    -    */
  150.  
  151. main(argc,argv)
  152. int argc;
  153. char **argv;
  154. {
  155.     char buf[32];
  156.  
  157.     progname = argv[0];
  158.     initGraphics(&argc,argv);
  159.     if (argc > 1) {
  160.     syntax(argc,argv);
  161.     XtDestroyApplicationContext(appContext);
  162.     exit(1);
  163.     }
  164.     initWidgets();
  165.     XtRealizeWidget(toplevel);
  166.     /* Set window title to indicate version */
  167.     sprintf(buf,"xarchie %d.%d",xarchieMajorVersion,xarchieMinorVersion);
  168.     XStoreName(display,XtWindow(toplevel),buf);
  169.     sprintf(buf,"Welcome to xarchie %d.%d",xarchieMajorVersion,
  170.                             xarchieMinorVersion);
  171.     status0(buf);
  172.     /* get the data structure for responses */
  173.     db = newDb();
  174.     /* do it */
  175.     XtAppMainLoop(appContext);
  176.     /*NOTREACHED*/
  177. }
  178.  
  179. void
  180. doPendingEvents()
  181. {
  182.     while (XtAppPending(appContext))
  183.     XtAppProcessEvent(appContext,XtIMAll);
  184. }
  185.  
  186. static void
  187. initGraphics(argcp,argv)
  188. int *argcp;
  189. char **argv;
  190. {
  191.     toplevel = XtAppInitialize(&appContext, "Xarchie",
  192.                    options, XtNumber(options),
  193.                    argcp,argv,fallbackResources,NULL,ZERO);
  194.     initConverters(appContext);
  195.     XawSimpleMenuAddGlobalActions(appContext);
  196.     XtAppAddActions(appContext,actionTable,XtNumber(actionTable));
  197.     XtGetApplicationResources(toplevel,(XtPointer)&appResources,
  198.                               resources,XtNumber(resources),NULL,ZERO);
  199.     display = XtDisplay(toplevel);
  200.     screen = XtScreen(toplevel);
  201.     root = RootWindowOfScreen(screen);
  202. }
  203.  
  204. /*
  205.  * initWidgets: Initialize the widgets given in the .widgets resource,
  206.  *    check for required widgets, and set globals vars.
  207.  */
  208. static void
  209. initWidgets()
  210. {
  211.     initWidgetsFromString(appResources.widgets,".widgets");
  212.     /* check for the necessary widgets and set the global variables */
  213.     if ((hostList=XtNameToWidget(toplevel,"*hostList")) == NULL)
  214.     fail0("didn't create widget \"hostList\"");
  215.     if ((locationList=XtNameToWidget(toplevel,"*locationList")) == NULL)
  216.     fail0("didn't create widget \"locationList\"");
  217.     if ((fileList=XtNameToWidget(toplevel,"*fileList")) == NULL)
  218.     fail0("didn't create widget \"fileList\"");
  219.     if ((searchText=XtNameToWidget(toplevel,"*searchText")) == NULL)
  220.     fail0("didn't create widget \"searchText\"");
  221.     /* set globals for optional widgets */
  222.     statusText = XtNameToWidget(toplevel,"*statusText");
  223.     hostText = XtNameToWidget(toplevel,"*hostText");
  224.     locationText = XtNameToWidget(toplevel,"*locationText");
  225.     fileText = XtNameToWidget(toplevel,"*fileText");
  226.     sizeText = XtNameToWidget(toplevel,"*sizeText");
  227.     modesText = XtNameToWidget(toplevel,"*modesText");
  228.     dateText = XtNameToWidget(toplevel,"*dateText");
  229.     /* make the lists behave like a browser should */
  230.     XtAddCallback(hostList,XtNcallback,selectItem,(XtPointer)1);
  231.     XtAddCallback(locationList,XtNcallback,selectItem,(XtPointer)2);
  232.     XtAddCallback(fileList,XtNcallback,selectItem,(XtPointer)3);
  233.     /* since Xaw is so bloody stupid... */
  234.     clearList(hostList);
  235.     clearList(locationList);
  236.     clearList(fileList);
  237. }
  238.  
  239. #define ISSPACE(c)    ((c) == ' ' || (c) == '\t' || (c) == '\n')
  240. #define NUL        '\0'
  241.  
  242. /*
  243.  * initWidgetsFromString : Create the widgets specified in resourceStr as
  244.  *    "parent class name" triples. The resourceName is used for
  245.  *    error messages.
  246.  */
  247. void
  248. initWidgetsFromString(resourceStr,resourceName)
  249. char *resourceStr,*resourceName;
  250. {
  251.     char name[32],class[32],parent[256];
  252.     char *s,*t;
  253.     Boolean isShell;
  254.     WidgetClass wc;
  255.     Widget pw;
  256.  
  257.     if ((s=resourceStr) == NULL)
  258.     fail1("no widgets specified in %s resource!",resourceName);
  259.     while (*s) {
  260.     /* skip leading whitespace */
  261.         while (ISSPACE(*s))
  262.             s += 1;
  263.     if (!*s)
  264.         break;
  265.     /* Gather the parent widget name */
  266.         t = parent;
  267.         while (*s && !ISSPACE(*s))
  268.             *t++ = *s++;
  269.         *t = NUL;
  270.     /* skip whitespace */
  271.         while (isspace(*s))
  272.             s += 1;
  273.     if (!*s)
  274.         fail1("missing widget class and name in %s resource",resourceName);
  275.     /* Gather the class name */
  276.         t = class;
  277.         while (*s && !ISSPACE(*s))
  278.             *t++ = *s++;
  279.         *t = NUL;
  280.     /* skip whitespace */
  281.         while (isspace(*s))
  282.             s += 1;
  283.     if (!*s)
  284.         fail1("missing widget name in %s resource",resourceName);
  285.     /* Gather the widget's name */
  286.         t = name;
  287.         while (*s && !ISSPACE(*s))
  288.             *t++ = *s++;
  289.         *t = NUL;
  290.     /* convert class name to WidgetClass */
  291.         if ((wc=classNameToWidgetClass(class,&isShell)) == NULL)
  292.         fail1("can't convert string \"%s\" to widgetClass",class);
  293.     /* convert parent name to Widget */
  294.     if (strcmp(parent,"toplevel") == 0)
  295.         pw = toplevel;
  296.     else if ((pw=XtNameToWidget(toplevel,parent)) == NULL)
  297.         fail1("can't convert string \"%s\" to widget",parent);
  298.     /* finally create the widget */
  299.     if (isShell)
  300.             (void)XtCreatePopupShell(name,wc,pw,NULL,ZERO);
  301.         else
  302.             (void)XtCreateManagedWidget(name,wc,pw,NULL,ZERO);
  303.     }
  304. }
  305.  
  306. /*    -    -    -    -    -    -    -    -    */
  307. /* Callback procedures */
  308.  
  309. /*ARGSUSED*/
  310. static void
  311. selectItem(w,closure,call_data)
  312. Widget w;
  313. XtPointer closure,call_data;
  314. {
  315.     XawListReturnStruct *item = (XawListReturnStruct*)call_data;
  316.  
  317.     switch ((int)closure) {
  318.     case 1 :
  319.         if (selectedHostEntry &&
  320.         findHostIndexFromEntry(selectedHostEntry) == item->list_index) {
  321.         XawListUnhighlight(hostList);
  322.         clearFileInfo();
  323.         clearList(fileList);
  324.         clearLocationInfo();
  325.         clearList(locationList);
  326.         clearHostInfo();
  327.         selectedHostEntry = HOST_NULL;
  328.         } else {
  329.         selectedHostEntry = findHostEntryFromIndex(item->list_index,
  330.                                db);
  331.         displayHostInfo(selectedHostEntry);
  332.         displayLocs(selectedHostEntry);
  333.         }
  334.         break;
  335.     case 2 :
  336.         if (selectedLocEntry &&
  337.         findLocIndexFromEntry(selectedLocEntry) == item->list_index) {
  338.         XawListUnhighlight(locationList);
  339.         clearFileInfo();
  340.         clearList(fileList);
  341.         clearLocationInfo();
  342.         selectedLocEntry = LOC_NULL;
  343.         } else {
  344.         selectedLocEntry = findLocEntryFromIndex(item->list_index,
  345.                              selectedHostEntry);
  346.         displayLocationInfo(selectedLocEntry);
  347.         displayFiles(selectedLocEntry);
  348.         }
  349.         break;
  350.     case 3 :
  351.         if (selectedFileEntry &&
  352.         findFileIndexFromEntry(selectedFileEntry) == item->list_index) {
  353.         XawListUnhighlight(fileList);
  354.         clearFileInfo();
  355.         selectedFileEntry = FILE_NULL;
  356.         } else {
  357.         selectedFileEntry = findFileEntryFromIndex(item->list_index,
  358.                                selectedLocEntry);
  359.         displayFileInfo(selectedFileEntry);
  360.         }
  361.         break;
  362.     }
  363. }
  364.  
  365. /*    -    -    -    -    -    -    -    -    */
  366.  
  367. void
  368. displayHostInfo(hostp)
  369. HostEntry *hostp;
  370. {
  371.     if (hostText != NULL)
  372.     setText(hostText,hostp->hostname);
  373. }
  374.  
  375. void
  376. clearHostInfo()
  377. {
  378.     if (hostText != NULL)
  379.     setText(hostText,"");
  380. }
  381.  
  382. void
  383. displayLocationInfo(locp)
  384. LocEntry *locp;
  385. {
  386.     if (locationText != NULL)
  387.     setText(locationText,locp->linkpath);
  388. }
  389.  
  390. void
  391. clearLocationInfo()
  392. {
  393.     if (locationText != NULL)
  394.     setText(locationText,"");
  395. }
  396.  
  397. void
  398. displayFileInfo(filep)
  399. FileEntry *filep;
  400. {
  401.     char buf[16];
  402.  
  403.     if (fileText != NULL)
  404.     setText(fileText,filep->name);
  405.     if (sizeText != NULL) {
  406.     sprintf(buf,"%d",filep->size);
  407.     setText(sizeText,buf);
  408.     }
  409.     if (modesText != NULL)
  410.     setText(modesText,filep->modes);
  411.     if (sizeText != NULL)
  412.     setText(dateText,filep->date);
  413. }
  414.  
  415. void
  416. clearFileInfo()
  417. {
  418.     if (fileText != NULL)
  419.     setText(fileText,"");
  420.     if (sizeText != NULL)
  421.     setText(sizeText,"");
  422.     if (modesText != NULL)
  423.     setText(modesText,"");
  424.     if (dateText != NULL)
  425.     setText(dateText,"");
  426. }
  427.  
  428. /*    -    -    -    -    -    -    -    -    */
  429. /*
  430.  * setText() : Set the given Text item's value to the given string.
  431.  */
  432. void
  433. setText(item,text)
  434. Widget item;
  435. char *text;
  436. {
  437.     Arg args[1];
  438.  
  439.     if (item != NULL) {
  440.     XtSetArg(args[0],XtNstring,text);
  441.     XtSetValues(item,args,ONE);
  442.     }
  443. }
  444.  
  445. /*
  446.  * setLabel() : Set the given Label item's value to the given string.
  447.  */
  448. void
  449. setLabel(item,text)
  450. Widget item;
  451. char *text;
  452. {
  453.     Arg args[1];
  454.  
  455.     if (item != NULL) {
  456.     XtSetArg(args[0],XtNlabel,text);
  457.     XtSetValues(item,args,ONE);
  458.     }
  459. }
  460.  
  461. /*    -    -    -    -    -    -    -    -    */
  462.  
  463. void
  464. status0(str)
  465. char *str;
  466. {
  467.     if (statusText != NULL)
  468.     setText(statusText,str);
  469.     doPendingEvents();
  470. }
  471.  
  472. void
  473. status1(fmt,arg)
  474. char *fmt,*arg;
  475. {
  476.     char buf[256];
  477.  
  478.     sprintf(buf,fmt,arg);
  479.     status0(buf);
  480. }
  481.  
  482. void
  483. status2(fmt,arg1,arg2)
  484. char *fmt,*arg1,*arg2;
  485. {
  486.     char buf[256];
  487.  
  488.     sprintf(buf,fmt,arg1,arg2);
  489.     status0(buf);
  490. }
  491.  
  492. /*    -    -    -    -    -    -    -    -    */
  493.  
  494. void
  495. fail0(str)
  496. char *str;
  497. {
  498.     fprintf(stderr,"%s: %s\n",progname,str);
  499.     XtDestroyApplicationContext(appContext);
  500.     exit(1);
  501. }
  502.  
  503. void
  504. fail1(fmt,arg)
  505. char *fmt,*arg;
  506. {
  507.     char buf[256];
  508.  
  509.     sprintf(buf,fmt,arg);
  510.     fail0(buf);
  511. }
  512.  
  513. /*    -    -    -    -    -    -    -    -    */
  514. /*
  515.  * syntax() : Print whatever caused the error and the usage message.
  516.  */
  517. static void
  518. syntax(argc,argv)
  519. int argc;
  520. char **argv;
  521. {
  522.     char *program;
  523.  
  524.     program = *argv;
  525.     argv += 1;
  526.     if (argc > 2 || (strcmp(*argv,"-help") != 0 && strcmp(*argv,"-?") != 0)) {
  527.     fprintf(stderr,"%s: bad argument(s): ",program);
  528.     while (--argc)
  529.         fprintf(stderr,"%s ",*argv++);
  530.     fprintf(stderr,"\n");
  531.     }
  532.     fprintf(stderr,"Valid options (in addition to X Toolkit options) are:\n");
  533.     fprintf(stderr,"  -search type\tset query type\n");
  534.     fprintf(stderr,"  -e\t\tset query type to exact\n");
  535.     fprintf(stderr,"  -c\t\tset query type to subcase\n");
  536.     fprintf(stderr,"  -s\t\tset query type to substr\n");
  537.     fprintf(stderr,"  -r\t\tset query type to regexp\n");
  538.     fprintf(stderr,"  -ec\t\tset query type to exactSubcase\n");
  539.     fprintf(stderr,"  -es\t\tset query type to exactSubstr\n");
  540.     fprintf(stderr,"  -er\t\tset query type to exactRegexp\n");
  541.     fprintf(stderr,"  -sort type\tset sort mode\n");
  542.     fprintf(stderr,"  -t\t\tset sort mode to invdate\n");
  543.     fprintf(stderr,"  -host host\tconnect to Archie at host\n");
  544.     fprintf(stderr,"  -maxHits num\tset maximum number of matches per query\n");
  545.     fprintf(stderr,"  -offset off\tset Prospero offset\n");
  546.     fprintf(stderr,"  -[nice|N] level\tset query niceness\n");
  547.     fprintf(stderr,"  -[debug|D] level\tset Prospero debugging level\n");
  548.     fprintf(stderr,"  -help\t\tprint this message\n");
  549.     fprintf(stderr,"  -xrm 'resource: value'  pass arbitrary resources\n");
  550.     fprintf(stderr,"Options can be abbreviated to their shortest unique prefix.\n");
  551. }
  552.