home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / amigalib / d993 / muiffr.lha / MUIFFR / src / config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-05  |  25.0 KB  |  876 lines

  1. /*
  2.  *    config.c        © by Martin Steppler
  3.  *
  4.  */
  5.  
  6. #include "muiffr.h"
  7. #include "muiffr_locale.h"
  8.  
  9. #define CONFIGNAME "PROGDIR:muiffr.config"
  10. #define CONFBANNER "MUI Fido File Request Configuration\nDo not edit by hand!\n"
  11.  
  12. static int GetFileSize(UBYTE *filename, int *file_len, int quiet);
  13. static int GetLine(UBYTE *readbuf, int *read_pos, int filesize, UBYTE *dest, int dest_size);
  14.  
  15. int ConfAliasReady(void)
  16. {
  17.     int return_ok = FALSE;
  18.     struct NodeList *nl = app->app_NodeList, node_list;
  19.     UBYTE *buf;
  20.  
  21.     get(app->app_st_Conf_Alias, MUIA_String_Contents, &buf);
  22.  
  23.     if (!*buf)
  24.         DeleteNodeListEntry();
  25.     else
  26.     {
  27.         node_list.nl_Next = NULL;
  28.         node_list.nl_Alias = buf;
  29.         get(app->app_st_Conf_Node, MUIA_String_Contents, &buf);
  30.         node_list.nl_Node = buf;
  31.         get(app->app_st_Conf_List, MUIA_String_Contents, &buf);
  32.         node_list.nl_List = buf;
  33.         get(app->app_st_Conf_Font, MUIA_String_Contents, &buf);
  34.         node_list.nl_Font = buf;
  35.         get(app->app_st_Conf_Phone, MUIA_String_Contents, &buf);
  36.         node_list.nl_Phone = buf;
  37.         get(app->app_st_Conf_Password, MUIA_String_Contents, &buf);
  38.         node_list.nl_Password = buf;
  39.  
  40.         if (!nl)
  41.         {
  42.             if (!AddNodeListEntry(&node_list, DONT_BE_SILENT, NODELIST_APPEND))
  43.                 goto abort;
  44.         }
  45.         else
  46.         {
  47.             if (!AddNodeListEntry(&node_list, DONT_BE_SILENT, NODELIST_REPLACE))
  48.                 goto abort;
  49.         }
  50.     }
  51.  
  52.     return_ok = TRUE;
  53. abort:
  54.     return (return_ok);
  55. }
  56.  
  57. int AddNodeListEntryInteractively(void)
  58. {
  59.     int return_ok = FALSE;
  60.     struct NodeList node_list;
  61.     UBYTE *buf;
  62.  
  63.     node_list.nl_Next = NULL;
  64.     get(app->app_st_Conf_Alias, MUIA_String_Contents, &buf);
  65.     node_list.nl_Alias = buf;
  66.     get(app->app_st_Conf_Node, MUIA_String_Contents, &buf);
  67.     node_list.nl_Node = buf;
  68.     get(app->app_st_Conf_List, MUIA_String_Contents, &buf);
  69.     node_list.nl_List = buf;
  70.     get(app->app_st_Conf_Font, MUIA_String_Contents, &buf);
  71.     node_list.nl_Font = buf;
  72.     get(app->app_st_Conf_Phone, MUIA_String_Contents, &buf);
  73.     node_list.nl_Phone = buf;
  74.     get(app->app_st_Conf_Password, MUIA_String_Contents, &buf);
  75.     node_list.nl_Password = buf;
  76.  
  77.     if (!AddNodeListEntry(&node_list, DONT_BE_SILENT, NODELIST_APPEND))
  78.         goto abort;
  79.  
  80.     return_ok = TRUE;
  81. abort:
  82.     return (return_ok);
  83. }
  84.  
  85. int AddNodeListEntry(struct NodeList *node_list, int quiet, int mode)
  86. {
  87.     int return_ok = FALSE;
  88.     struct NodeList *nl = NULL;
  89.     struct NodeList *nl_walk;
  90.  
  91.     if (!(nl = (struct NodeList *)AllocVec(sizeof(struct NodeList), MEMF_CLEAR)))
  92.         goto abort;
  93.  
  94.     if (!(nl->nl_Alias = (UBYTE *)AllocVec(strlen(node_list->nl_Alias) + 1, MEMF_CLEAR)))
  95.         goto abort;
  96.     strcpy(nl->nl_Alias, node_list->nl_Alias);
  97.  
  98.     if (!(nl->nl_Node = (UBYTE *)AllocVec(strlen(node_list->nl_Node) + 1, MEMF_CLEAR)))
  99.         goto abort;
  100.     strcpy(nl->nl_Node, node_list->nl_Node);
  101.  
  102.     if (!(nl->nl_List = (UBYTE *)AllocVec(strlen(node_list->nl_List) + 1, MEMF_CLEAR)))
  103.         goto abort;
  104.     strcpy(nl->nl_List, node_list->nl_List);
  105.  
  106.     if (!(nl->nl_Font = (UBYTE *)AllocVec(strlen(node_list->nl_Font) + 1, MEMF_CLEAR)))
  107.         goto abort;
  108.     strcpy(nl->nl_Font, node_list->nl_Font);
  109.  
  110.     if (!(nl->nl_Phone = (UBYTE *)AllocVec(strlen(node_list->nl_Phone) + 1, MEMF_CLEAR)))
  111.         goto abort;
  112.     strcpy(nl->nl_Phone, node_list->nl_Phone);
  113.  
  114.     if (!(nl->nl_Password = (UBYTE *)AllocVec(strlen(node_list->nl_Password) + 1, MEMF_CLEAR)))
  115.         goto abort;
  116.     strcpy(nl->nl_Password, node_list->nl_Password);
  117.  
  118.     if (mode == NODELIST_APPEND)
  119.     {
  120.         // append entry
  121.         if (nl_walk = app->app_NodeList)
  122.         {
  123.             while (nl_walk->nl_Next)
  124.                 nl_walk = nl_walk->nl_Next;
  125.             nl_walk->nl_Next = nl;
  126.         }
  127.         else
  128.             app->app_NodeList = nl;
  129.  
  130.         // now add entry
  131.         DoMethod(app->app_lv_Conf_NodeList, MUIM_List_Insert,
  132.                  &nl->nl_Alias, 1, MUIV_List_Insert_Bottom);
  133.         set(app->app_lv_Conf_NodeList, MUIA_List_Active, MUIV_List_Active_Bottom);
  134.     }
  135.     else if (mode == NODELIST_REPLACE)
  136.     {
  137.         LONG pos = -1, count = 0, pos_bak;
  138.  
  139.  
  140.         nl_walk = app->app_NodeList;
  141.         if (nl_walk)
  142.         {
  143.             for (; nl_walk; nl_walk = nl_walk->nl_Next)
  144.                 count++;
  145.  
  146.             nl_walk = app->app_NodeList;
  147.  
  148.             // cursor position
  149.             get(app->app_lv_Conf_NodeList, MUIA_List_Active, &pos);
  150.             if (pos >= 0)
  151.             {
  152.                 struct NodeList nl_copy;
  153.  
  154.                 pos_bak = pos;
  155.                 // jump to selected entry
  156.                 while (pos > 0)
  157.                 {
  158.                     nl_walk = nl_walk->nl_Next;
  159.                     pos--;
  160.                 }
  161.                 CopyMem(nl_walk, &nl_copy, sizeof(struct NodeList));
  162.  
  163.                 // remove entry
  164.                 DoMethod(app->app_lv_Conf_NodeList, MUIM_List_Remove, pos_bak);
  165.                 nl_walk->nl_Alias = nl->nl_Alias;
  166.                 nl_walk->nl_Node = nl->nl_Node;
  167.                 nl_walk->nl_List = nl->nl_List;
  168.                 nl_walk->nl_Font = nl->nl_Font;
  169.                 nl_walk->nl_Phone = nl->nl_Phone;
  170.                 nl_walk->nl_Password = nl->nl_Password;
  171.  
  172.                 // readd entry
  173.                 DoMethod(app->app_lv_Conf_NodeList, MUIM_List_Insert,
  174.                          &nl_walk->nl_Alias, 1,
  175.                          (pos_bak + 1 == count) ? MUIV_List_Insert_Bottom : pos_bak);
  176.                 set(app->app_lv_Conf_NodeList, MUIA_List_Active, pos_bak);
  177.  
  178.                 FreeVec(nl_copy.nl_Alias);
  179.                 FreeVec(nl_copy.nl_Node);
  180.                 FreeVec(nl_copy.nl_List);
  181.                 FreeVec(nl_copy.nl_Font);
  182.                 FreeVec(nl_copy.nl_Phone);
  183.                 FreeVec(nl_copy.nl_Password);
  184.             }
  185.             else
  186.             {
  187.                 quiet = BE_SILENT;
  188.                 goto abort;
  189.             }
  190.         }
  191.         else
  192.         {
  193.             quiet = BE_SILENT;
  194.             goto abort;
  195.         }
  196.     }
  197.  
  198.     return_ok = TRUE;
  199. abort:
  200.     if (!return_ok)
  201.     {
  202.         if (nl)
  203.         {
  204.             if (nl->nl_Alias)
  205.                 FreeVec(nl->nl_Alias);
  206.             if (nl->nl_Node)
  207.                 FreeVec(nl->nl_Node);
  208.             if (nl->nl_List)
  209.                 FreeVec(nl->nl_List);
  210.             if (nl->nl_Font)
  211.                 FreeVec(nl->nl_Font);
  212.             if (nl->nl_Phone)
  213.                 FreeVec(nl->nl_Phone);
  214.             if (nl->nl_Password)
  215.                 FreeVec(nl->nl_Password);
  216.             FreeVec(nl);
  217.         }
  218.         if (!quiet)
  219.             DispError(MSG_ERROR_OUT_OF_MEMORY, NULL);
  220.     }
  221.     else if (mode == NODELIST_REPLACE)
  222.     {
  223.         if (nl)
  224.             FreeVec(nl);
  225.     }
  226.     return (return_ok);
  227. }
  228.  
  229. void DeleteNodeListEntry(void)
  230. {
  231.     // non empty list
  232.     if (app->app_NodeList)
  233.     {
  234.         LONG pos = -1;
  235.         struct NodeList **nl = &app->app_NodeList, *nl_delete;
  236.  
  237.         get(app->app_lv_Conf_NodeList, MUIA_List_Active, &pos);
  238.         if (pos >= 0)
  239.         {
  240.             DoMethod(app->app_lv_Conf_NodeList, MUIM_List_Remove, pos);
  241.  
  242.             // jump to selected entry
  243.             while (pos > 0)
  244.             {
  245.                 nl = &(*nl)->nl_Next;
  246.                 pos--;
  247.             }
  248.  
  249.             // delete from chain and free mem
  250.             if (*nl)
  251.             {
  252.                 nl_delete = *nl;
  253.                 *nl = (*nl)->nl_Next;
  254.  
  255.                 // update gadgets
  256.                 NodeListDoubleClick();
  257.  
  258.                 if (nl_delete->nl_Alias)
  259.                     FreeVec(nl_delete->nl_Alias);
  260.                 if (nl_delete->nl_Node)
  261.                     FreeVec(nl_delete->nl_Node);
  262.                 if (nl_delete->nl_List)
  263.                     FreeVec(nl_delete->nl_List);
  264.                 if (nl_delete->nl_Font)
  265.                     FreeVec(nl_delete->nl_Font);
  266.                 if (nl_delete->nl_Phone)
  267.                     FreeVec(nl_delete->nl_Phone);
  268.                 if (nl_delete->nl_Password)
  269.                     FreeVec(nl_delete->nl_Password);
  270.                 FreeVec(nl_delete);
  271.             }
  272.         }
  273.     }
  274. }
  275. void ClearNodeList(void)
  276. {
  277.     if (app->app_NodeList)
  278.     {
  279.         struct NodeList *nl = app->app_NodeList, *nl_next;
  280.  
  281.         do
  282.         {
  283.             if (nl->nl_Alias)
  284.                 FreeVec(nl->nl_Alias);
  285.             if (nl->nl_Node)
  286.                 FreeVec(nl->nl_Node);
  287.             if (nl->nl_List)
  288.                 FreeVec(nl->nl_List);
  289.             if (nl->nl_Font)
  290.                 FreeVec(nl->nl_Font);
  291.             if (nl->nl_Phone)
  292.                 FreeVec(nl->nl_Phone);
  293.             if (nl->nl_Password)
  294.                 FreeVec(nl->nl_Password);
  295.             nl_next = nl->nl_Next;
  296.             FreeVec(nl);
  297.             nl = nl_next;
  298.         }
  299.         while (nl);
  300.         app->app_NodeList = NULL;
  301.     }
  302. }
  303. void NodeListDoubleClick(void)
  304. {
  305.     LONG pos = -1;
  306.     struct NodeList *nl = app->app_NodeList;
  307.  
  308.     if (nl)
  309.     {
  310.         get(app->app_lv_Conf_NodeList, MUIA_List_Active, &pos);
  311.         if (pos >= 0)
  312.         {
  313.             // jump to selected entry
  314.             while (pos > 0)
  315.             {
  316.                 nl = nl->nl_Next;
  317.                 pos--;
  318.             }
  319.  
  320.             // set string gadgets accordingly
  321.             set(app->app_st_Conf_Alias, MUIA_String_Contents, nl->nl_Alias);
  322.             set(app->app_st_Conf_Node, MUIA_String_Contents, nl->nl_Node);
  323.             set(app->app_st_Conf_List, MUIA_String_Contents, nl->nl_List);
  324.             set(app->app_st_Conf_Font, MUIA_String_Contents, nl->nl_Font);
  325.             set(app->app_st_Conf_Phone, MUIA_String_Contents, nl->nl_Phone);
  326.             set(app->app_st_Conf_Password, MUIA_String_Contents, nl->nl_Password);
  327.         }
  328.     }
  329.     else
  330.     {
  331.         // set string gadgets accordingly
  332.         set(app->app_st_Conf_Alias, MUIA_String_Contents, app->app_Conf_AliasBuf);
  333.         set(app->app_st_Conf_Node, MUIA_String_Contents, app->app_Conf_NodeBuf);
  334.         set(app->app_st_Conf_List, MUIA_String_Contents, app->app_Conf_ListBuf);
  335.         set(app->app_st_Conf_Font, MUIA_String_Contents, app->app_Conf_FontBuf);
  336.         set(app->app_st_Conf_Phone, MUIA_String_Contents, app->app_Conf_PhoneBuf);
  337.         set(app->app_st_Conf_Password, MUIA_String_Contents, app->app_Conf_PasswordBuf);
  338.     }
  339. }
  340.  
  341. int UpdateNodelist(int buf_num)
  342. {
  343.     int return_ok = FALSE;
  344.  
  345.     LONG pos = -1;
  346.     struct NodeList *nl = app->app_NodeList;
  347.     UBYTE *buf, **buf_ptr, *new_buf;
  348.     APTR strgad;
  349.  
  350.     if (nl)
  351.     {
  352.         get(app->app_lv_Conf_NodeList, MUIA_List_Active, &pos);
  353.         if (pos >= 0)
  354.         {
  355.             // jump to selected entry
  356.             while (pos > 0)
  357.             {
  358.                 nl = nl->nl_Next;
  359.                 pos--;
  360.             }
  361.  
  362.             if (buf_num == NODE_BUF_NUM)
  363.             {
  364.                 get(strgad = app->app_st_Conf_Node, MUIA_String_Contents, &buf);
  365.                 buf_ptr = &nl->nl_Node;
  366.             }
  367.             else if (buf_num == LIST_BUF_NUM)
  368.             {
  369.                 get(strgad = app->app_st_Conf_List, MUIA_String_Contents, &buf);
  370.                 buf_ptr = &nl->nl_List;
  371.             }
  372.             else if (buf_num == FONT_BUF_NUM)
  373.             {
  374.                 get(strgad = app->app_st_Conf_Font, MUIA_String_Contents, &buf);
  375.                 buf_ptr = &nl->nl_Font;
  376.             }
  377.             else if (buf_num == PHONE_BUF_NUM)
  378.             {
  379.                 get(strgad = app->app_st_Conf_Phone, MUIA_String_Contents, &buf);
  380.                 buf_ptr = &nl->nl_Phone;
  381.             }
  382.             else if (buf_num == PASSWORD_BUF_NUM)
  383.             {
  384.                 get(strgad = app->app_st_Conf_Password, MUIA_String_Contents, &buf);
  385.                 buf_ptr = &nl->nl_Password;
  386.             }
  387.  
  388.             if (!(new_buf = (UBYTE *)AllocVec(strlen(buf) + 1, MEMF_CLEAR)))
  389.                 goto abort;
  390.             strcpy(new_buf, buf);
  391.             buf = *buf_ptr;
  392.             *buf_ptr = new_buf;
  393.  
  394.             // set string gadgets accordingly
  395.             set(strgad, MUIA_String_Contents, new_buf);
  396.             FreeVec(buf);
  397.         }
  398.     }
  399.  
  400.     return_ok = TRUE;
  401. abort:
  402.     if (!return_ok)
  403.         DispError(MSG_ERROR_OUT_OF_MEMORY, NULL);
  404.     return (return_ok);
  405. }
  406.  
  407. void SaveConfig(void)
  408. {
  409.     int return_ok = FALSE;
  410.     UBYTE *buf, *confname;
  411.     FILE *stream = NULL;
  412.     int error = TRUE;
  413.  
  414.     confname = CONFIGNAME;
  415.     if (!(stream = fopen(confname, "w")))
  416.     {
  417.         error = FALSE;
  418.         DispError(MSG_ERROR_CANT_OPEN, confname);
  419.         goto abort;
  420.     }
  421.  
  422.     if (fprintf(stream, "%s", CONFBANNER) < 0)
  423.         goto abort;
  424.  
  425.     get(app->app_st_Main_Aliases, MUIA_String_Contents, &buf);
  426.     if (fprintf(stream, "%s\n", buf) < 0)
  427.         goto abort;
  428.  
  429.     get(app->app_st_Main_Password, MUIA_String_Contents, &buf);
  430.     if (fprintf(stream, "%s\n", buf) < 0)
  431.         goto abort;
  432.  
  433.     get(app->app_st_Main_Find, MUIA_String_Contents, &buf);
  434.     if (fprintf(stream, "%s\n", buf) < 0)
  435.         goto abort;
  436.  
  437.     get(app->app_st_Conf_Outbound, MUIA_String_Contents, &buf);
  438.     if (fprintf(stream, "%s\n", buf) < 0)
  439.         goto abort;
  440.  
  441.     if (app->app_Flags & APP_CYA_CONF_TERM_CRLF)
  442.         fprintf(stream, "CRLF\n");
  443.     else
  444.         fprintf(stream, "LF\n");
  445.     if (ferror(stream))
  446.         goto abort;
  447.  
  448.     {
  449.         LONG pos = 1;
  450.  
  451.         get(app->app_sl_Conf_FileNamePos, MUIA_Slider_Level, &pos);
  452.         if (fprintf(stream, "%d\n", pos) < 0)
  453.             goto abort;
  454.     }
  455.  
  456.     get(app->app_st_Conf_ViaNumber, MUIA_String_Contents, &buf);
  457.     if (fprintf(stream, "%s\n", buf) < 0)
  458.         goto abort;
  459.  
  460.     get(app->app_st_Conf_ViaNode, MUIA_String_Contents, &buf);
  461.     if (fprintf(stream, "%s\n", buf) < 0)
  462.         goto abort;
  463.  
  464.     get(app->app_st_Conf_NodeList, MUIA_String_Contents, &buf);
  465.     if (fprintf(stream, "%s\n", buf) < 0)
  466.         goto abort;
  467.  
  468.     {
  469.         struct NodeList *nl = app->app_NodeList;
  470.  
  471.         for (; nl; nl = nl->nl_Next)
  472.         {
  473.             if (fprintf(stream, "%s\n", nl->nl_Alias) < 0)
  474.                 goto abort;
  475.  
  476.             if (fprintf(stream, "%s\n", nl->nl_Node) < 0)
  477.                 goto abort;
  478.  
  479.             if (fprintf(stream, "%s\n", nl->nl_Phone) < 0)
  480.                 goto abort;
  481.  
  482.             if (fprintf(stream, "%s\n", nl->nl_Password) < 0)
  483.                 goto abort;
  484.  
  485.             if (fprintf(stream, "%s\n", nl->nl_List) < 0)
  486.                 goto abort;
  487.  
  488.             if (fprintf(stream, "%s\n", nl->nl_Font) < 0)
  489.                 goto abort;
  490.         }
  491.     }
  492.  
  493.     return_ok = TRUE;
  494. abort:
  495.     if (stream)
  496.         fclose(stream);
  497.     if (!return_ok && error)
  498.         DispError(MSG_ERROR_WHILE_WRITING, confname);
  499.     if (return_ok)
  500.         DispError(MSG_INFO_CONFIG_SAVED, NULL);
  501. }
  502.  
  503. int LoadConfig(int quiet)
  504. {
  505.     int return_ok = FALSE;
  506.     UBYTE buffer[BUF_SIZE], *confname, *readbuf = NULL;
  507.     FILE *stream = NULL;
  508.     int error = TRUE;
  509.     int filenamepos = 1;
  510.     int filesize, read_pos = 0;
  511.  
  512.     confname = CONFIGNAME;
  513.     if (!(stream = fopen(confname, "r")))
  514.     {
  515.         error = FALSE;
  516.         if (!quiet)
  517.             DispError(MSG_ERROR_CANT_OPEN, confname);
  518.         goto abort;
  519.     }
  520.  
  521.     if (!GetFileSize(confname, &filesize, quiet))
  522.     {
  523.         error = FALSE;
  524.         goto abort;
  525.     }
  526.  
  527.     if (!(readbuf = (UBYTE *)AllocVec(filesize, MEMF_CLEAR)))
  528.     {
  529.         error = FALSE;
  530.         if (!quiet)
  531.             DispError(MSG_ERROR_OUT_OF_MEMORY, confname);
  532.         goto abort;
  533.     }
  534.  
  535.     if (fread(readbuf, 1, filesize, stream) != filesize)
  536.     {
  537.         error = FALSE;
  538.         if (!quiet)
  539.             DispError(MSG_ERROR_WHILE_READING, confname);
  540.         goto abort;
  541.     }
  542.  
  543.     // skip banner
  544.     if (!GetLine(readbuf, &read_pos, filesize, buffer, BUF_SIZE))
  545.         goto abort;
  546.     if (!GetLine(readbuf, &read_pos, filesize, buffer, BUF_SIZE))
  547.         goto abort;
  548.  
  549.     // alias
  550.     if (!GetLine(readbuf, &read_pos, filesize, buffer, ALIASSIZE))
  551.         goto abort;
  552.     strncpy(app->app_Main_AliasesBuf, buffer, ALIASSIZE - 1);
  553.  
  554.     // password
  555.     if (!GetLine(readbuf, &read_pos, filesize, buffer, STANDARDSIZE))
  556.         goto abort;
  557.     strncpy(app->app_Main_PasswordBuf, buffer, STANDARDSIZE - 1);
  558.  
  559.     // find
  560.     if (!GetLine(readbuf, &read_pos, filesize, buffer, STANDARDSIZE))
  561.         goto abort;
  562.     strncpy(app->app_Main_FindBuf, buffer, STANDARDSIZE - 1);
  563.  
  564.     // outbound
  565.     if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  566.         goto abort;
  567.     strncpy(app->app_Conf_OutboundBuf, buffer, PATHSIZE - 1);
  568.  
  569.     // termination
  570.     if (!GetLine(readbuf, &read_pos, filesize, buffer, STANDARDSIZE))
  571.         goto abort;
  572.     if (!strcmp(buffer, "CRLF"))
  573.         app->app_Flags |= APP_CYA_CONF_TERM_CRLF;
  574.     else
  575.         app->app_Flags &= ~APP_CYA_CONF_TERM_CRLF;
  576.  
  577.     // filenamepos
  578.     if (!GetLine(readbuf, &read_pos, filesize, buffer, STANDARDSIZE))
  579.         goto abort;
  580.     filenamepos = atoi(buffer);
  581.     if (filenamepos < 1 || filenamepos > MAX_FILENAMEPOS)
  582.         filenamepos = 1;
  583.  
  584.     // via number
  585.     if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  586.         goto abort;
  587.     strncpy(app->app_Conf_ViaNumberBuf, buffer, PATHSIZE - 1);
  588.  
  589.     // via node
  590.     if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  591.         goto abort;
  592.     strncpy(app->app_Conf_ViaNodeBuf, buffer, PATHSIZE - 1);
  593.  
  594.     // nodelist
  595.     if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  596.         goto abort;
  597.     strncpy(app->app_Conf_NodeListBuf, buffer, PATHSIZE - 1);
  598.  
  599.     // clear gadgets
  600.     set(app->app_st_Conf_Alias, MUIA_String_Contents, app->app_Conf_AliasBuf);
  601.     set(app->app_st_Conf_Node, MUIA_String_Contents, app->app_Conf_NodeBuf);
  602.     set(app->app_st_Conf_List, MUIA_String_Contents, app->app_Conf_ListBuf);
  603.     set(app->app_st_Conf_Font, MUIA_String_Contents, app->app_Conf_FontBuf);
  604.     set(app->app_st_Conf_Phone, MUIA_String_Contents, app->app_Conf_PhoneBuf);
  605.     set(app->app_st_Conf_Password, MUIA_String_Contents, app->app_Conf_PasswordBuf);
  606.     DoMethod(app->app_lv_Conf_NodeList, MUIM_List_Clear, TAG_IGNORE);
  607.     ClearNodeList();
  608.  
  609.     // set gadgets
  610.     set(app->app_st_Main_Aliases, MUIA_String_Contents, app->app_Main_AliasesBuf);
  611.     set(app->app_st_Main_Password, MUIA_String_Contents, app->app_Main_PasswordBuf);
  612.     set(app->app_st_Main_Find, MUIA_String_Contents, app->app_Main_FindBuf);
  613.     set(app->app_st_Conf_Outbound, MUIA_String_Contents, app->app_Conf_OutboundBuf);
  614.     set(app->app_sl_Conf_FileNamePos, MUIA_Slider_Level, filenamepos);
  615.     set(app->app_cy_Conf_Termination, MUIA_Cycle_Active, (app->app_Flags & APP_CYA_CONF_TERM_CRLF) ? CYA_CONF_TERM_CRLF : CYA_CONF_TERM_LF);
  616.     set(app->app_st_Conf_ViaNumber, MUIA_String_Contents, app->app_Conf_ViaNumberBuf);
  617.     set(app->app_st_Conf_ViaNode, MUIA_String_Contents, app->app_Conf_ViaNodeBuf);
  618.     set(app->app_st_Conf_NodeList, MUIA_String_Contents, app->app_Conf_NodeListBuf);
  619.  
  620.     // get nodes
  621.     {
  622.         struct NodeList node_list;
  623.         int end_of_file = FALSE;
  624.         UBYTE alias_buf[ALIASSIZE], node_buf[NODESIZE],
  625.               list_buf[PATHSIZE], font_buf[PATHSIZE],
  626.               phone_buf[PATHSIZE], password_buf[PATHSIZE];
  627.  
  628.         node_list.nl_Next = NULL;
  629.         node_list.nl_Alias = alias_buf;
  630.         node_list.nl_Node = node_buf;
  631.         node_list.nl_List = list_buf;
  632.         node_list.nl_Font = font_buf;
  633.         node_list.nl_Phone = phone_buf;
  634.         node_list.nl_Password = password_buf;
  635.  
  636.         while (!end_of_file)
  637.         {
  638.             // alias
  639.             if (!GetLine(readbuf, &read_pos, filesize, buffer, ALIASSIZE))
  640.             {
  641.                 end_of_file = TRUE;
  642.                 continue;
  643.             }
  644.             strncpy(alias_buf, buffer, ALIASSIZE - 1);
  645.  
  646.             // node
  647.             if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  648.                 goto abort;
  649.             strncpy(node_buf, buffer, PATHSIZE - 1);
  650.  
  651.             // phone
  652.             if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  653.                 goto abort;
  654.             strncpy(phone_buf, buffer, PATHSIZE - 1);
  655.  
  656.             // password
  657.             if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  658.                 goto abort;
  659.             strncpy(password_buf, buffer, PATHSIZE - 1);
  660.  
  661.             // list
  662.             if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  663.                 goto abort;
  664.             strncpy(list_buf, buffer, PATHSIZE - 1);
  665.  
  666.             // font
  667.             if (!GetLine(readbuf, &read_pos, filesize, buffer, PATHSIZE))
  668.                 goto abort;
  669.             strncpy(font_buf, buffer, PATHSIZE - 1);
  670.  
  671.             if (!AddNodeListEntry(&node_list, quiet, NODELIST_APPEND))
  672.             {
  673.                 error = FALSE;
  674.                 goto abort;
  675.             }
  676.         }
  677.     }
  678.  
  679.     // select node in nodelist and load filelist
  680.     {
  681.         LONG pos = 0, count = -1;
  682.         struct NodeList *nl = app->app_NodeList;
  683.  
  684.         if (nl)
  685.         {
  686.             get(app->app_lv_Conf_NodeList, MUIA_List_Entries, &count);
  687.  
  688.             for (; pos < count; pos++, nl = nl->nl_Next)
  689.                 if (!strcmp(app->app_Main_AliasesBuf, nl->nl_Alias))
  690.                     break;
  691.  
  692.             if (pos < count)
  693.             {
  694.                 // refresh configuration window
  695.                 set(app->app_lv_Conf_NodeList, MUIA_List_Active, pos);
  696.                 NodeListDoubleClick();
  697.  
  698.                 if (!ReadList(quiet))
  699.                 {
  700.                     error = FALSE;
  701.                     goto abort;
  702.                 }
  703.             }
  704.             else
  705.             {
  706.                 if (!quiet)
  707.                     DispError(MSG_ERROR_UNKNOWN_ALIAS, app->app_Main_AliasesBuf);
  708.                 error = FALSE;
  709.                 goto abort;
  710.             }
  711.         }
  712.     }
  713.  
  714.     return_ok = TRUE;
  715. abort:
  716.     if (stream)
  717.         fclose(stream);
  718.     if (readbuf)
  719.         FreeVec(readbuf);
  720.     if (!return_ok && !quiet && error)
  721.         DispError(MSG_ERROR_CORRUPT_CONFIG, confname);
  722.     return (return_ok);
  723. }
  724.  
  725. static int GetFileSize(UBYTE *filename, int *file_len, int quiet)
  726. {
  727.     int return_ok = FALSE;
  728.     BPTR lock;
  729.     __aligned struct FileInfoBlock fib;
  730.  
  731.     if (!(lock = Lock(filename, ACCESS_READ)))
  732.     {
  733.         if (!quiet)
  734.             DispError(MSG_ERROR_CANT_OPEN, filename);
  735.         goto abort;
  736.     }
  737.  
  738.     if (!Examine(lock, &fib))
  739.         goto abort;
  740.  
  741.     *file_len = fib.fib_Size;
  742.     return_ok = TRUE;
  743. abort:
  744.     if (lock)
  745.         UnLock(lock);
  746.     return (return_ok);
  747. }
  748.  
  749. static int GetLine(UBYTE *readbuf, int *read_pos, int filesize, UBYTE *dest, int dest_size)
  750. {
  751.     int return_ok = FALSE;
  752.     int dest_pos = 0;
  753.  
  754.     if (*read_pos >= filesize)
  755.         goto abort;
  756.  
  757.     for (; *read_pos < filesize &&
  758.            readbuf[*read_pos] != '\n' &&
  759.            dest_pos < dest_size - 1; (*read_pos)++)
  760.         dest[dest_pos++] = readbuf[*read_pos];
  761.  
  762.     dest[dest_pos] = EOS;
  763.     (*read_pos)++;
  764.  
  765.     return_ok = TRUE;
  766. abort:
  767.     return (return_ok);
  768. }
  769.  
  770. void Download(void)
  771. {
  772.     UBYTE *nodelist, *mailer, *buf;
  773.     UBYTE buffer[BUF_SIZE];
  774.     int buf_pos = 0, flag = FALSE;
  775.  
  776.     // request list empty?
  777.     if (!app->app_RequestList)
  778.     {
  779.         DispError(MSG_ERROR_NOTHING_SELECTED, NULL);
  780.         return;
  781.     }
  782.  
  783.     // save request list
  784.     if (!SaveReqFile())
  785.         return;
  786.  
  787.     // did the user supply a telephone number for the current node?
  788.     get(app->app_st_Conf_Phone, MUIA_String_Contents, &buf);
  789.  
  790.     // yes --> call node via phone number
  791.     if (*buf)
  792.         get(app->app_st_Conf_ViaNumber, MUIA_String_Contents, &mailer);
  793.     // no --> call node via node number
  794.     else
  795.         get(app->app_st_Conf_ViaNode, MUIA_String_Contents, &mailer);
  796.     get(app->app_st_Conf_NodeList, MUIA_String_Contents, &nodelist);
  797.  
  798.     if (!*mailer)
  799.         return;
  800.  
  801.     while (*mailer)
  802.     {
  803.         if (*mailer == '%')
  804.         {
  805.             // %t --> insert telephone number
  806.             // %n --> insert node number
  807.             // %l --> insert node list
  808.             // %p --> insert password
  809.  
  810.             flag = TRUE;
  811.             switch (mailer[1])
  812.             {
  813.             case 't':
  814.                 get(app->app_st_Conf_Phone, MUIA_String_Contents, &buf);
  815.                 break;
  816.  
  817.             case 'n':
  818.                 get(app->app_st_Conf_Node, MUIA_String_Contents, &buf);
  819.                 break;
  820.  
  821.             case 'l':
  822.                 get(app->app_st_Conf_NodeList, MUIA_String_Contents, &buf);
  823.                 break;
  824.  
  825.             case 'p':
  826.                 get(app->app_st_Conf_Password, MUIA_String_Contents, &buf);
  827.                 break;
  828.  
  829.             default:
  830.                 flag = FALSE;
  831.                 break;
  832.             }
  833.             if (flag)
  834.             {
  835.                 buffer[buf_pos] = EOS;
  836.                 strcat(buffer, buf);
  837.                 buf_pos = strlen(buffer);
  838.                 mailer += 2;
  839.             }
  840.         }
  841.         if (!flag)
  842.             buffer[buf_pos++] = *mailer++;
  843.         flag = FALSE;
  844.     }
  845.     buffer[buf_pos] = EOS;
  846.  
  847.     // invoke mailer asynchronously
  848.     {
  849.         BPTR nil_in, nil_out;
  850.  
  851.         // input handle
  852.         if (!(nil_in = Open("nil:", MODE_OLDFILE)))
  853.             return;
  854.  
  855.         // output handle
  856.         if (!(nil_out = Open("nil:", MODE_OLDFILE)))
  857.         {
  858.             Close(nil_in);
  859.             return;
  860.         }
  861.  
  862.         if (SystemTags(buffer,
  863.                        SYS_Input, nil_in,
  864.                        SYS_Output, nil_out,
  865.                        SYS_UserShell, TRUE,
  866.                        SYS_Asynch, TRUE,
  867.                        NP_StackSize, 50000,
  868.                        TAG_DONE) == -1)
  869.         {
  870.             DispError(MSG_ERROR_INVOKING_MAILER, buffer);
  871.             Close(nil_in);
  872.             Close(nil_out);
  873.         }
  874.     }
  875. }
  876.