home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / dos / listz21s.exe / LSZ_LIST.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-07  |  10.1 KB  |  379 lines

  1. /*
  2.  * This file is part of Listerz v2.0 (VE)
  3.  *
  4.  * Copyright (C) 1995-1997 by Branislav L. Slantchev
  5.  * A Product of Silicon Creations, Inc.
  6.  *
  7.  * This file is distributed under the terms and conditions of the GNU
  8.  * General Public License. For more information, refer to the file
  9.  * Copying.Doc which is included in the archive.
  10. */
  11. #include "lsz_appl.h"
  12. #include "lsz_area.h"
  13. #include "proboard.h"
  14. #include "stdmac.h"
  15. #include "keyboard.h"
  16. #include "kbcodes.h"
  17. #include "progbar.h"
  18. #include "str.h"
  19. #include "file.h"
  20. #include "febbs.h"
  21. #include "pblsdk.h"
  22.  
  23. #ifndef PB_SDK
  24.     #include <conio.h>
  25.     #include <string.h>
  26.     #include <dos.h>
  27. #else
  28.     #include "pblibc.h"
  29. #endif
  30.  
  31. #define FBBS_OFFSET 37
  32. #define NAME_WIDTH  80
  33. #define NAME_NELEM  25
  34. // temp buffer for area names shown in the processing box
  35. static char g_DisplayNames[NAME_NELEM][NAME_WIDTH];
  36. extern Application *application;
  37.  
  38. static void
  39. UpdatePercent(short percent, const zRect &bounds)
  40. {
  41.     gotoxy(bounds.a.x, bounds.a.y);
  42.     textattr(application->config()->total_DigitColor);
  43.     cprintf("%*d%%", bounds.Width() - 1, percent);
  44. }
  45.  
  46. static void
  47. UpdateCounter(ulong n, const zRect &bounds)
  48. {
  49.     char src[80], dest[80];
  50.  
  51.     sprintf(src, "%lu", n);
  52.     strcma(dest, src);
  53.     gotoxy(bounds.a.x, bounds.a.y);
  54.     textattr(application->config()->total_DigitColor);
  55.     cprintf("%*s", bounds.Width(), dest);
  56. }
  57.  
  58. void
  59. Application::FormatLine(zFbbsLine &fbbs)
  60. {
  61.     char buf[1024];
  62.     int  flags = fbbs.GetFlags();
  63.     long bytes, downs;
  64.  
  65.     if( flags & zFbbsLine::name )
  66.     {
  67.         m_AreaFiles++;
  68.         bytes = atol(fbbs.GetFileSize());
  69.         downs = atol(&fbbs.GetFileCount()[1]);
  70.         m_AreaBytes += bytes;
  71.         m_AreaFdls  += downs;
  72.         m_TotalFdls += downs;
  73.         m_TotalKbytes += bytes / 1024;
  74.         m_DeltaBytes += (int)(bytes % 1024);
  75.         if( m_DeltaBytes > 1024 )
  76.         {
  77.             m_DeltaBytes -= 1024;
  78.             m_TotalKbytes++;
  79.         }
  80.         UpdateCounter(++m_TotalFiles, m_Config.total_Files);
  81.         UpdateCounter(m_TotalKbytes, m_Config.total_Size);
  82.  
  83.         sprintf(buf, "%-12s ", fbbs.GetFileName());
  84.         sprintf(buf + strlen(buf), "%8s ", fbbs.GetFileDate());
  85.         sprintf(buf + strlen(buf), "%9s ", fbbs.GetFileSize());
  86.         sprintf(buf + strlen(buf), "%s ", fbbs.GetFileCount());
  87.         sprintf(buf + strlen(buf), "%s", fbbs.GetFileDesc());
  88.     }
  89.     else
  90.     {
  91.         char temp[1024];
  92.  
  93.         // we only fix (if needed) multi-line descriptions
  94.         strcpy(buf, fbbs.GetFileDesc());
  95.         // special case for programs that use the backspace to start
  96.         // a line, AMU is one of those programs (for the headers)
  97.         if( 0 == strchr(buf, '\b') )
  98.         {
  99.             char   *p;
  100.             size_t  len;
  101.  
  102.             strcpy(temp, buf);
  103.             memset(buf, ' ', sizeof(buf));
  104.             for( p = temp; strchr(";+! \t", *p); ++p )
  105.             {
  106.                 if( EOS == *p ) goto WriteLine;
  107.             }
  108.             len = strlen(p) + 1;
  109.             memcpy(buf + FBBS_OFFSET, p, len);
  110.             buf[FBBS_OFFSET + len] = EOS;
  111.         }
  112.     }
  113. WriteLine:
  114.     fputs(buf, m_fp);
  115.     m_ListerSize = ftell(m_fp);
  116.     UpdateCounter(m_ListerSize, m_Config.total_ListSize);
  117. }
  118.  
  119. void
  120. Application::ProcessFileArea(short index)
  121. {
  122.     int      len, y, i = 0;
  123.     char     buf[1024];
  124.     FILE    *fpCur;
  125.  
  126.     // make room for the new area name
  127.     m_CurArea = (*m_Bucket)[index];
  128.     for( i = 1; i < m_Config.proc_Bounds.Height(); ++i )
  129.     {
  130.         memcpy(g_DisplayNames[i-1], g_DisplayNames[i], NAME_WIDTH);
  131.     }
  132.     memset(g_DisplayNames[i-1], ' ', NAME_WIDTH);
  133.     len = min((int)strlen(m_CurArea.name), m_Config.proc_Bounds.Width());
  134.     memcpy(g_DisplayNames[i-1], m_CurArea.name, len);
  135.     g_DisplayNames[i-1][m_Config.proc_Bounds.Width()] = EOS;
  136.     // display the scrolling area list
  137.     textattr(m_Config.proc_Color);
  138.     for( i = 0, y = m_Config.proc_Bounds.a.y; y < m_Config.proc_Bounds.b.y; )
  139.     {
  140.         gotoxy(m_Config.proc_Bounds.a.x, y++);
  141.         cprintf(g_DisplayNames[i++]);
  142.     }
  143.     // display the current area name
  144.     memset(buf, ' ', m_Config.area_Bounds.Width());
  145.     len = strlen(m_CurArea.name);
  146.     memcpy(buf, m_CurArea.name, len);
  147.     buf[m_Config.area_Bounds.Width()] = EOS;
  148.     if( len > m_Config.area_Bounds.Width() )
  149.     {    // name is too long, indicate that with a trailing "..."
  150.         len = m_Config.area_Bounds.Width();
  151.         buf[len - 1] = '.';
  152.         buf[len - 2] = '.';
  153.         buf[len - 3] = '.';
  154.     }
  155.     textattr(m_Config.area_Color);
  156.     gotoxy(m_Config.area_Bounds.a.x, m_Config.area_Bounds.a.y);
  157.     cprintf(buf);
  158.     // initialize the progress bars and the statistics
  159.     ushort fg = (int)m_Config.area_Progbar.fgColor << 8;
  160.     ushort bg = (int)m_Config.area_Progbar.bgColor << 8;
  161.     fg |= m_Config.area_Progbar.fgChar & 0xff;
  162.     bg |= m_Config.area_Progbar.bgChar & 0xff;
  163.     zProgBar progress(m_Config.area_Progbar.bounds, fg, bg);
  164.  
  165.     progress.setTotal(file_size(m_CurArea.listpath));
  166.     zFbbsLine fbbs((zFbbsLine::date_format_t)m_CurArea.dateFormat);
  167.     fbbs.SetPath(m_CurArea.filepath, index + 1, Boolean(m_CurArea.copyLocal));
  168.  
  169.     m_CurAreaNo = index + 1;
  170.     m_AreaFiles = m_AreaBytes = m_AreaFdls = 0L;
  171.  
  172.     WriteHeaderOrFooter(m_AreaHeader);
  173.  
  174.     if( 0 != (fpCur = fopen(m_CurArea.listpath, "rt")) )
  175.     {
  176.         long lastOffset = 0L;
  177.  
  178.         fgets(buf, sizeof(buf), fpCur);
  179.         while( !feof(fpCur) )
  180.         {
  181.             progress.update(ftell(fpCur) - lastOffset);
  182.             UpdatePercent(progress.getPerCent(), m_Config.area_Percent);
  183.             fbbs.SetLine(buf);
  184.             FormatLine(fbbs);
  185.             lastOffset = ftell(fpCur);
  186.             fgets(buf, sizeof(buf), fpCur);
  187.         }
  188.         fclose(fpCur);
  189.     }
  190.  
  191.     WriteHeaderOrFooter(m_AreaFooter);
  192. }
  193.  
  194. Boolean
  195. Application::CompressFile(ushort command)
  196. {
  197.     Boolean   retval = True, aborted = False;
  198.     ARCHIVER *parch = NULL;
  199.     char     *extension;
  200.  
  201.     switch( command )
  202.     {
  203.         case cmZip: parch = &m_Config.zip; extension = ".ZIP"; break;
  204.         case cmRar: parch = &m_Config.rar; extension = ".RAR"; break;
  205.         case cmArj: parch = &m_Config.arj; extension = ".ARJ"; break;
  206.         case cmLha: parch = &m_Config.lha; extension = ".LZH"; break;
  207.         case cmZoo: parch = &m_Config.zoo; extension = ".ZOO"; break;
  208.         case cmNoCompression:
  209.             break;
  210.         case cmExit:
  211.             if( file_exist(m_fileName) ) file_remove(m_fileName);
  212.             aborted = True;
  213.             break;
  214.         default:
  215.             retval = False;
  216.     }
  217.  
  218.     // execute the archiver command
  219.     if( retval && !aborted )
  220.     {
  221.         char buf[255], fileName[MAXPATH];
  222.  
  223.         if( parch )
  224.         {    // if we are compressing, do it now
  225.             const char *msg = "please hold while i bundle the list...";
  226.  
  227.             memset(buf, ' ', m_Config.cbar_Bounds.Width());
  228.             memcpy(buf, msg, strlen(msg));
  229.             buf[m_Config.cbar_Bounds.Width()] = EOS;
  230.             gotoxy(m_Config.cbar_Bounds.a.x, m_Config.cbar_Bounds.a.y);
  231.             textattr(m_Config.cbar_Color);
  232.             cprintf(buf);
  233.  
  234.             sprintf(buf, "LISTZ%03X%s", NodeNumber, extension);
  235.             strcpy(fileName, pb_getpath(buf, PBDIR_SYS));
  236.  
  237.             sprintf(buf, "%s*!*Q*Z %s %s %s %s",
  238.                 parch->swap ? "*X" : "", parch->path, parch->options,
  239.                 fileName, m_fileName);
  240.  
  241.             #ifdef PB_SDK
  242.                 RemoteDisplay(FALSE);
  243.                 MenuFunction(MENU_SHELL, buf);
  244.                 RemoteDisplay(TRUE);
  245.             #else
  246.                 cprintf("\n\rCommand: %s\n\r", buf);
  247.                 getch();
  248.             #endif
  249.         }
  250.         else
  251.         {    // no compression, copy path to listerz file
  252.             strcpy(fileName, m_fileName);
  253.         }
  254.  
  255.         // now fileName has the path to the file for download
  256.         #ifdef PB_SDK
  257.             // check the default protocol first
  258.             clrscr();
  259.             if( !CurUser->defaultProtocol ) MenuFunction(74, "");
  260.             if( CurUser->defaultProtocol )
  261.             {
  262.                 sprintf(buf, "/A /F=%s /I /Q /K=%c",
  263.                     fileName, CurUser->defaultProtocol);
  264.                 MenuFunction(MENU_DOWNLOAD, buf);
  265.             }
  266.         #endif
  267.  
  268.         // cleanup just in case, we don't want these files here
  269.         if( file_exist(m_fileName) ) file_remove(m_fileName);
  270.         if( file_exist(fileName) ) file_remove(fileName);
  271.     }
  272.  
  273.     return retval;
  274. }
  275.  
  276. // this function creates the area lists and handles the download
  277. void
  278. Application::MakeAreaList()
  279. {
  280.     zListCursor  cursor(*m_AreaList, True);
  281.     ushort       nAreas = 0;
  282.     int          i;
  283.  
  284.     // nothing in the list, don't process
  285.     if( 0 == m_AreaList->size() )
  286.         return;
  287.  
  288.     m_TotalAreas = 0;
  289.     do
  290.     {
  291.         if( ((Area *)cursor.get())->m_tagged ) m_TotalAreas++;
  292.     }while( cursor++ );
  293.  
  294.     // nothing tagged for processing
  295.     if( 0 == m_TotalAreas )
  296.         return;
  297.  
  298.     // display processing area file
  299.     clrscr();
  300.     pb_showfile(m_ProcScreen, NULL, &m_Terminal);
  301.  
  302.     // initialize the area display name buffers
  303.     for( i = 0; i < NAME_NELEM; ++i )
  304.     {
  305.         memset(g_DisplayNames[i], ' ', NAME_WIDTH);
  306.         g_DisplayNames[i][m_Config.proc_Bounds.Width()] = EOS;
  307.     }
  308.  
  309.     // initialize the progress bar for the totals
  310.     ushort fg = (int)m_Config.total_Progbar.fgColor << 8;
  311.     ushort bg = (int)m_Config.total_Progbar.bgColor << 8;
  312.     fg |= m_Config.total_Progbar.fgChar & 0xff;
  313.     bg |= m_Config.total_Progbar.bgChar & 0xff;
  314.     zProgBar progress(m_Config.total_Progbar.bounds, fg, bg);
  315.     progress.setTotal((ulong)m_TotalAreas);
  316.  
  317.     // init the totals and percentage area
  318.     gotoxy(m_Config.total_Percent.a.x, m_Config.total_Percent.a.y);
  319.     textattr(m_Config.total_DigitColor);
  320.     cprintf("%*s%%", m_Config.total_Percent.Width() - 1, "0");
  321.  
  322.     m_TotalFiles = m_TotalKbytes = m_TotalFdls = m_ListerSize = 0L;
  323.     m_DeltaBytes = 0;
  324.     m_AreaFiles = m_AreaBytes = m_AreaFdls = 0L;
  325.  
  326.     // flush the keyboard
  327.     m_Keyboard->flush();
  328.     ushort keyCode = 0x0000;
  329.     // prepare the listerz file
  330.     m_fp = fopen(m_fileName, "wt");
  331.     if( m_fp )
  332.     {
  333.         WriteHeaderOrFooter(m_MainHeader);
  334.         // process all tagged areas
  335.         cursor.begin();
  336.         do
  337.         {
  338.             Area *areaptr = (Area *)cursor.get();
  339.  
  340.             if( areaptr->m_tagged )
  341.             {
  342.                 ProcessFileArea(areaptr->m_index);
  343.                 areaptr->m_tagged = False;
  344.                 progress.update(1L);
  345.                 UpdatePercent(progress.getPerCent(), m_Config.total_Percent);
  346.                 UpdateCounter(++nAreas, m_Config.total_Areas);
  347.             }
  348.  
  349.             keyCode = m_Keyboard->peek();
  350.         }while( cursor++ && kbEsc != keyCode );
  351.  
  352.         WriteHeaderOrFooter(m_MainFooter);
  353.         fclose(m_fp);
  354.  
  355.         // redisplay area screen
  356.         clrscr();
  357.         pb_showfile(m_MainScreen, NULL, &m_Terminal);
  358.         m_AreaBox->draw();
  359.  
  360.         // get the format of the archiver to use
  361.         m_ArchiveBar->setState(True);
  362.         for( ;; )
  363.         {
  364.             keyCode = m_Keyboard->get();
  365.             // see if we recognized the command, if we did, this
  366.             // returns True (and the file has been compressed &
  367.             // sent to the user or the thing was aborted)
  368.             if( CompressFile(m_ArchiveBar->handle(keyCode)) )
  369.                 break;
  370.         }
  371.     }
  372.  
  373.     // redisplay screen and go back to main loop
  374.     clrscr();
  375.     pb_showfile(m_MainScreen, NULL, &m_Terminal);
  376.     m_AreaBox->draw();
  377.     m_AreaBar->draw();
  378. }
  379.