home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE-.1 / FTP-ACTI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-22  |  11.5 KB  |  473 lines

  1. /*
  2.  * ftp-actions.c : X/FTP interface routines for xarchie
  3.  *
  4.  * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <fcntl.h>            /* O_RDONLY, etc. */
  9. #include <X11/Intrinsic.h>
  10. #include <X11/Shell.h>
  11. #include <X11/StringDefs.h>
  12. #include <X11/Xaw/Form.h>
  13. #include <X11/Xaw/Command.h>
  14. #include <X11/Xaw/AsciiText.h>
  15. #include <X11/Xaw/Dialog.h>
  16. #include "config.h"
  17. #ifdef HAVE_SYS_PARAM_H
  18. #include <sys/param.h>
  19. #endif
  20. #include "db.h"
  21. #include "appres.h"
  22. #include "xarchie.h"
  23. #include "selection.h"
  24. #include "browser.h"
  25. #include "ftp.h"
  26. #include "view-file.h"
  27. #include "status.h"
  28. #include "popups.h"
  29. #include "xutil.h"
  30. #include "alert.h"
  31. #include "syserr.h"
  32. #include "debug.h"
  33.  
  34. /*
  35.  * Functions defined here
  36.  */
  37. void initFtpActions();
  38. void ftpGetSelectedItems(),ftpOpenSelectedItems();
  39. void RegisterFtpFd(),UnregisterFtpFd();
  40. int ftpPrompt();
  41.  
  42. static void ftpSelectedItems(),countFileToGet(),countFileToOpen(),addFile();
  43. static void ftpGetFinished(),ftpOpenOneFinished();
  44. static void initFtpTraceWidgets();
  45. static void ftpTraceDoneAction();
  46. static void ftpTraceReset(),ftpTraceFunc();
  47. static void inputCallback();
  48. static void ftpPromptCallback();
  49.  
  50. /*
  51.  * Data defined here
  52.  */
  53. static char **ftpFilenames;
  54. static int numFtpFiles;
  55. static FtpContext *ftpCurrentContext;
  56.  
  57. static Widget ftpTraceShell,ftpTraceText;
  58. static Boolean isPoppedUp;
  59.  
  60. static XtActionsRec actionTable[] = {
  61.     { "ftp-trace-done",    ftpTraceDoneAction },
  62. };
  63.  
  64. /*    -    -    -    -    -    -    -    -    */
  65. /* Interface functions */
  66.  
  67. void
  68. initFtpActions()
  69. {
  70.     XtAppAddActions(appContext,actionTable,XtNumber(actionTable));
  71. }
  72.  
  73. void
  74. ftpGetSelectedItems()        /* Called from getAction() */
  75. {
  76.     ftpSelectedItems(appResources.ftpLocalDir,appResources.ftpType,
  77.              appResources.ftpPrompt,appResources.ftpStrip,
  78.              countFileToGet,NULL,ftpGetFinished);
  79. }
  80.  
  81. void
  82. ftpOpenSelectedItems()        /* Called from openBrowser() */
  83. {
  84.     ftpSelectedItems(tmpDirectory,"ascii",False,True,
  85.              countFileToOpen,ftpOpenOneFinished,ftpGetFinished);
  86. }
  87.  
  88. void
  89. ftpAbortTransfer()
  90. {
  91.     DEBUG1("ftpAbortTransfer: ftpCurrentContext=0x%x\n",ftpCurrentContext);
  92.     ftpAbort(ftpCurrentContext);
  93.     DEBUG0("ftpAbortTransfer: done\n");
  94. }
  95.  
  96. /*    -    -    -    -    -    -    -    -    */
  97. /*
  98.  * This function starts ftp retrieval of the items selected in the
  99.  * browser into the local directory.
  100.  */
  101. static void
  102. ftpSelectedItems(local_dir,typestr,prompt,strip,
  103.          countProc,doneOneProc,doneAllProc)
  104. char *local_dir,*typestr;
  105. Boolean prompt,strip;
  106. void (*countProc)();
  107. FtpCallbackProc doneOneProc,doneAllProc;
  108. {
  109.     char *host,*cwd;
  110.     int type;
  111. #ifdef DEBUG
  112.     int i;
  113. #endif
  114.  
  115.     DEBUG0("ftpSelectedItems: setting files to transfer\n");
  116.     numFtpFiles = 0;
  117.     forEachSelectedItem(countProc);
  118.     if (numFtpFiles == 0) {
  119.     return;
  120.     }
  121.     ftpFilenames = (char **)XtCalloc(numFtpFiles,sizeof(char *));
  122.     numFtpFiles = 0;
  123.     forEachSelectedItem(addFile);
  124. #ifdef DEBUG
  125.     for (i=0; i < numFtpFiles; i++)
  126.     fprintf(stderr,"ftpSelectedItems: ftpFilenames[%d] = \"%s\"\n",
  127.         i,ftpFilenames[i]);
  128. #endif
  129.     /* Is there a host? */
  130.     if ((host=getWidgetString(hostText)) == NULL || *host == '\0') {
  131.     alert0("No host specified for transfer!");
  132.     return;
  133.     }
  134.     DEBUG1("ftpSelectedItems: host = \"%s\"\n",host);
  135.     /* Optional remote directory */
  136.     cwd = getWidgetString(locationText); /* Can be "" */
  137.     DEBUG1("ftpSelectedItems: remote dir = \"%s\"\n",cwd);
  138.     if (cwd && *cwd == '\0')
  139.     cwd = NULL;
  140.     /* Convert type to ARPA code */
  141.     if (typestr == NULL || *typestr == 'a' || *typestr == 'A')
  142.     type = TYPE_A;
  143.     else if (*typestr == 'b' || *typestr == 'B')
  144.     type = TYPE_I;
  145.     else if (*typestr == 'e' || *typestr == 'E')
  146.     type = TYPE_E;
  147.     else
  148.     type = atoi(typestr);
  149.     /* Put up the tracing window if needed */
  150.     if (appResources.ftpTrace) {
  151.     if (ftpTraceShell == NULL)
  152.         initFtpTraceWidgets();
  153.     ftpTraceReset();
  154.     isPoppedUp = True;
  155.     XtPopup(ftpTraceShell,XtGrabNone);
  156.     }
  157.     /* Get the FTP context */
  158.     ftpCurrentContext =
  159.     ftpNewContext(host,"anonymous",appResources.ftpMailAddress,
  160.               cwd,local_dir,type,strip,(numFtpFiles>1 && prompt),
  161.               FTP_GET,ftpFilenames,numFtpFiles,
  162.               (appResources.ftpTrace ? ftpTraceFunc : NULL),
  163.               doneOneProc,doneAllProc);
  164.     XtFree((char *)ftpFilenames);
  165.     /* Here we go... */
  166.     setBrowserState(BROWSER_FTP);
  167.     ftpStart(ftpCurrentContext);
  168.     DEBUG0("ftpSelectedItems: done\n");
  169. }
  170.  
  171. /*    -    -    -    -    -    -    -    -    */
  172. /* Functions called by ftpGetSelectedItems */
  173.  
  174. /*ARGSUSED*/
  175. static void
  176. countFileToGet(dbp,list_index)        /* complains about non-files */
  177. DbEntry *dbp;
  178. int list_index;
  179. {
  180.     if (dbp->type == DB_FILE) {
  181.     numFtpFiles += 1;
  182.     } else {
  183.     alert1("Can't retrieve non-file \"%s\".",dbp->name);
  184.     }
  185. }
  186.  
  187. /*ARGSUSED*/
  188. static void
  189. countFileToOpen(dbp,list_index)        /* doesn't complain about non-files */
  190. DbEntry *dbp;
  191. int list_index;
  192. {
  193.     if (dbp->type == DB_FILE) {
  194.     numFtpFiles += 1;
  195.     }
  196. }
  197.  
  198. /*ARGSUSED*/
  199. static void
  200. addFile(dbp,list_index)            /* adds filename to array */
  201. DbEntry *dbp;
  202. int list_index;
  203. {
  204.     if (dbp->type == DB_FILE) {
  205.     ftpFilenames[numFtpFiles++] = XtNewString(dbp->name);
  206.     }
  207. }
  208.  
  209. /*    -    -    -    -    -    -    -    -    */
  210. /* FTP callbacks */
  211.  
  212. /*
  213.  * This function is called back when the ftp transfer is complete (for
  214.  * whatever reason).
  215.  */
  216. /*ARGUSED*/
  217. static void
  218. ftpGetFinished(ftpc)
  219. FtpContext *ftpc;
  220. {
  221.     DEBUG1("ftpGetFinished(0x%x)...\n",ftpc);
  222.     setBrowserState(BROWSER_READY);
  223.     ftpFreeContext(ftpc);
  224.     status0("Ready");
  225.     DEBUG0("ftpGetFinished: done\n");
  226. }
  227.  
  228. /*
  229.  * This function is called back when a single file has been successfully
  230.  * retrieved for Open.
  231.  */
  232. /*ARGSUSED*/
  233. static void
  234. ftpOpenOneFinished(ftpc)
  235. FtpContext *ftpc;
  236. {
  237.     char filename[MAXPATHLEN];
  238.  
  239.     DEBUG1("ftpOpenOneFinished(0x%x)...\n",ftpc);
  240.     if (ftpc->local_dir && *(ftpc->local_dir))
  241.     sprintf(filename,"%s/%s",ftpc->local_dir,ftpc->files[ftpc->this_file]);
  242.     else
  243.     strcpy(filename,ftpc->files[ftpc->this_file]);
  244.     viewFile(filename);
  245.     DEBUG0("ftpOpenOneFinished: done\n");
  246. }
  247.  
  248. /*    -    -    -    -    -    -    -    -    */
  249. /* Routines for tracing the ftp connection in a window */
  250.  
  251. static void
  252. initFtpTraceWidgets()
  253. {
  254.     Widget form;
  255.  
  256.     ftpTraceShell = XtCreatePopupShell("ftpTraceShell",
  257.                        topLevelShellWidgetClass,
  258.                        toplevel,NULL,0);
  259.     form = XtCreateManagedWidget("ftpTraceForm",formWidgetClass,
  260.                  ftpTraceShell,NULL,0);
  261.     (void)XtCreateManagedWidget("ftpTraceDismissButton",commandWidgetClass,
  262.                 form,NULL,0);
  263.     ftpTraceText = XtCreateManagedWidget("ftpTraceText",asciiTextWidgetClass,
  264.                      form,NULL,0);
  265.     XtRealizeWidget(ftpTraceShell);
  266.     (void)XSetWMProtocols(XtDisplay(ftpTraceShell),XtWindow(ftpTraceShell),
  267.               &WM_DELETE_WINDOW,1);
  268. }
  269.  
  270. void
  271. setFtpTraceShellState(state)
  272. int state;
  273. {
  274.     if (!isPoppedUp)
  275.     return;
  276.     switch (state) {
  277.     case NormalState:
  278.         XtMapWidget(ftpTraceShell);
  279.         break;
  280.     case IconicState:
  281.         XtUnmapWidget(ftpTraceShell);
  282.         break;
  283.     }
  284. }
  285.  
  286. /*ARGSUSED*/
  287. static void
  288. ftpTraceDoneAction(w,event,params,num_params)
  289. Widget w;
  290. XEvent *event;
  291. String *params;
  292. Cardinal *num_params;
  293. {
  294.     isPoppedUp = False;
  295.     XtPopdown(ftpTraceShell);
  296. }
  297.  
  298. static void
  299. ftpTraceReset()
  300. {
  301.     Arg args[1];
  302.  
  303.     XtSetArg(args[0],XtNstring,"");
  304.     XtSetValues(ftpTraceText,args,1);
  305. }
  306.  
  307. /*
  308.  * This function is called back from within the ftp routines to monitor
  309.  * the exchange of messages.
  310.  */
  311. /*ARGSUSED*/
  312. static void
  313. ftpTraceFunc(ftpc,who,text)
  314. FtpContext *ftpc;
  315. int who;        /* 0 => recvd, non-0 => sent */
  316. char *text;        /* text of this message */
  317. {
  318.     if (who)
  319.     appendWidgetText(ftpTraceText,"ftp> ");
  320.     appendWidgetText(ftpTraceText,text);
  321.     if (*(text+strlen(text)-1) != '\n')
  322.     appendWidgetText(ftpTraceText,"\n");
  323. }
  324.  
  325. /*    -    -    -    -    -    -    -    -    */
  326. /* File descriptor registration routines: */
  327.  
  328. /*
  329.  * We need as many of these as there are file descriptors. It's
  330.  * easier to guess big than to figure out where such a magic number lives.
  331.  */
  332. #define NUMFDS 64
  333. FtpCallbackProc ftpRegisteredProcs[NUMFDS];
  334. FtpContext *ftpRegisteredContexts[NUMFDS];
  335. XtInputId ftpRegisteredIds[NUMFDS];
  336.  
  337. /*
  338.  * This function is exported and used by the FTP routines to register
  339.  * a file descriptor for notification. We register it by recording the
  340.  * callback information (proc and ftpc) and telling X to register the
  341.  * fd as an external input source. When X calls back to inputCallback(),
  342.  * we use the stored information to call back to the FTP routine.
  343.  * Got that?
  344.  */
  345. void
  346. RegisterFtpFd(ftpc,fd,flags,proc)
  347. FtpContext *ftpc;
  348. int fd,flags;
  349. FtpCallbackProc proc;
  350. {
  351.     XtInputMask condition;
  352.  
  353.     DEBUG3("RegisterFtpFd: ftpc=0x%x, fd=%d, flags=%d\n",ftpc,fd,flags);
  354.     if (fd < 0 || fd >= NUMFDS) {
  355.     fprintf(stderr,"YOW! Attempt to register fd %d!\n",fd);
  356. #ifdef DEBUG
  357.     abort();
  358. #endif
  359.     return;
  360.     }
  361.     switch (flags) {
  362.       case O_RDONLY:
  363.     condition = XtInputReadMask;
  364.     break;
  365.       case O_WRONLY:
  366.     condition = XtInputWriteMask;
  367.     break;
  368.       case O_RDWR:
  369.     condition = XtInputReadMask | XtInputWriteMask;
  370.     break;
  371.     }
  372.     ftpRegisteredProcs[fd] = proc;
  373.     ftpRegisteredContexts[fd] = ftpc;
  374.     ftpRegisteredIds[fd] =
  375.     XtAppAddInput(appContext,fd,(XtPointer)condition,inputCallback,NULL);
  376.     DEBUG1("RegisterFtpFd: done: id=0x%x\n",ftpRegisteredIds[fd]);
  377. }
  378.  
  379. /*
  380.  * Called back when X says source is ready. We call the function registered
  381.  * by the FTP routines, passing the context.
  382.  */
  383. /*ARGSUSED*/
  384. static void
  385. inputCallback(client_data,source,id)
  386. XtPointer client_data;
  387. int *source;
  388. XtInputId *id;
  389. {
  390.     if (ftpRegisteredProcs[*source] != NULL) {
  391.     (*(ftpRegisteredProcs[*source]))(ftpRegisteredContexts[*source]);
  392.     } else {
  393.     fprintf(stderr,"YOW! Callback for fd=%d not registered!\n",*source);
  394. #ifdef DEBUG
  395.     abort();
  396. #endif
  397.     }
  398. }
  399.  
  400. /*
  401.  * This function is exported and used by the FTP routines to undo
  402.  * a previous registration.
  403.  */
  404. /*ARGSUSED*/
  405. void
  406. UnregisterFtpFd(ftpc,fd)
  407. FtpContext *ftpc;
  408. int fd;
  409. {
  410.     DEBUG3("UnregisterFtpFd: ftpc=0x%x, fd=%d, id=0x%x\n",
  411.        ftpc,fd,ftpRegisteredIds[fd]);
  412.     if (fd < 0 || fd >= NUMFDS) {
  413.     fprintf(stderr,"YOW! Attempt to unregister fd %d!\n",fd);
  414. #ifdef DEBUG
  415.     abort();
  416. #endif
  417.     return;
  418.     }
  419.     if (ftpRegisteredIds[fd] != (XtInputId)NULL)
  420.     XtRemoveInput(ftpRegisteredIds[fd]);
  421.     ftpRegisteredIds[fd] = (XtInputId)NULL;
  422.     ftpRegisteredProcs[fd] = NULL;
  423.     ftpRegisteredContexts[fd] = NULL;
  424.     DEBUG0("UnregisterFtpFd: done\n");
  425. }
  426.  
  427. /*    -    -    -    -    -    -    -    -    */
  428. /* Routines for prompting during FTP transfers: */
  429.  
  430. static Widget ftpPromptShell;
  431. static int ftpPromptResult;
  432.  
  433. int
  434. ftpPrompt(ftpc)
  435. FtpContext *ftpc;
  436. {
  437.     char str[256];
  438.  
  439.     if (ftpPromptShell == NULL)
  440.     ftpPromptShell = createPopup("ftpPrompt",4,ftpPromptCallback);
  441.     sprintf(str,"%s %s?",
  442.         (ftpc->filecmd==FTP_GET?"GET":"PUT"),ftpc->files[ftpc->this_file]);
  443.     setPopupLabel(ftpPromptShell,"ftpPrompt",str);
  444.     popupMainLoop(ftpPromptShell);
  445.     return(ftpPromptResult);
  446. }
  447.  
  448. /*ARGSUSED*/
  449. static void
  450. ftpPromptCallback(w,client_data,call_data)
  451. Widget w;
  452. XtPointer client_data;        /* button number */
  453. XtPointer call_data;
  454. {
  455.     switch ((int)client_data) {
  456.       case 0:            /* Yes */
  457.     ftpPromptResult = 1;
  458.     break;
  459.       case 1:            /* No */
  460.     ftpPromptResult = 0;
  461.     break;
  462.       case 2:            /* All */
  463.     ftpCurrentContext->prompt = 0;
  464.     ftpPromptResult = 1;
  465.     break;
  466.       case 3:            /* Abort */
  467.     ftpCurrentContext->this_file = ftpCurrentContext->num_files;
  468.     ftpPromptResult = 0;
  469.     break;
  470.     }
  471.     popupDone();
  472. }
  473.