home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 November / PCONLINE_11_99.ISO / filesbbs / OS2 / MMSRC029.ZIP / mmail-0.29 / mmail / filelist.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-14  |  4.9 KB  |  278 lines

  1. /*
  2.  * MultiMail offline mail reader
  3.  * file_header and file_list
  4.  
  5.  Copyright (c) 1996 Toth Istvan <stoty@vma.bme.hu>
  6.  Copyright (c) 1999 William McBrine <wmcbrine@clark.net>
  7.  
  8.  Distributed under the GNU General Public License.
  9.  For details, see the file COPYING in the parent directory. */
  10.  
  11. #include "mmail.h"
  12.  
  13. // --------------------------------------------------------------------------
  14. // file_header methods
  15. // --------------------------------------------------------------------------
  16. file_header::file_header(const char *nameA, time_t dateA, off_t sizeA)
  17. {
  18.     name = strdupplus(nameA);
  19.     date = dateA;
  20.     size = sizeA;
  21.     next = 0;
  22. }
  23.  
  24. file_header::~file_header()
  25. {
  26.     delete[] name;
  27. }
  28.  
  29. const char *file_header::getName() const
  30. {
  31.     return name;
  32. }
  33.  
  34. time_t file_header::getDate() const
  35. {
  36.     return date;
  37. }
  38.  
  39. off_t file_header::getSize() const
  40. {
  41.     return size;
  42. }
  43.  
  44. // ------------------------------------------------------------------------
  45. // file_list methods
  46. // ------------------------------------------------------------------------
  47.  
  48. file_list::file_list(const char *FileDir, bool sorttypeA, bool dirlistA)
  49. {
  50.     sorttype = sorttypeA;
  51.     dirlist = dirlistA;
  52.  
  53.     dirlen = strlen(FileDir);
  54.     DirName = new char[dirlen + 81];
  55.     strcpy(DirName, FileDir);
  56.  
  57.     initFiles();
  58. }
  59.  
  60. file_list::~file_list()
  61. {
  62.     while (noOfFiles)
  63.         delete files[--noOfFiles];
  64.     delete[] files;
  65.     delete[] DirName;
  66. }
  67.  
  68. void file_list::initFiles()
  69. {
  70.     if (!myopendir(DirName))
  71.         fatalError("There is no Packet Dir!");
  72.  
  73.     noOfFiles = 0;
  74.  
  75.     file_header head("", 0, 0);
  76.     file_header *filept = &head;
  77.  
  78.     const char *fname;
  79.     mystat st;
  80.  
  81.     while ((fname = myreaddir()))
  82.         if (st.init(fname))
  83.         if (dirlist ^ !st.isdir)
  84.             if (strcmp(fname, "."))
  85.             if (readable(fname)) {
  86.                 filept->next = new file_header(fname,
  87.                     st.date, st.size);
  88.                 filept = filept->next;
  89.                 noOfFiles++;
  90.             }
  91.  
  92.     files = new file_header *[noOfFiles];
  93.     int c = 0;
  94.     filept = head.next;
  95.     while (filept) {
  96.         files[c++] = filept;
  97.         filept = filept->next;
  98.     }
  99.     sort();
  100. }
  101.  
  102. void file_list::sort()
  103. {
  104.     if (noOfFiles > 1)
  105.         qsort(files, noOfFiles, sizeof(file_header *), sorttype ?
  106.             ftimecomp : fnamecomp);
  107. }
  108.  
  109. void file_list::resort()
  110. {
  111.     sorttype = !sorttype;
  112.     sort();
  113. }
  114.  
  115. int fnamecomp(const void *a, const void *b)
  116. {
  117.     int d;
  118.  
  119.     const char *p = (*((file_header **) a))->getName();
  120.     const char *q = (*((file_header **) b))->getName();
  121.  
  122.     d = strcasecmp(p, q);
  123.     if (!d)
  124.         d = strcmp(q, p);
  125.  
  126.     return d;
  127. }
  128.  
  129. int ftimecomp(const void *a, const void *b)
  130. {
  131.     return (*((file_header **) b))->getDate() -
  132.         (*((file_header **) a))->getDate();
  133. }
  134.  
  135. const char *file_list::getDirName() const
  136. {
  137.     DirName[dirlen] = '\0';
  138.     return DirName;
  139. }
  140.  
  141. int file_list::getNoOfFiles() const
  142. {
  143.     return noOfFiles;
  144. }
  145.  
  146. void file_list::gotoFile(int fileNo)
  147. {
  148.     if (fileNo < noOfFiles)
  149.         activeFile = fileNo;
  150. }
  151.  
  152. const char *file_list::changeDir(const char *newpath)
  153. {
  154.     static char newdir[256];
  155.  
  156.     if (dirlist) {
  157.         if (!newpath)
  158.             newpath = getName();
  159.         mychdir(DirName);
  160.         mychdir(newpath);
  161.         mygetcwd(newdir);
  162.  
  163.         char *p = newdir + strlen(newdir) - 1;
  164.         if ((*p == '\\') || (*p == '/')) {
  165.             p[1] = '.';
  166.             p[2] = '\0';
  167.         }
  168.     }
  169.     return newdir;
  170. }
  171.  
  172. int file_list::changeName(const char *newname)
  173. {
  174.     mychdir(DirName);
  175.     return rename(getName(), newname);
  176. }
  177.  
  178. const char *file_list::getName() const
  179. {
  180.     return files[activeFile]->getName();
  181. }
  182.  
  183. time_t file_list::getDate() const
  184. {
  185.     return files[activeFile]->getDate();
  186. }
  187.  
  188. off_t file_list::getSize() const
  189. {
  190.     return files[activeFile]->getSize();
  191. }
  192.  
  193. const char *file_list::getNext(const char *fname)
  194. {
  195.     int c, len;
  196.     const char *p, *q;
  197.     bool isExt;
  198.  
  199.     if (fname) {
  200.         isExt = (*fname == '.');
  201.  
  202.         for (c = activeFile + 1; c < noOfFiles; c++) {
  203.             q = files[c]->getName();
  204.  
  205.             if (isExt) {
  206.                 len = strlen(q);
  207.                 if (len > 5) {
  208.                 p = q + len - 4;
  209.                     if (!strcasecmp(p, fname)) {
  210.                         activeFile = c;
  211.                         return q;
  212.                     }
  213.                 }
  214.             } else
  215.                 if (!strncasecmp(q, fname, strlen(fname))) {
  216.                     activeFile = c;
  217.                     return q;
  218.                 }
  219.             }
  220.     }
  221.         return 0;
  222. }
  223.  
  224. file_header *file_list::getNextF(const char *fname)
  225. {
  226.     return getNext(fname) ? files[activeFile] : 0;
  227. }
  228.  
  229. const char *file_list::exists(const char *fname)
  230. {
  231.     gotoFile(-1);
  232.     return getNext(fname);
  233. }
  234.  
  235. file_header *file_list::existsF(const char *fname)
  236. {
  237.     return exists(fname) ? files[activeFile] : 0;
  238. }
  239.  
  240. void file_list::addItem(file_header **list, const char *q, int &filecount)
  241. {
  242.     file_header *p;
  243.     int x;
  244.  
  245.     gotoFile(-1);
  246.     while ((p = getNextF(q))) {
  247.         for (x = 0; x < filecount; x++)
  248.             if (list[x] == p)
  249.                 break;
  250.         if (x == filecount) {
  251.             list[x] = p;
  252.             filecount++;
  253.         }
  254.     }
  255. }
  256.  
  257. const char *file_list::expandName(const char *fname)
  258. {
  259.     sprintf(DirName + dirlen, "/%.79s", fname);
  260.     return DirName;
  261. }
  262.  
  263. FILE *file_list::ftryopen(const char *fname, const char *mode)
  264. {
  265.     const char *p = exists(fname);
  266.     return p ? fopen(expandName(p), mode) : 0;
  267. }
  268.  
  269. void file_list::kill()
  270. {
  271.     remove(expandName(getName()));
  272.  
  273.     delete files[activeFile];
  274.     noOfFiles--;
  275.     for (int i = activeFile; i < noOfFiles; i++)
  276.         files[i] = files[i + 1];
  277. }
  278.