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