home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UFakeNntp.cp < prev    next >
Encoding:
Text File  |  1994-04-04  |  8.5 KB  |  368 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UFakeNntp.cp
  3.  
  4. #include "UFakeNntp.h"
  5. #include "UProgress.h"
  6. #include "UPrefsDatabase.h"
  7. #include "FileTools.h"
  8. #include "Tools.h"
  9. #include "NetAsciiTools.h"
  10. #include "UPassword.h"
  11. #include "UThread.h"
  12.  
  13. #include <ErrorGlobals.h>
  14.  
  15. #include <Packages.h>
  16. #include <Errors.h>
  17.  
  18. #pragma segment MyComm
  19.  
  20. #define qDebugConstruct qDebug & 0
  21.  
  22. #define macroPATH "scratch-1:csm:"
  23.  
  24. PFakeNntp::PFakeNntp()
  25. {
  26. #if qDebugConstruct
  27.     fprintf(stderr, "PFakeNntp::PFakeNntp() at $%lx called\n", long(this));
  28. #endif
  29.     fPath = "";
  30.     fRealFirstArticleID = 0;
  31.     fRealLastArticleID = 0;
  32. }
  33.  
  34. void PFakeNntp::IFakeNntp()
  35. {
  36. #if qDebugConstruct
  37.     fprintf(stderr, "PFakeNntp::IFakeNntp() at $%lx called \n", long(this));
  38. #endif
  39.     INntp();
  40. }
  41.  
  42. PFakeNntp::~PFakeNntp()
  43. {
  44. #if qDebugConstruct
  45.     fprintf(stderr, "PFakeNntp::~PFakeNntp() at $%lx called\n", long(this));
  46. #endif
  47. }
  48.  
  49. Handle PFakeNntp::ReadFile(const CStr255 &name)
  50. {
  51.     FailInfo fi;
  52.     TFile *theFile;
  53.     VOLATILE(theFile);
  54.     Handle h = nil;
  55.     VOLATILE(h);
  56.     if (fi.Try())
  57.     {
  58.         theFile = new TFile();
  59.         theFile->IFile('TEXT', 'MPS ', kUsesDataFork, noResourceFork, kDataOpen, !kRsrcOpen);
  60.         theFile->SpecifyWithTrio(0, 0, name);
  61.         FailOSErr(theFile->OpenFile());
  62.         long len = 0;
  63.         FailOSErr(theFile->GetDataLength(len));
  64.         h = NewPermHandle(len);
  65.         HLock(h);
  66.         FailOSErr(theFile->SetDataMark(0, fsFromStart));
  67.         Ptr p = *h;
  68.         while (len)
  69.         {
  70.             gCurThread->YieldTime();
  71.             long sublen = Min(2000, len);
  72.             FailOSErr(theFile->ReadData(p, sublen));
  73.             p += sublen;
  74.             len -= sublen;
  75.         }
  76.         HUnlock(h);
  77.         theFile->CloseFile();
  78.         theFile->Free(); theFile = nil;// closes file
  79.         gCurThread->YieldTime();
  80.         MakeLastCharNull(h);
  81.         fi.Success();
  82.         return h;
  83.     }
  84.     else // fail
  85.     {
  86.         h = DisposeIfHandle(h);
  87.         FreeIfObject(theFile); theFile = nil;
  88.         fi.ReSignal();
  89.     }
  90. }
  91.  
  92. Handle PFakeNntp::GetListOfAllGroups()
  93. {
  94.     return ReadFile(macroPATH"GroupList");
  95. }
  96.  
  97. Handle PFakeNntp::GetListOfNewGroups(unsigned long /* fromDate */)
  98. {
  99.     return ReadFile(macroPATH"GroupNew");
  100. }
  101.  
  102. Handle PFakeNntp::GetListOfGroupDesciptions()
  103. {
  104.     return ReadFile(macroPATH"GroupDescriptions");
  105. }
  106.  
  107. void PFakeNntp::DoSetGroup(const CStr255 &name)
  108. {
  109.     TFile *theFile = nil;
  110.     VOLATILE(theFile);
  111.     FailInfo fi;
  112.     if (fi.Try())
  113.     {
  114.         fPath = macroPATH;
  115.         fPath += name;
  116.         fPath += ':';
  117.         CStr255 s(fPath);
  118.         s += "qRange";
  119.         theFile = new TFile();
  120.         theFile->IFile('TEXT', 'MPS ', kUsesDataFork, noResourceFork, kDataOpen, !kRsrcOpen);
  121.         theFile->SpecifyWithTrio(0, 0, s);
  122.         OSErr err = theFile->OpenFile();
  123.         if (err == fnfErr)
  124.             FailOSErr(errNntpBadGroup);
  125.         else
  126.             FailOSErr(err);
  127.         gCurThread->YieldTime();
  128.         char buffer[400];
  129.         long count = 390;
  130.         theFile->ReadData(buffer, count);
  131.         buffer[count] = 0;
  132.         gCurThread->YieldTime();
  133.         long realFirstArticleID, realLastArticleID, first, last;
  134.         sscanf(buffer, "%ld %ld %ld %ld", &realFirstArticleID, &realLastArticleID, &first, &last);
  135.         fFirstArticleID = first;
  136.         fLastArticleID = last;
  137.         if (realLastArticleID != 0 && realFirstArticleID > realLastArticleID)
  138.         {
  139.             DebugStr("realFirstArticleID > realLastArticleID");
  140.             Failure(9999, 0);
  141.         }
  142.         fRealFirstArticleID = realFirstArticleID;
  143.         fRealLastArticleID = realLastArticleID;
  144.         FreeIfObject(theFile); theFile = nil;
  145.         fi.Success();
  146.     }
  147.     else // fail
  148.     {
  149.         FreeIfObject(theFile); theFile = nil;
  150.         fi.ReSignal();
  151.     }
  152. }
  153.  
  154. Handle PFakeNntp::GetHeaderList(const char *headerName, long firstArticleID, long lastArticleID)
  155. {
  156.     if (fPath == "")
  157.     {
  158.         DebugStr("Group not set!");
  159.         return NewPermHandle(0);
  160.     }
  161.     if (firstArticleID > lastArticleID)
  162.         return NewPermHandle(0); // shortcut: don't fetch anything
  163.     FailInfo fi;
  164.     TFile *theFile = nil;
  165.     VOLATILE(theFile);
  166.     Handle h = nil;
  167.     VOLATILE(h);
  168.     if (fi.Try()) 
  169.     {
  170.         CStr255 s(fPath);
  171.         s += "q";
  172.         s += headerName;
  173.         theFile = new TFile();
  174.         theFile->IFile('TEXT', 'MPS ', kUsesDataFork, noResourceFork, kDataOpen, !kRsrcOpen);
  175.         theFile->SpecifyWithTrio(0, 0, s);
  176.         FailOSErr(theFile->OpenFile());
  177.         long len = 0;
  178.         FailOSErr(theFile->GetDataLength(len));
  179.         h = NewPermHandle(len);
  180.         HLock(h);
  181.         theFile->SetDataMark(0, fsFromStart);
  182.         Ptr p = *h;
  183.         long loadLen = len;
  184.         while (loadLen)
  185.         {
  186.             gCurThread->YieldTime();
  187.             long sublen = Min(2000, loadLen);
  188.             FailOSErr(theFile->ReadData(p, sublen));
  189.             p += sublen;
  190.             loadLen -= sublen;
  191.         }
  192.         HUnlock(h);
  193.         theFile->CloseFile();
  194.         theFile->Free(); theFile = nil; // closes file
  195.         register Ptr startP = *h;
  196.         register long i;
  197.         if (firstArticleID < fFirstArticleID)
  198.             firstArticleID = fFirstArticleID;
  199.         if (lastArticleID > fLastArticleID)
  200.             lastArticleID = fLastArticleID;
  201.         for (i = firstArticleID - fRealFirstArticleID; i > 0; i--)
  202.             while (*startP++ != 13)
  203.                 ;
  204.         if (*startP == 10) 
  205.             startP++;
  206.         register Ptr endP = startP;
  207.         for (i = lastArticleID - firstArticleID + 1; i > 0; i--)
  208.             while (*endP++ != 13)
  209.                 ;
  210.         if (endP > *h + len) 
  211.         {
  212.             DebugStr(CStr255("UPS: got past end of handle in parsing!"));
  213.             endP = *h + len;
  214.         }
  215.         BytesMove(startP, *h, endP - startP);
  216.         SetPermHandleSize(h, endP - startP); // downsizing
  217.         MakeLastCharNull(h);
  218.         gCurProgress->Worked(lastArticleID - firstArticleID);
  219. #if qDebug
  220.         long zzsize = GetHandleSize(h);
  221.         if (zzsize && *(*h + zzsize - 1) != 0)
  222.             ProgramBreak("The last char is not null (som jeg lovede!)");
  223. #endif
  224.         fi.Success();
  225.         return h;
  226.     }
  227.     else // fail
  228.     {
  229.         FreeIfObject(theFile); theFile = nil;
  230.         h = DisposeIfHandle(h);
  231.         fi.ReSignal();
  232.     }
  233. }
  234.  
  235.  
  236. Handle PFakeNntp::GetArticle(long articleID)
  237. {
  238.     if (fPath == "")
  239.     {
  240.         DebugStr("Group not set!");
  241.         return NewPermHandle(0);
  242.     }
  243.     if (articleID <= 0 || articleID > fRealLastArticleID)
  244.     {
  245.         char sss[200];
  246.         sprintf(sss, "Crazy article requested: articleID = %ld", articleID);
  247.         DebugStr(sss);
  248.         return nil;
  249.     }
  250.     FailInfo fi;
  251.     TFile *theFile;
  252.     VOLATILE(theFile);
  253.     Handle h = nil;
  254.     if (fi.Try()) 
  255.     {
  256.         CStr255 s;
  257.         long hs, hl, bs, bl, as, al;
  258.         theFile = new TFile();
  259.         theFile->IFile('TEXT', 'MPS ', kUsesDataFork, noResourceFork, kDataOpen, !kRsrcOpen);
  260.         {
  261.             s = fPath;
  262.             s += "article_index";
  263.             theFile->SpecifyWithTrio(0, 0, s);
  264.             FailOSErr(theFile->OpenFile());
  265.             short diffID = short(articleID - fRealFirstArticleID);
  266.             long offset = 77 * diffID;
  267.             FailOSErr(theFile->SetDataMark(offset, fsFromStart));
  268.             char buffer[400];
  269.             long count = 390;
  270.             theFile->ReadData(buffer, count);
  271.             buffer[count] = 0;
  272.             long line_id = 0;
  273.             sscanf(buffer, "%ld %ld %ld %ld %ld %ld %ld", &line_id, &hs, &hl, &bs, &bl, &as, &al);
  274.             if (line_id != articleID) 
  275.             {
  276.                 char sss[200];
  277.                 sprintf(sss, "WRONG ARTICLE ID (%ld) found in article_index, %ld expected, buffer at $%lx", line_id, articleID, buffer);
  278.                 DebugStr(sss);
  279.                 fi.Success();
  280.                 return NewPermHandle(0);
  281.             }
  282.             FailOSErr(theFile->CloseFile());
  283.         }
  284.         theFile->SpecifyWithTrio(0, 0, CStr255(fPath) + "articles");
  285.         FailOSErr(theFile->OpenFile());
  286.         FailOSErr(theFile->SetDataMark(as, fsFromStart));
  287.         long len;
  288.         FailOSErr(theFile->GetDataLength(len));
  289.         al = Min(al, len - as);
  290.         h = NewPermHandle(al);
  291.         HLock(h);
  292.         FailOSErr(theFile->ReadData(*h, al));
  293.         theFile->Free(); theFile = nil; // closes file
  294.         HUnlock(h);
  295.         MakeLastCharNull(h);
  296.         fi.Success();
  297. #if qDebug
  298.         long zzsize = GetHandleSize(h);
  299.         if (zzsize && *(*h + zzsize - 1) != 0)
  300.             ProgramBreak("The last char is not null (som jeg lovede!)");
  301. #endif
  302.         gCurThread->YieldTime();
  303.         return h;
  304.     }
  305.     else // fail
  306.     {
  307.         h = DisposeIfHandle(h);
  308.         FreeIfObject(theFile); theFile = nil;
  309.         fi.ReSignal();
  310.     }
  311. }
  312.  
  313. Boolean PFakeNntp::IsPostingAllowed()
  314. {
  315.     return true;
  316. }
  317.  
  318. void PFakeNntp::PostArticle(Handle h, short /* ackStringID */)
  319. {
  320. #if qDebug
  321.     CStr255 username, password;
  322.     GetUserNameAndPassword(username, password);
  323.     fprintf(stderr, "PFakeNntp::PostArticle, username = '%s', ", (char*)username);
  324.     fprintf(stderr, "password = '%s'\n", (char*)password);
  325. #endif
  326.     TFile *file = nil;
  327.     VOLATILE(file);
  328.     FailInfo fi;
  329.     if (fi.Try())
  330.     {
  331.         file = NewFile('TEXT', 'MPS ',
  332.             kUsesDataFork, noResourceFork, !kDataOpen, !kRsrcOpen);
  333.         file->SetPermissions(fsRdWrPerm, fsRdWrPerm);
  334.         FSSpec spec;
  335.         gPrefs->GetSilentDirAliasPrefs('FEdi', spec);
  336.         short nr = 1;
  337.         while (true)
  338.         {
  339.             CStr255 s;
  340.             NumToString(nr++, s);
  341.             s.Insert("Posted article ", 1);
  342.             CopyCString2String(s, spec.name);
  343.             file->Specify(spec);
  344.             if (!FileExist(file))
  345.                 break;
  346.         }
  347.         FailOSErr(file->CreateFile());
  348.         FailOSErr(file->OpenFile());
  349.         HLock(h);
  350.         long size = GetHandleSize(h);
  351.         FailOSErr(file->WriteData(*h, size));
  352.         HUnlock(h);
  353.         file->Free(); file = nil;
  354.         gCurThread->YieldTime();
  355.         fi.Success();
  356.     }
  357.     else // fail
  358.     {
  359.         FreeIfObject(file); file = nil;
  360.         fi.ReSignal();
  361.     }
  362. }
  363.  
  364. void PFakeNntp::ExamineNewsServer()
  365. {
  366.     // who is going to doubt this server?
  367. }
  368.