home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / archival / ftp / BFTP.312 / bftp_tool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-29  |  38.2 KB  |  1,403 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *     Background File Transfer Program (BFTP)                *
  4.  *                                    *
  5.  *    Written at USC/Information Sciences Institute            *
  6.  *                                    *
  7.  *      BFTP is Public Domain, and may be used for any purpose as    *
  8.  *      long as this notice is not removed.  USC-ISI does not assume    *
  9.  *    any responsibility for the correctness, performance, or use    *
  10.  *    of this software.                        *
  11.  *                                    *
  12.  ************************************************************************/
  13.  
  14. /*  bftp_tool.c
  15.  *
  16.  *  The "bftptool" SunView user interface, is implemented in this module.
  17. */
  18.  
  19. /* *** Things to add *** */
  20.     /* More defaults in menus? */
  21.     /* Mailbox check on find? */
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include <sys/param.h>
  26. #include <sys/file.h>
  27. #include <suntool/sunview.h>
  28.     /* includes <sunwindow/window_hs.h>, which includes <sys/time.h> */
  29. #include <suntool/panel.h>
  30. #include <sunwindow/notify.h>
  31. #include <suntool/textsw.h>
  32.  
  33. #define text_print(str) (void)textsw_insert(fts_sw, str, strlen(str))
  34. #define endof(x) (x + strlen(x))
  35. #define scroll_to_end()\
  36.   textsw_possibly_normalize(fts_sw, (int)window_get(fts_sw,TEXTSW_LENGTH))
  37.  
  38. /* FTS */
  39.  
  40. #include <netinet/in.h>    
  41. #include "fts.h"
  42.     /* bftp.h is included in fts.h */
  43.     
  44. extern FILE 
  45.     *tracefp,  /* File to save trace of Telnet history */
  46.     *logfp;    /* File to compose message */
  47.  
  48. extern char
  49.    *get_request_file(),
  50.    bftp_dir[MAXPATHLEN],
  51.    def_user[L_cuserid],
  52.    *version,
  53.    *introduction,
  54.    *background;
  55.    
  56. extern struct hostinfo src, dst, nullhost;
  57. extern struct fileinfo fil, defaultfile;
  58. extern struct reqinfo nullreq;
  59.  
  60. extern int 
  61.     init_param_help(),
  62.     init_req_help(),
  63.     init_submit_help(),
  64.     find_errors(),
  65.     op_choice(),
  66.     op_value();
  67.  
  68. extern FILE *listp;
  69.  
  70. extern Notify_value close_popup();
  71.  
  72. extern void 
  73.     copy_fileparams(),
  74.     destroy_req_frame(),
  75.     display_sfile_menu(),
  76.     dummy_event_proc(),
  77.     hint_event_proc(),
  78.     init_attr_lists(),
  79.     init_host_menu(),
  80.     init_login_menu(),
  81.     init_passw_menu(),
  82.     init_port_menu(),
  83.     init_req(),
  84.     init_rs_location(),
  85.     init_user(),
  86.     make_bold(),
  87.     make_submit_frame(),
  88.     make_fts_frame(),
  89.     no_spaces(),
  90.     rStorage_proc(),
  91.     update_params();
  92.     
  93. boolean verbose = FALSE;
  94.  
  95. extern boolean
  96.     parse_date(),
  97.     confirm_yes(),
  98.     read_req(),
  99.     write_req(),
  100.     empty_str(),
  101.     mailbox_ok();
  102.  
  103. extern Attr_avlist 
  104.     app_attr,
  105.     byte_attr,
  106.     form_attr,
  107.       mode_attr,
  108.     mult_attr,
  109.     stou_attr,
  110.     stru_attr,
  111.     type_attr,
  112.  
  113.       dir_attr,
  114.     file_attr,
  115.     host_attr,
  116.     login_attr,
  117.     pass_attr,
  118.     port_attr;
  119.  
  120. /* Globals used in the Find procedures */
  121.  
  122. static char filename[100], request[20], listfile[100], keyword[20];
  123. static struct hostinfo tmpsrc, tmpdst;
  124. static struct fileinfo tmpfil;
  125. static struct reqinfo req, tmpreq;
  126.  
  127. static short icon_image[] = {
  128. #include "bftp.icon"
  129. };
  130. DEFINE_ICON_FROM_IMAGE(bftp_icon, icon_image);
  131.  
  132. static int fts_pid;
  133.  
  134. /* Required for tool_lib.c */
  135.  
  136. Frame tool_frame;
  137.  
  138. /* *********************** */
  139.  
  140. extern Window popup_frame;
  141. extern Textsw fts_sw;
  142. Window params;
  143.  
  144. /* Panel items (used to index help info) */
  145.     
  146. extern Panel_item
  147.   /* Popup Window */
  148.     quitSW_item, keyword_item, 
  149.     interval_item, tries_item, startTime_item, mailbox_item,
  150.   /* Parameters subwindow */
  151.     type_item, format_item, byteSize_item, stru_item, 
  152.       mode_item, stou_item, append_item, multiple_item;
  153.  
  154. Panel_item
  155.     sFile_item;
  156. static Panel_item 
  157.   /* Commands */
  158.     quit_item, explain_item, verify_item, submit_item, transfer_item,
  159.     find_item, clear_item, storage_item,
  160.   /* Parameters */
  161.     op_item, verbose_item, 
  162.     src_item, sHost_item, sLogin_item, sPass_item, sAcct_item, 
  163.     sDir_item, sPort_item,
  164.     dest_item, dHost_item, dLogin_item, dPass_item, dAcct_item,
  165.     dFile_item, dFileDef_msg, dDir_item, dPort_item,
  166.     param_item, 
  167.   /* Find Popup Window */
  168.     id_item,
  169.     find_button,
  170.     next_button,
  171.     cancel_button,
  172.     read_button;
  173.  
  174. #define SAME_AS_SRC "(same as Src)"
  175.  
  176. /* Table of item, corresponding hint text, and event_proc for optional
  177.    fields for which the default value is displayed as a hint:
  178. */
  179.  
  180. struct hint_record {
  181.      Panel_item *field_item, *msg_item;
  182.      void (*event_proc)();
  183.    } hint_list[] = {
  184.     &dFile_item,     &dFileDef_msg,       display_sfile_menu
  185.     };
  186.  
  187. /* Help strings for event procs -- middle mouse button */
  188.  
  189. #include "help_strings.h"
  190.  
  191. struct help_record {
  192.    union u_tag {
  193.      Panel_item *ip;
  194.      char    *cp;
  195.      } uval;
  196.    } helplist[1000];
  197.  
  198. static void
  199. init_help()
  200. {
  201.    int i = 0;
  202.  
  203. #define set_ptr(item) helplist[i++].uval.ip = &item
  204. #define set_str(str) helplist[i++].uval.cp = str
  205. #define last_str() helplist[i++].uval.cp = NULL
  206.  
  207.    set_ptr(quit_item);
  208.    set_str(quit_help);
  209.    last_str();
  210.  
  211.    set_ptr(verbose_item);
  212.    set_str("The Verbose flag specifies that a detailed log of the FTP commands will");
  213.    set_str("  be displayed when the 'Verify' and the 'Transfer' commands are selected.");
  214.    set_str("  The default is FALSE.");
  215.    last_str();
  216.  
  217.    set_ptr(src_item);
  218.    set_str("Source parameters specify from where file(s) will be copied,");
  219.    set_str("  moved, or deleted.");
  220.    last_str();
  221.  
  222.    set_ptr(sHost_item);
  223.    set_str(sHost_help);
  224.    last_str();
  225.  
  226.    set_ptr(sLogin_item);
  227.    set_str(sLogin_help);
  228.    last_str();
  229.  
  230.    set_ptr(sPass_item);
  231.    set_str(sPass_help);
  232.    last_str();
  233.  
  234.    set_ptr(sAcct_item);
  235.    set_str("Account on source host.");
  236.    last_str();
  237.  
  238.    set_ptr(sPort_item);
  239.    set_str("Port used for the FTP control connection to the source host.");
  240.    set_str("  The default is 21.");
  241.    last_str();
  242.  
  243.    set_ptr(sFile_item);
  244.    set_str("Name of file to be transfered/deleted.  The wildcard character '*'");
  245.    set_str(sFile2_help);
  246.    last_str();
  247.  
  248.    set_ptr(sDir_item);
  249.    set_str(sDir1_help);
  250.    set_str(sDir2_help);
  251.    set_str(sDir3_help);
  252.    set_str(sDir4_help);
  253.    set_str(sDir5_help);
  254.    last_str();
  255.  
  256.    i = init_submit_help(i);
  257.  
  258.    set_ptr(dest_item);
  259.    set_str("Destination parameters specify where file(s) will be copied or moved.");
  260.    last_str();
  261.   
  262.    set_ptr(dHost_item);
  263.    set_str(dhost_help);
  264.    last_str();
  265.  
  266.    set_ptr(dLogin_item);
  267.    set_str(dlogin_help);
  268.    last_str();
  269.  
  270.    set_ptr(dPass_item);
  271.    set_str(dpass_help);
  272.    last_str();
  273.  
  274.    set_ptr(dFile_item);
  275.    set_str(dfile_help);
  276.    set_str(paren_help);
  277.    last_str();
  278.  
  279.    set_ptr(dAcct_item);
  280.    set_str("Account on destination host.");
  281.    last_str();
  282.    
  283.    set_ptr(dPort_item);
  284.    set_str("Port used for the FTP control connection to the destintation host.");
  285.    set_str("  The default is 21.");
  286.    last_str();
  287.  
  288.    set_ptr(dDir_item);
  289.    set_str(ddir1_help);
  290.    set_str(ddir2_help);
  291.    set_str(ddir3_help);
  292.    set_str(ddir4_help);
  293.    set_str(ddir5_help);
  294.    last_str();
  295.  
  296.    set_ptr(storage_item);
  297.    set_str(reqSW1_help);
  298.    set_str(reqSW2_help);
  299.    set_str(toggle_help);
  300.    last_str();
  301.  
  302.    i = init_req_help();
  303.  
  304.    set_ptr(op_item);
  305.    set_str("The following operations are supported:");
  306.    set_str("  'copy'    The source file will be copied to the destination file name.");
  307.    set_str("  'move'    The source file will be deleted after it has been copied.");
  308.    set_str("  'delete'  The source file will be deleted.");
  309.    set_str("  The default is 'copy'.");
  310.    last_str();
  311.   
  312.    i = init_param_help(i);
  313.  
  314.    set_ptr(explain_item);
  315.    set_str("Explain displays a short explanation of how to use this tool.");
  316.    last_str();
  317.  
  318.    set_ptr(verify_item);
  319.    set_str("Verify is used to connect to the specified hosts, while you wait,");
  320.    set_str("  and to determine whether the specified parameters are supported.");
  321.    last_str();
  322.  
  323.    set_ptr(submit_item);
  324.    set_str("Submit is used to queue the request.  A popup window will appear,");
  325.    set_str("   requesting additional parameters such as the start time.");
  326.    last_str();
  327.  
  328.    set_ptr(transfer_item);
  329.    set_str("Transfer is used to connect to the specified hosts,");
  330.    set_str("  and to perform the file transfer while you wait.");
  331.    last_str();
  332.  
  333.    set_ptr(find_item);
  334.    set_str("Find brings up a popup window, and can be used to locate and");
  335.    set_str("  display a previous request.  Once a request is displayed, it");
  336.    set_str("  can be changed and resubmited, or cancelled.");
  337.    last_str();
  338.  
  339.    set_ptr(clear_item);
  340.    set_str("Clear resets all parameters to their default values.");
  341.    last_str();
  342.  
  343.    set_ptr(find_button);
  344.    set_str("FindRequest searches for and displays BFTP request(s) that match");
  345.    set_str("  the specified RequestID and/or RequestKeyword.");
  346.    last_str();
  347.  
  348.    set_ptr(next_button);
  349.    set_str("NextRequest displays the next matching BFTP request.");
  350.    last_str();
  351.  
  352.    set_ptr(cancel_button);
  353.    set_str("CancelRequest cancels the BFTP request most recently displayed in");
  354.    set_str("  the text subwindow, and displays the next matching request.");
  355.    last_str();
  356.  
  357.    set_ptr(read_button);
  358.    set_str("ChangeRequest reads the displayed request into the BFTPTOOL,");
  359.    set_str("  and cancels the original request.  This request may now");
  360.    set_str("  be modified and resubmitted.");
  361.    last_str();
  362.  
  363.    set_ptr(id_item);
  364.    set_str("The RequestID refers to a specific request.  It is displayed");
  365.    set_str("  in the text subwindow when a request is first queued.");
  366.    set_str("  Fill in the RequestID to display the status of a request");
  367.    set_str("  that was previously queued.  An example of the format is");
  368.    set_str("  'bftp588464123'.  If the RequestID field is omitted, all");
  369.    set_str("  requests that match the RequestKeyword field will be displayed.");
  370.    last_str();
  371.  
  372.    /* end the list */
  373.    helplist[i++].uval.ip = NULL;
  374. }
  375.  
  376. static void
  377. set_buttons(status)
  378.    boolean status;
  379. {
  380.    /* these items use the popup_frame and must be cleared */
  381.    panel_set(find_item, PANEL_SHOW_ITEM, status, 0);
  382.    panel_set(transfer_item, PANEL_SHOW_ITEM, status, 0);
  383.    panel_set(verify_item, PANEL_SHOW_ITEM, status, 0);
  384.    panel_set(submit_item, PANEL_SHOW_ITEM, status, 0);
  385.    panel_set(explain_item, PANEL_SHOW_ITEM, status, 0);
  386.  
  387.    panel_set(clear_item, PANEL_SHOW_ITEM, status, 0);
  388.    panel_set(storage_item, PANEL_SHOW_ITEM, status, 0);
  389.    if (!status)
  390.       destroy_req_frame();
  391. }
  392.  
  393. void
  394. quit_popup(item, event)
  395.    Panel_item item;
  396.    Event *event;
  397. {
  398.    close_listp();
  399.    if (fts_pid) {
  400.       kill(fts_pid, SIGKILL);
  401.       fts_pid = 0;
  402.       }
  403.    window_destroy(popup_frame);
  404.    set_buttons(TRUE);
  405. }
  406.  
  407. /* routine used in upcoming notify procs */
  408.  
  409. void
  410. toggle_dest_items(show)
  411.    int show;
  412. {
  413.    if ((int)panel_get(dHost_item, PANEL_SHOW_ITEM) != show) {
  414.       panel_set(dHost_item, PANEL_SHOW_ITEM, show, 0);
  415.       panel_set(dLogin_item, PANEL_SHOW_ITEM, show, 0);
  416.       panel_set(dPass_item, PANEL_SHOW_ITEM, show, 0);
  417.       panel_set(dAcct_item, PANEL_SHOW_ITEM, show, 0);
  418.       panel_set(dDir_item, PANEL_SHOW_ITEM, show, 0);
  419.       panel_set(dPort_item, PANEL_SHOW_ITEM, show, 0);
  420.       panel_set(dFile_item, PANEL_SHOW_ITEM, show, 0);
  421.       if (show && ((int)panel_get(multiple_item, PANEL_VALUE)) &&
  422.           (!(int)panel_get(append_item, PANEL_VALUE)))
  423.      panel_set(dFile_item, PANEL_SHOW_ITEM, FALSE, 0);
  424.       panel_set(stou_item, PANEL_SHOW_ITEM, show, 0);
  425.       panel_set(append_item, PANEL_SHOW_ITEM, show, 0);
  426.       panel_set(stru_item, PANEL_SHOW_ITEM, show, 0);
  427.       panel_set(mode_item, PANEL_SHOW_ITEM, show, 0);
  428.       panel_set(type_item, PANEL_SHOW_ITEM, show, 0);
  429.       switch ((int)panel_get(type_item, PANEL_VALUE)) {
  430.          case 0: /* ascii */
  431.          case 1: /* ebcdic */
  432.             panel_set(format_item, PANEL_SHOW_ITEM, show, 0);
  433.             break;
  434.          case 2: /* image */
  435.             break;
  436.          case 3: /* local */
  437.         panel_set(byteSize_item, PANEL_SHOW_ITEM, show, 0);
  438.             break;
  439.          }
  440.       }
  441. }
  442.  
  443. /* Notify Procs for Parameters */
  444.  
  445. static void
  446. op_proc(item, value, event)
  447.    Panel_item item;
  448.   int value;
  449.   Event *event;
  450. {
  451.    toggle_dest_items((value==op_choice(DFILE))?FALSE:TRUE);
  452. }
  453.  
  454. /* Routines used in Notify procs */
  455.  
  456. void
  457. show_dest_file(yes)
  458.    boolean yes;
  459. {
  460.    if (DFILE != op_value((int)panel_get(op_item, PANEL_VALUE))) {
  461.       panel_set(dFile_item, PANEL_SHOW_ITEM, (yes)?TRUE:FALSE, 0);
  462.       panel_set(dFileDef_msg, PANEL_SHOW_ITEM, 
  463.         (yes && !strlen((char *)panel_get(dFile_item, PANEL_VALUE)))?
  464.                  TRUE:FALSE, 
  465.         0);
  466.       }
  467. }
  468.  
  469. void
  470. update_screen(src, dst, fil)
  471.    struct hostinfo *src, *dst;
  472.    struct fileinfo *fil;
  473. {
  474.    char temp[6];
  475.    boolean show_file;
  476.  
  477.    panel_set(op_item, PANEL_VALUE, op_choice(fil->reqtype), 0);
  478.    toggle_dest_items((fil->reqtype==DFILE)?FALSE:TRUE);
  479.    panel_set(sHost_item, PANEL_VALUE, src->host, 0);
  480.    panel_set(dHost_item, PANEL_VALUE, dst->host, 0);
  481.    panel_set(sLogin_item, PANEL_VALUE, src->user, 0);
  482.    panel_set(dLogin_item, PANEL_VALUE,dst->user, 0);
  483.    panel_set(sPass_item, PANEL_VALUE, src->passwd,
  484.        PANEL_LABEL_BOLD, (strlen(src->passwd))?TRUE:FALSE,
  485.     0);
  486.    panel_set(dPass_item, PANEL_VALUE, dst->passwd,
  487.        PANEL_LABEL_BOLD, (strlen(dst->passwd))?TRUE:FALSE,
  488.     0);
  489.    panel_set(sDir_item, PANEL_VALUE, src->dir, 0);
  490.    panel_set(dDir_item, PANEL_VALUE, dst->dir, 0);
  491.    panel_set(sAcct_item, PANEL_VALUE, src->acct, 0);
  492.    panel_set(dAcct_item, PANEL_VALUE, dst->acct, 0);
  493.    sprintf(temp,"%d",src->port);
  494.    panel_set(sPort_item, PANEL_VALUE, temp, 0);
  495.    sprintf(temp,"%d",dst->port);
  496.    panel_set(dPort_item, PANEL_VALUE, temp, 0);
  497.    panel_set(sFile_item, PANEL_VALUE, src->file, 0);
  498.    if (!strcmp(src->file, dst->file)) /* they're equal */
  499.       dst->file[0] = '\0';
  500.    show_file = ((!fil->multflag) ||(fil->creation==APPE))?TRUE:FALSE;
  501.    panel_set(dFile_item, 
  502.          PANEL_VALUE,     dst->file, 
  503.          PANEL_SHOW_ITEM,     show_file,
  504.          0);
  505.    if (!strlen(dst->file))
  506.       panel_set(dFileDef_msg, PANEL_SHOW_ITEM, show_file, 0);
  507.    update_params(fil);
  508. } /* update_screen */
  509.  
  510. void
  511. copy_screen(src, dst, fil)
  512.    struct hostinfo *src, *dst;
  513.    struct fileinfo *fil;
  514. {
  515.    char temp[6];
  516.    int type, form, bytesiz;
  517.  
  518.    verbose = (int)panel_get(verbose_item, PANEL_VALUE);
  519.  
  520.    strcpy(src->host, (char *)panel_get(sHost_item, PANEL_VALUE));
  521.    strcpy(src->user, (char *)panel_get(sLogin_item, PANEL_VALUE));
  522.    strcpy(src->passwd, (char *)panel_get(sPass_item, PANEL_VALUE));
  523.    if (empty_str(src->passwd)) src->passwd[0] = '\0';
  524.    strcpy(src->dir, (char *)panel_get(sDir_item, PANEL_VALUE));
  525.    strcpy(src->acct, (char *)panel_get(sAcct_item, PANEL_VALUE));
  526.    src->port = atoi((char *)panel_get(sPort_item, PANEL_VALUE));
  527.    strcpy(src->file, (char *)panel_get(sFile_item, PANEL_VALUE));
  528.  
  529.    strcpy(dst->host, (char *)panel_get(dHost_item, PANEL_VALUE));
  530.    strcpy(dst->user, (char *)panel_get(dLogin_item, PANEL_VALUE));
  531.    strcpy(dst->passwd, (char *)panel_get(dPass_item, PANEL_VALUE));
  532.    if (empty_str(dst->passwd)) dst->passwd[0] = '\0';
  533.    strcpy(dst->dir, (char *)panel_get(dDir_item, PANEL_VALUE));
  534.    strcpy(dst->acct, (char *)panel_get(dAcct_item, PANEL_VALUE));
  535.    dst->port = atoi((char *)panel_get(dPort_item, PANEL_VALUE));
  536.    
  537.    /* if visable, copy it, otherwise make it empty */
  538.    if ((int)panel_get(dFile_item, PANEL_SHOW_ITEM)) {
  539.       strcpy(dst->file, (char *)panel_get(dFile_item, PANEL_VALUE));
  540.       if (!strlen(dst->file))
  541.      strcpy(dst->file, src->file);
  542.       }
  543.    else
  544.       dst->file[0] = '\0';
  545.  
  546.    copy_fileparams(fil);
  547. } /* copy_screen */
  548.  
  549. /* Notify Procs for the Commands Subwindow */
  550.  
  551. static void
  552. quit_proc(item, event)
  553.    Panel_item item;
  554.    Event *event;
  555. {
  556.    if (fts_pid) {
  557.       kill(fts_pid, SIGKILL);
  558.       fts_pid = 0;
  559.       }
  560.    window_destroy(tool_frame);
  561. }
  562.  
  563. static void
  564. find_proc()
  565. {
  566.    set_buttons(FALSE);
  567.    make_find_frame();
  568. }
  569.  
  570. static void
  571. reset_text(sw)
  572.    Textsw sw;
  573. {
  574.    textsw_reset(sw, 0, 0);
  575.    window_set(sw, TEXTSW_READ_ONLY, TRUE, 0);
  576. }
  577.  
  578. static void
  579. clear_proc()
  580. {
  581.    update_screen(&nullhost, &nullhost, &defaultfile);
  582.    init_req(&req);
  583. }
  584.  
  585. static void
  586. submit_proc()
  587. {
  588.    set_buttons(FALSE);
  589.    make_submit_frame(&req, 60, 12, 
  590.              (int)panel_get(verbose_item, PANEL_ITEM_X),
  591.              (int)panel_get(verbose_item, PANEL_ITEM_Y));
  592. }
  593.  
  594. /* Notify Procs for the Commands Subwindow (continued)*/
  595.  
  596. static void
  597. explain_proc()
  598. {
  599.    set_buttons(FALSE);
  600.    make_fts_frame("Explain", 80, 20,
  601.           (int)panel_get(verbose_item, PANEL_ITEM_X),
  602.           (int)panel_get(verbose_item, PANEL_ITEM_Y));
  603.  
  604.    text_print(introduction);
  605.  
  606. text_print(
  607. "Mouse Functions:\n\
  608. \n\
  609.   The LEFT mouse button is used to position the cursor in a text field,\n\
  610.   and to select a command.\n\
  611. \n\
  612.   The CENTER mouse button is used to display help information. To test this\n\
  613.   feature, position the mouse pointer over a command/field label, such as\n\
  614.   'File:', and depress the center mouse button.\n\
  615. \n\
  616.   The RIGHT mouse button is used to display and fill in default values.\n\
  617.   To test this feature, position the mouse pointer over the label for a\n\
  618.   field, such as a 'Host' field.  Depress the right mouse button, highlight\n\
  619.   a value on the menu, and release the mouse button.\n");
  620.  
  621. text_print("\n\
  622. Parameters:\n\
  623. \n\
  624.   File transfer parameters, such as host names, logins, and file names,\n\
  625.   are entered into the appropriate fields on the BFTPTOOL.  Some such as,\n\
  626.   'Type' are selected by clicking the left mouse button over the field\n\
  627.   or depressing the right mouse button and making a menu selection.\n\
  628. \n\
  629.   Characters that are typed into a password field are not echoed; when such\n\
  630.   a field contains text, the label for the field is displayed in bold font.\n\
  631.   Although characters in a password field are invisible, they may deleted\n\
  632.   using the <delete> key, similarly to fields in which the contents are\n\
  633.   displayed.\n\
  634. ");
  635.  
  636. text_print("\n\
  637. Commands:\n\
  638. \n\
  639.   Some commands such as 'Verify', 'Submit', 'Transfer', and 'Find', create\n\
  640.   a popup window.  These popup windows prompt for additional information\n\
  641.   that is needed to complete the operation.  Each of these popup windows\n\
  642.   contains a 'Quit' subcommand, which can be used to terminate the command.\n\
  643. ");
  644.  
  645. text_print(background);
  646. textsw_normalize_view(fts_sw,0);
  647. }
  648.  
  649. Notify_value
  650. my_pipe_reader(me, fd)
  651.    int *me, fd;
  652. {
  653.    char c[2];
  654.    int n;
  655.  
  656.    while (fd_select(fd))
  657.       if (n = read(fd, c, 1)) {
  658.      (void)textsw_insert(fts_sw, c, n);
  659.      }
  660.       else {
  661.      if (close(fd) == -1)
  662.         perror("close0");
  663.      fts_pid = 0;
  664.      (void) notify_set_input_func(&fts_pid,
  665.                                       NOTIFY_FUNC_NULL, fd);
  666.      break;
  667.      }
  668.    return(NOTIFY_DONE);
  669. }
  670.  
  671. static void
  672. do_fts(transfer)
  673.    boolean transfer;
  674. {
  675.    char temp[100], path[100];
  676.    struct server_struct ssh, dsh;
  677.    u_long now;
  678.    int fd, nfds, pid, retcode, fildes[2];
  679.  
  680.    if (pipe(fildes) == -1) {
  681.       perror("pipe");
  682.       exit(1);
  683.       }
  684.    (void) notify_set_input_func(&fts_pid, my_pipe_reader, fildes[0]);
  685.    if (pid = fork()) {
  686.       if (pid == -1) {
  687.          perror("fork");
  688.      close(fildes[0]);
  689.      (void) notify_set_input_func(&fts_pid,
  690.                      NOTIFY_FUNC_NULL, fildes[0]);
  691.      close(fildes[1]);
  692.      return;
  693.      }
  694.       fts_pid = pid;
  695.       (void)notify_set_wait3_func(&fts_pid,
  696.                         notify_default_wait3, pid);
  697.       if (close(fildes[1]) == -1)
  698.          perror("close1");
  699.       }
  700.    else { /* this is the child process */
  701.       nfds = getdtablesize();         /* Get max number of fd's */
  702.       for (fd = 0; fd < nfds; fd++)   /* Close all unwanted fd's */
  703.      if (fd!=fildes[1])
  704.         (void)close(fd);
  705.  
  706.       if (dup2(fildes[1], 1) == -1) {
  707.         perror("dup2");
  708.         close(fildes[1]);
  709.         exit(1);
  710.         }
  711.       if (close(fildes[1]) == -1) {
  712.         perror("close-c1");
  713.         exit(1);
  714.         }
  715.  
  716.       if (!transfer) 
  717.         if (fil.reqtype == DFILE)
  718.            fil.reqtype = VERIFY_SRC;  /* set just in the child process */
  719.         else
  720.            fil.reqtype = VERIFY;
  721.  
  722.       tracefp = (verbose)?stdout:NULL;
  723.       logfp = stdout;
  724.  
  725.       format_time(0, temp);
  726.       fprintf(logfp,"\n  %s: starting...\n\n", temp);
  727.     
  728.       now = time(NULL);
  729.       sprintf(path,"%s%d",REQPREFIX,now);
  730.       sprintf(temp, "%s.req", path);
  731.      
  732.       bcopy((char *)&src, (char *)&ssh.h, sizeof(struct hostinfo));
  733.       bcopy((char *)&dst, (char *)&dsh.h, sizeof(struct hostinfo));
  734.       retcode = xfer(&ssh, &dsh, &fil, temp, NULL);
  735.      
  736.       sprintf(temp,"rm %s.list 1> /dev/null 2>&1\n", path);
  737.       system(temp);
  738.  
  739.       format_time(0, temp);
  740.       fprintf(logfp,"\n  %s: completed %ssuccessfully.\n\n", temp, 
  741.           (retcode == OK)?"":"un");
  742.  
  743.       fflush(logfp);
  744.       exit(0);
  745.       }
  746. } /* do_fts */
  747.  
  748. /* Notify Procs for the Commands Subwindow (continued) */
  749.  
  750. static void 
  751. verify_proc()
  752. {
  753.    set_buttons(FALSE);
  754.    make_fts_frame("Verify", 80, 20,
  755.           (int)panel_get(verbose_item, PANEL_ITEM_X),
  756.           (int)panel_get(verbose_item, PANEL_ITEM_Y));
  757.    copy_screen(&src, &dst, &fil);
  758.    if (find_errors(fts_sw, &src, &dst, &fil))
  759.       textsw_normalize_view(fts_sw,0);
  760.    else
  761.       do_fts(FALSE);
  762. }
  763.  
  764. static void
  765. transfer_proc()
  766. {
  767.    set_buttons(FALSE);
  768.    make_fts_frame("Transfer", 80, 20,
  769.           (int)panel_get(verbose_item, PANEL_ITEM_X),
  770.           (int)panel_get(verbose_item, PANEL_ITEM_Y));
  771.    copy_screen(&src, &dst, &fil);
  772.    if (find_errors(fts_sw, &src, &dst, &fil))
  773.       textsw_normalize_view(fts_sw,0);
  774.    else
  775.       do_fts(TRUE);
  776. }
  777.  
  778. /* Notify Proc for the Submit Window */
  779.  
  780. void
  781. do_submit()
  782. {
  783.    FILE *xxx;
  784.    char timestr[100], temp[100], path[100];
  785.    u_long now, start;
  786.  
  787.    now = time(NULL);
  788.  
  789.    scroll_to_end();
  790.  
  791.    copy_screen(&src, &dst, &fil);
  792.    if (find_errors(fts_sw, &src, &dst, &fil))
  793.       return;
  794.  
  795.    /* parse the start time */
  796.    strcpy(timestr, (char *)panel_get(startTime_item, PANEL_VALUE));
  797.    if (empty_str(timestr))
  798.       start = now;
  799.    else if (!parse_date(timestr, &start)) {
  800.       sprintf(temp," Date '%s' not parsed.\n",timestr);
  801.       text_print(temp);
  802.       panel_set(startTime_item, PANEL_VALUE, "now", 0);
  803.       return;
  804.       }
  805.  
  806.    /* copy request parameters from screen */
  807.    strcpy(req.rpasswd, (char *)panel_get(keyword_item, PANEL_VALUE));
  808.    if (empty_str(req.rpasswd)) req.rpasswd[0] = '\0';
  809.    strcpy(req.mailbox, (char *)panel_get(mailbox_item, PANEL_VALUE));
  810.    if (!mailbox_ok(req.mailbox, temp)) {
  811.       text_print(temp);
  812.       return;
  813.       }
  814.    req.interval = atoi((char *)panel_get(interval_item, PANEL_VALUE));
  815.    req.ntries = atoi((char *)panel_get(tries_item, PANEL_VALUE));
  816.  
  817.    sprintf(path,"%s%d",REQPREFIX,now);
  818.  
  819.    sprintf(temp, "%s.req", path);
  820.    sprintf(req.mailfile,"%s.msg",path);
  821.    sprintf(req.cmdfile,"%s.cmd",path);
  822.  
  823.    write_req(temp,&req,&src,&dst,&fil,NULL);
  824.  
  825.    sprintf(temp, "%s.cmd", path);
  826.    xxx = fdopen(open(temp,(O_WRONLY|O_CREAT),0600),"w");
  827.    fprintf(xxx, "%s -v %s.req\n", FXPATH, path);
  828.    fclose(xxx);
  829.  
  830.    sprintf(temp, "%s.msg", path);
  831.    xxx = fdopen(open(temp,(O_WRONLY|O_CREAT),0600),"w");
  832.    queue_req(&req, (now > start) ? now : start, temp);
  833.    print_req(xxx, &req, &src, &dst, &fil, FALSE);
  834.    fprintf(xxx,"\n%s\n",temp);
  835.    fclose(xxx);
  836.    strcat(temp,"\n\n");
  837.    text_print(temp);
  838. } /* do_submit */
  839.  
  840. /* Find Subwindow Notify Procs */
  841.  
  842. static void
  843. do_find()
  844. {
  845.    char temp[100], id[100];
  846.    char *filep;
  847.    int  okay = TRUE;    
  848.    FILE *grepfp;
  849.     
  850.    scroll_to_end();
  851.  
  852.    text_print("Find...\n");
  853.    if ((int) panel_get(id_item, PANEL_SHOW_ITEM)) {
  854.       strcpy(request, (char *)panel_get(id_item, PANEL_VALUE));
  855.       strcpy(keyword, (char *)panel_get(keyword_item, PANEL_VALUE));
  856.       if (empty_str(keyword)) keyword[0] = '\0';
  857.       if (!empty_str(request)) {
  858.          sprintf(filename,"%s.req",request);
  859.          if (!read_req(filename,
  860.              &tmpreq, &tmpsrc, &tmpdst, &tmpfil, listfile)) {
  861.         sprintf(temp,"    Request %s not found.\n",request);
  862.         text_print(temp);
  863.         okay = FALSE;
  864.             }
  865.          else if (strcmp(keyword, tmpreq.rpasswd) != 0) {
  866.             text_print("    Keyword does not match.\n");
  867.         okay = FALSE;
  868.         }
  869.          }
  870.       else {
  871.      while (filep = get_request_file(keyword)) {
  872.          if (read_req(filep,
  873.                  &tmpreq, &tmpsrc, &tmpdst, &tmpfil, listfile)) {
  874.         if (strcmp(keyword, tmpreq.rpasswd) == 0) {
  875.            strcpy(filename, filep);
  876.            break;
  877.            }
  878.             }
  879.          }
  880.      if (!filep) {
  881.         text_print("    No matching request was found.\n");
  882.         okay = FALSE;
  883.         }
  884.          }
  885.       }
  886.    else {
  887.       while (filep = get_request_file(keyword)) {
  888.      if (read_req(filep, &tmpreq, &tmpsrc, &tmpdst, &tmpfil, listfile)) {
  889.         if (!strcmp(keyword, tmpreq.rpasswd)) {
  890.         strcpy(filename, filep);
  891.         break;
  892.         }
  893.         }
  894.      }
  895.       if (!filep) {
  896.          text_print("    No more matching requests.\n");
  897.          okay = FALSE;
  898.      }
  899.       }
  900.  
  901.    if (!okay) {
  902.       panel_set(next_button, PANEL_SHOW_ITEM, FALSE, 0);
  903.       panel_set(cancel_button, PANEL_SHOW_ITEM, FALSE, 0);
  904.       panel_set(read_button, PANEL_SHOW_ITEM, FALSE, 0);
  905.       panel_set(find_button, PANEL_SHOW_ITEM, TRUE, 0);
  906.       panel_set(keyword_item, PANEL_SHOW_ITEM, TRUE, 0);
  907.       panel_set(id_item, PANEL_SHOW_ITEM, TRUE, 0);
  908.       }
  909.    else {
  910.       /* Display the request in the text subwidow. */
  911.       get_id(id, filename);
  912.       sprintf(temp,"\nRequest: %s\n\n",id);
  913.       text_print(temp);
  914.  
  915.       /* print_req equivalent */
  916.       sprintf(temp,"    Request type: %s\n",
  917.         (tmpfil.reqtype==COPY)?"COPY":
  918.         (tmpfil.reqtype==MOVE)?"MOVE":
  919.         (tmpfil.reqtype==DFILE)?"DFILE":
  920.         (tmpfil.reqtype==VERIFY)?"VERIFY":
  921.         (tmpfil.reqtype==VERIFY_SRC)?"VERIFY_SRC":
  922.         "unknown");
  923.       text_print(temp);
  924.       sprintf(temp,"    Source: %s,%s,XXX,%s,%d,%s,%s\n",
  925.           tmpsrc.host, tmpsrc.user, tmpsrc.acct, tmpsrc.port,
  926.        tmpsrc.dir, tmpsrc.file);
  927.       text_print(temp);
  928.       if ((tmpfil.reqtype != VERIFY_SRC) && (tmpfil.reqtype != DFILE)) {
  929.      sprintf(temp,"    Destination: %s,%s,XXX,%s,%d,%s,%s\n",
  930.        tmpdst.host, tmpdst.user, tmpdst.acct, tmpdst.port,
  931.        tmpdst.dir, tmpdst.file);
  932.            text_print(temp);
  933.      sprintf(temp,"    Stru: %c",tmpfil.stru);
  934.          text_print(temp);
  935.      sprintf(temp,", Mode: %c, Type: %s, Creation: %s\n",
  936.              tmpfil.mode, tmpfil.filetype,
  937.             (tmpfil.creation==APPE)?"APPE":
  938.             (tmpfil.creation==STOU)?"STOU":
  939.             "STOR");
  940.          text_print(temp);
  941.      }
  942.       sprintf(temp,"    Multiple matching: %s",
  943.                (tmpfil.multflag)?"TRUE": "FALSE");
  944.       text_print(temp);
  945.       if ((tmpfil.reqtype != VERIFY) && (tmpfil.reqtype != VERIFY_SRC)) {
  946.          sprintf(temp, ", Return mailbox: '%s'\n", tmpreq.mailbox);
  947.          text_print(temp);
  948.          sprintf(temp,
  949.          "    Remaining tries: %d, Current retry interval: %d minutes",
  950.               tmpreq.ntries, tmpreq.interval);
  951.          text_print(temp);
  952.          }
  953.       text_print("\n\n");
  954.  
  955.       /* Summarize */
  956.       if (!empty_str(tmpreq.mailfile)) {
  957.          text_print("History:\n\n");
  958.  
  959.      sprintf(temp,"egrep 'submitted|starting|completed' %s\n",
  960.              tmpreq.mailfile);
  961.          if (grepfp = popen(temp,"r")) {
  962.               while (fgets(temp, sizeof(temp), grepfp))
  963.            text_print(temp);
  964.         pclose(grepfp);
  965.             }
  966.          text_print("\n");
  967.          }
  968.       else
  969.          text_print("History: No mail file found!\n\n");
  970.  
  971.       panel_set(find_button, PANEL_SHOW_ITEM, FALSE, 0);
  972.       panel_set(keyword_item, PANEL_SHOW_ITEM, FALSE, 0);
  973.       panel_set(id_item, PANEL_SHOW_ITEM, FALSE, 0);
  974.       panel_set(next_button, PANEL_SHOW_ITEM, TRUE, 0);
  975.       panel_set(cancel_button, PANEL_SHOW_ITEM, TRUE, 0);
  976.       panel_set(read_button, PANEL_SHOW_ITEM, TRUE, 0);
  977.       if (!request_queued(filename))
  978.          text_print(
  979.      " This request is NOT queued; to resubmit it, click ChangeRequest.\n\n"
  980.      );
  981.       }
  982. } /* do_find */
  983.  
  984. static void
  985. findnext_proc()
  986. {
  987.    if (empty_str(request) && listp)
  988.     do_find();
  989.    else {
  990.        panel_set(next_button, PANEL_SHOW_ITEM, FALSE, 0);
  991.        panel_set(cancel_button, PANEL_SHOW_ITEM, FALSE, 0);
  992.        panel_set(read_button, PANEL_SHOW_ITEM, FALSE, 0);
  993.        panel_set(find_button, PANEL_SHOW_ITEM, TRUE, 0);
  994.        panel_set(keyword_item, PANEL_SHOW_ITEM, TRUE, 0);
  995.        panel_set(id_item, PANEL_SHOW_ITEM, TRUE, 0);
  996.        }
  997. }
  998.  
  999. static void
  1000. cancel_req()
  1001. {
  1002.    cancel_msg(filename, &tmpreq, tmpsrc.file, listfile);
  1003.    scroll_to_end();
  1004.    text_print("\n Previous request cancelled.\n");
  1005. }
  1006.  
  1007. static void
  1008. cancel_proc()
  1009. {
  1010.    cancel_req();
  1011.    findnext_proc();    
  1012. }
  1013.  
  1014.  
  1015. static void
  1016. read_proc()
  1017. {
  1018.    char temp[100];
  1019.  
  1020.    scroll_to_end();
  1021.    sprintf(temp, "Reading %s%s...\n", bftp_dir, filename);
  1022.    text_print(temp);
  1023.    if (! read_req(filename, &req, &src, &dst, &fil, temp))
  1024.          text_print("    Request file not found.\n");
  1025.    else
  1026.          update_screen(&src, &dst, &fil);
  1027.    text_print("    Done\n");
  1028.  
  1029.    cancel_req();
  1030.    quit_popup();
  1031. }
  1032.  
  1033. make_find_frame()
  1034. {
  1035.    Window sw_panel;
  1036.    int row = 0;
  1037.     
  1038.    popup_frame = window_create(tool_frame, FRAME,
  1039.            WIN_X, (int)panel_get(verbose_item, PANEL_ITEM_X),
  1040.         WIN_Y, (int)panel_get(verbose_item, PANEL_ITEM_Y),
  1041.         FRAME_NO_CONFIRM, TRUE,
  1042.         FRAME_DONE_PROC,    close_popup,
  1043.         0);
  1044.         
  1045.    sw_panel = window_create(popup_frame, PANEL,
  1046.            0);
  1047.    quitSW_item = panel_create_item(sw_panel, PANEL_BUTTON,
  1048.                 PANEL_LABEL_IMAGE,
  1049.             panel_button_image(sw_panel, "Quit", 0, 0),
  1050.         PANEL_EVENT_PROC,    dummy_event_proc,
  1051.         PANEL_NOTIFY_PROC,      quit_popup,
  1052.         0);
  1053.    find_button = panel_create_item(sw_panel, PANEL_BUTTON,
  1054.                 PANEL_LABEL_IMAGE,
  1055.             panel_button_image(sw_panel, "FindRequest", 0, 0),
  1056.         PANEL_EVENT_PROC,    dummy_event_proc,
  1057.         PANEL_NOTIFY_PROC,      do_find,
  1058.         0);
  1059.    next_button = panel_create_item(sw_panel, PANEL_BUTTON,
  1060.            PANEL_LABEL_X,        (int)panel_get(find_button,
  1061.                             PANEL_LABEL_X),
  1062.         PANEL_LABEL_Y,        (int)panel_get(find_button,
  1063.                             PANEL_LABEL_Y),
  1064.                 PANEL_LABEL_IMAGE,
  1065.             panel_button_image(sw_panel, "NextRequest", 0, 0),
  1066.         PANEL_EVENT_PROC,    dummy_event_proc,
  1067.         PANEL_NOTIFY_PROC,      findnext_proc,
  1068.         PANEL_SHOW_ITEM,     FALSE,
  1069.         0);
  1070.    cancel_button = panel_create_item(sw_panel, PANEL_BUTTON,
  1071.                 PANEL_LABEL_IMAGE,
  1072.             panel_button_image(sw_panel, "CancelRequest", 0, 0),
  1073.         PANEL_EVENT_PROC,    dummy_event_proc,
  1074.         PANEL_NOTIFY_PROC,      cancel_proc,
  1075.         PANEL_SHOW_ITEM,     FALSE,
  1076.         0);
  1077.    read_button = panel_create_item(sw_panel, PANEL_BUTTON,
  1078.                 PANEL_LABEL_IMAGE,
  1079.             panel_button_image(sw_panel, "ChangeRequest", 0, 0),
  1080.         PANEL_EVENT_PROC,    dummy_event_proc,
  1081.         PANEL_NOTIFY_PROC,      read_proc,
  1082.         PANEL_SHOW_ITEM,     FALSE,
  1083.         0);
  1084.    keyword_item = panel_create_item(sw_panel, PANEL_TEXT,
  1085.            PANEL_LABEL_X,        ATTR_COL(0),
  1086.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1087.            PANEL_LABEL_STRING,    "RequestKeyword:",
  1088.         PANEL_VALUE_DISPLAY_LENGTH, 5,
  1089.         PANEL_EVENT_PROC,    make_bold,
  1090.         PANEL_MASK_CHAR,    ' ',
  1091.         0);
  1092.    id_item = panel_create_item(sw_panel, PANEL_TEXT,
  1093.            PANEL_LABEL_X,        ATTR_COL(0),
  1094.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1095.            PANEL_LABEL_STRING,    "RequestID (optional):",
  1096.         PANEL_VALUE_DISPLAY_LENGTH, 20,
  1097.         PANEL_EVENT_PROC,    no_spaces,
  1098.         0);
  1099.    window_fit(sw_panel);
  1100.    window_fit_width(popup_frame);
  1101.  
  1102.    fts_sw = window_create(popup_frame, TEXTSW,
  1103.         WIN_WIDTH,        ATTR_COL(70),
  1104.          WIN_HEIGHT,        ATTR_ROW(20),
  1105.         TEXTSW_IGNORE_LIMIT,    TEXTSW_INFINITY,
  1106.            TEXTSW_READ_ONLY,     TRUE,
  1107.         0);
  1108.    window_fit(fts_sw);
  1109.  
  1110.    window_fit(popup_frame);
  1111.    window_set(popup_frame, WIN_SHOW, TRUE, 0);
  1112. } /* make_find_frame */
  1113.  
  1114. static void
  1115. create_param_items()
  1116. {
  1117.    int bwidth = 8,
  1118.        indent = 4,
  1119.        row = 0;
  1120.     
  1121.    quit_item = panel_create_item(params, PANEL_BUTTON,
  1122.            PANEL_LABEL_IMAGE,    
  1123.             panel_button_image(params, "Quit", bwidth, 0),
  1124.         PANEL_EVENT_PROC,    dummy_event_proc,
  1125.         PANEL_NOTIFY_PROC,    quit_proc,
  1126.         0);
  1127.    verify_item = panel_create_item(params, PANEL_BUTTON,
  1128.            PANEL_LABEL_IMAGE,    
  1129.             panel_button_image(params, "Verify", bwidth, 0),
  1130.         PANEL_EVENT_PROC,    dummy_event_proc,
  1131.         PANEL_NOTIFY_PROC,    verify_proc,
  1132.         0);
  1133.    submit_item = panel_create_item(params, PANEL_BUTTON,
  1134.            PANEL_LABEL_IMAGE,    
  1135.             panel_button_image(params, "Submit", bwidth, 0),
  1136.         PANEL_EVENT_PROC,    dummy_event_proc,
  1137.         PANEL_NOTIFY_PROC,    submit_proc,
  1138.         0);
  1139.    transfer_item = panel_create_item(params, PANEL_BUTTON,
  1140.            PANEL_LABEL_IMAGE,    
  1141.             panel_button_image(params, "Transfer", bwidth, 0),
  1142.         PANEL_EVENT_PROC,    dummy_event_proc,
  1143.         PANEL_NOTIFY_PROC,    transfer_proc,
  1144.         0);
  1145.    find_item = panel_create_item(params, PANEL_BUTTON,
  1146.            PANEL_LABEL_IMAGE,    
  1147.             panel_button_image(params, "Find", bwidth, 0),
  1148.         PANEL_EVENT_PROC,    dummy_event_proc,
  1149.         PANEL_NOTIFY_PROC,    find_proc,
  1150.         0);
  1151.  
  1152.    clear_item = panel_create_item(params, PANEL_BUTTON,
  1153.            PANEL_LABEL_X,        ATTR_COL(0),
  1154.         PANEL_LABEL_Y,        (ATTR_ROW(++row)+(row*10)),
  1155.            PANEL_LABEL_IMAGE,    
  1156.             panel_button_image(params, "Clear", bwidth, 0),
  1157.         PANEL_EVENT_PROC,    dummy_event_proc,
  1158.         PANEL_NOTIFY_PROC,    clear_proc,
  1159.         0);
  1160.    explain_item = panel_create_item(params, PANEL_BUTTON,
  1161.            PANEL_LABEL_IMAGE,    
  1162.             panel_button_image(params, "Explain", bwidth, 0),
  1163.         PANEL_EVENT_PROC,    dummy_event_proc,
  1164.         PANEL_NOTIFY_PROC,    explain_proc,
  1165.         0);
  1166.    storage_item = panel_create_item(params, PANEL_BUTTON,
  1167.            PANEL_LABEL_IMAGE,
  1168.             panel_button_image(params, "RequestStorage", bwidth, 0),
  1169.         PANEL_EVENT_PROC,    dummy_event_proc,
  1170.         PANEL_NOTIFY_PROC,    rStorage_proc,
  1171.         0);
  1172.  
  1173.    op_item = panel_create_item(params, PANEL_CHOICE,
  1174.            PANEL_LABEL_X,        ATTR_COL(0),
  1175.         PANEL_LABEL_Y,        (ATTR_ROW(++row)+(row*10)),
  1176.            PANEL_LABEL_STRING,    "Operation:",
  1177.         PANEL_CHOICE_STRINGS,     "copy", "move", "delete", 0,
  1178.         PANEL_VALUE,        op_choice(COPY),
  1179.         PANEL_DISPLAY_LEVEL,    PANEL_CURRENT,
  1180.         PANEL_NOTIFY_PROC,    op_proc,
  1181.         PANEL_EVENT_PROC,    dummy_event_proc,
  1182.         0);
  1183.    verbose_item = panel_create_item(params, PANEL_CHOICE,
  1184.            PANEL_LABEL_STRING,    "Verbose:",
  1185.         PANEL_CHOICE_STRINGS,     "FALSE", "TRUE", 0,
  1186.         PANEL_VALUE,        0,
  1187.         PANEL_DISPLAY_LEVEL,    PANEL_CURRENT,
  1188.         PANEL_EVENT_PROC,    dummy_event_proc,
  1189.         0);
  1190.    row++;
  1191.    src_item = panel_create_item(params, PANEL_MESSAGE,
  1192.            PANEL_LABEL_STRING,    "Source",
  1193.            PANEL_LABEL_X,        ATTR_COL(0),
  1194.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1195.         PANEL_EVENT_PROC,    dummy_event_proc,
  1196.         0);
  1197.         
  1198.    sHost_item = panel_create_item(params, PANEL_TEXT,
  1199.            PANEL_LABEL_X,        ATTR_COL(indent),
  1200.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1201.         ATTR_LIST,        host_attr,
  1202.         0);
  1203.    sLogin_item = panel_create_item(params, PANEL_TEXT,
  1204.         ATTR_LIST,        login_attr,
  1205.         PANEL_VALUE_DISPLAY_LENGTH, 11,
  1206.         0);
  1207.    sPass_item = panel_create_item(params, PANEL_TEXT,
  1208.         ATTR_LIST,        pass_attr,
  1209.         0);
  1210.    sDir_item = panel_create_item(params, PANEL_TEXT,
  1211.            PANEL_LABEL_X,        ATTR_COL(indent),
  1212.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1213.         ATTR_LIST,        dir_attr,
  1214.         0);
  1215.    sAcct_item = panel_create_item(params, PANEL_TEXT,
  1216.            PANEL_LABEL_STRING,    "Acct:",
  1217.         PANEL_VALUE_DISPLAY_LENGTH, 12,
  1218.         PANEL_EVENT_PROC,    no_spaces,
  1219.         0);
  1220.    sPort_item = panel_create_item(params, PANEL_TEXT,
  1221.         ATTR_LIST,              port_attr,
  1222.         0);
  1223.    sFile_item = panel_create_item(params, PANEL_TEXT,
  1224.            PANEL_LABEL_X,        ATTR_COL(indent),
  1225.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1226.         ATTR_LIST,        file_attr,
  1227.         PANEL_VALUE_DISPLAY_LENGTH, 40,
  1228.         0);
  1229.  
  1230.    dest_item = panel_create_item(params, PANEL_MESSAGE,
  1231.                 PANEL_LABEL_STRING,     "Destination",
  1232.         PANEL_LABEL_X,          ATTR_COL(0),
  1233.         PANEL_LABEL_Y,          ATTR_ROW(++row),
  1234.         PANEL_EVENT_PROC,    dummy_event_proc,
  1235.         0);
  1236.    dHost_item = panel_create_item(params, PANEL_TEXT,
  1237.            PANEL_LABEL_X,        ATTR_COL(indent),
  1238.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1239.         ATTR_LIST,        host_attr,
  1240.         0);
  1241.    dLogin_item = panel_create_item(params, PANEL_TEXT,
  1242.         ATTR_LIST,        login_attr,
  1243.         PANEL_VALUE_DISPLAY_LENGTH, 11,
  1244.         0);
  1245.    dPass_item = panel_create_item(params, PANEL_TEXT,
  1246.         ATTR_LIST,        pass_attr,
  1247.         0);
  1248.    dDir_item = panel_create_item(params, PANEL_TEXT,
  1249.            PANEL_LABEL_X,        ATTR_COL(indent),
  1250.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1251.         ATTR_LIST,        dir_attr,
  1252.         0);
  1253.    dAcct_item = panel_create_item(params, PANEL_TEXT,
  1254.            PANEL_LABEL_STRING,    "Acct:",
  1255.         PANEL_VALUE_DISPLAY_LENGTH, 12,
  1256.         PANEL_EVENT_PROC,    no_spaces,
  1257.         0);
  1258.    dPort_item = panel_create_item(params, PANEL_TEXT,
  1259.         ATTR_LIST,              port_attr,
  1260.         0);
  1261.         
  1262.    dFile_item = panel_create_item(params, PANEL_TEXT,
  1263.            PANEL_LABEL_X,        ATTR_COL(indent),
  1264.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1265.         ATTR_LIST,        file_attr,
  1266.         PANEL_VALUE_DISPLAY_LENGTH, 40,
  1267.         PANEL_EVENT_PROC,    hint_event_proc,
  1268.         0);
  1269.    dFileDef_msg = panel_create_item(params, PANEL_MESSAGE,
  1270.            PANEL_LABEL_X,        (int)panel_get(dFile_item,
  1271.                             PANEL_VALUE_X),
  1272.         PANEL_LABEL_Y,        (int)panel_get(dFile_item,
  1273.                             PANEL_VALUE_Y),
  1274.             PANEL_LABEL_STRING,      SAME_AS_SRC,
  1275.         0);
  1276.  
  1277.    param_item = panel_create_item(params, PANEL_MESSAGE,
  1278.            PANEL_LABEL_STRING,     "FTP Parameters",
  1279.                 PANEL_LABEL_X,          ATTR_COL(0),
  1280.                 PANEL_LABEL_Y,          ATTR_ROW(++row),
  1281.         PANEL_EVENT_PROC,    dummy_event_proc,
  1282.                 0);
  1283.    stru_item = panel_create_item(params, PANEL_CHOICE,
  1284.            PANEL_LABEL_X,        ATTR_COL(indent),
  1285.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1286.         ATTR_LIST,        stru_attr,
  1287.         0);
  1288.    mode_item = panel_create_item(params, PANEL_CHOICE,
  1289.         ATTR_LIST,        mode_attr,
  1290.         0);
  1291.    type_item = panel_create_item(params, PANEL_CHOICE,
  1292.         ATTR_LIST,              type_attr,
  1293.         0);
  1294.         
  1295.    format_item = panel_create_item(params, PANEL_CHOICE,
  1296.         ATTR_LIST,              form_attr,
  1297.         0);
  1298.    byteSize_item = panel_create_item(params, PANEL_TEXT,
  1299.         ATTR_LIST,              byte_attr,
  1300.            PANEL_LABEL_X,        (int)panel_get(format_item, 
  1301.                         PANEL_LABEL_X),
  1302.         PANEL_LABEL_Y,
  1303.                     (int)panel_get(format_item, 
  1304.                         PANEL_LABEL_Y),
  1305.         0);
  1306.    multiple_item = panel_create_item(params, PANEL_CHOICE,
  1307.            PANEL_LABEL_X,        ATTR_COL(indent),
  1308.         PANEL_LABEL_Y,        ATTR_ROW(++row),
  1309.         ATTR_LIST,              mult_attr,
  1310.         0);
  1311.    append_item = panel_create_item(params, PANEL_CHOICE,
  1312.         ATTR_LIST,              app_attr,
  1313.         0);
  1314.    stou_item = panel_create_item(params, PANEL_CHOICE,
  1315.         ATTR_LIST,              stou_attr,
  1316.         0);
  1317.  
  1318.    window_fit(params);
  1319.    window_fit(tool_frame);
  1320. } /* create_param_items */
  1321.  
  1322. static void
  1323. tool_help(name)
  1324.    char *name;
  1325. {
  1326.    fprintf(stderr,"Background File Transfer Program\n\n");
  1327.    frame_cmdline_help(name);
  1328. }
  1329.  
  1330. static Notify_value
  1331. clear_text(frame, status)
  1332.    Frame frame;
  1333.    Destroy_status status;
  1334. {
  1335.    if (fts_pid) {
  1336.       kill(fts_pid, SIGKILL);
  1337.       fts_pid = 0;
  1338.       }
  1339.    window_destroy(frame);
  1340. }
  1341.  
  1342. static void
  1343. close_proc()
  1344. {
  1345.    window_set(tool_frame, FRAME_CLOSED, TRUE, 0);
  1346.    quit_popup();
  1347. }
  1348.  
  1349. main(argc, argv)
  1350.    int argc;
  1351.    char *argv;
  1352. {
  1353.    Menu menu;
  1354.    Menu_item close_item;
  1355.    char frame_label[40];
  1356.  
  1357.    init_help();
  1358.    init_user();
  1359.    init_req(&req);
  1360.  
  1361.    init_src_file_menu();
  1362.    init_login_menu();
  1363.    init_passw_menu();
  1364.    init_host_menu();
  1365.    init_port_menu();
  1366.    init_attr_lists();
  1367.    
  1368.    strcpy(frame_label, "BFTP Tool  ");
  1369.    strcat(frame_label, version);
  1370.    tool_frame = window_create(NULL, FRAME,
  1371.            FRAME_LABEL,          frame_label,
  1372.         FRAME_ICON,           &bftp_icon, 
  1373.         FRAME_CMDLINE_HELP_PROC, tool_help,
  1374.         FRAME_ARGS,         argc, argv,
  1375.         WIN_ERROR_MSG,         "Can't create window.",
  1376.         FRAME_NO_CONFIRM,     TRUE,
  1377.         FRAME_DONE_PROC,    clear_text,
  1378.         0);
  1379.  
  1380.    menu = (Menu)window_get(tool_frame, WIN_MENU);
  1381.    close_item = menu_find(menu, MENU_STRING, "Close", 0);
  1382.    menu_set(close_item, MENU_ACTION_PROC, close_proc, 0);
  1383.         
  1384.    params = window_create(tool_frame, PANEL,
  1385.            PANEL_ITEM_X_GAP,    15,
  1386.         0);
  1387.    create_param_items(); 
  1388. /*
  1389.    text_sw = window_create(tool_frame, TEXTSW,
  1390.          WIN_HEIGHT,        ATTR_ROW(20),
  1391.         TEXTSW_IGNORE_LIMIT,    TEXTSW_INFINITY,
  1392.            TEXTSW_READ_ONLY,     TRUE,
  1393.         0);
  1394.    window_fit(text_sw);
  1395.    window_fit(tool_frame);
  1396. */
  1397.  
  1398.    init_rs_location(ATTR_COL(40),ATTR_ROW(2)); 
  1399.  
  1400.    window_main_loop(tool_frame);
  1401.    exit(0);
  1402. }
  1403.