home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / monitors / rsys / rsyssrc.lha / RSysFiletype.c < prev    next >
C/C++ Source or Header  |  1993-09-19  |  10KB  |  499 lines

  1. /*
  2. ***************************************************************************
  3. *
  4. * Datei:
  5. *      RSysFiletype.c
  6. *
  7. * Inhalt:
  8. *
  9. *      --- Globale Routinen ---
  10. *
  11. *    int filetype ( char *Name );
  12. *
  13. *      --- Lokale  Routinen ---
  14. *
  15. *    static int IsDirectory ( char *Name );
  16. *    static UBYTE Local2Upper ( UBYTE c );
  17. *    static UBYTE StrCmp ( char *a , char *b );
  18. *
  19. * Bemerkungen:
  20. *      Routinen zur Ermittlung des Typs einer Datei.
  21. *
  22. * Erstellungsdatum:
  23. *      07-Jul-93     Rolf Böhme
  24. *
  25. * Änderungen:
  26. *      07-Jul-93     Rolf Böhme      Erstellung
  27. *
  28. ***************************************************************************
  29. */
  30.  
  31. #include "RSys.h"
  32.  
  33.     /*
  34.      * Die Routinen zur Überprüfung von Filetypen wurden komplett aus
  35.      * dem Terminalprogramm TERM von Olaf 'Olsen' Barthel entnommen. Ich
  36.      * habe ein paar Teile modifiziert und die Kommentare beibehalten.
  37.      * Faulheit overwhelmed me...;-)
  38.      */
  39. int    global_type;
  40.  
  41. char *mess[]=
  42. {
  43.     "Disk/Directory",
  44.     "File",
  45.     "Icon file",
  46.     "Text file",
  47.     "C Sourcefile",
  48.     ".h-C-Include",
  49.     "Assembler file",
  50.     "Assembler-Include file",
  51.     ".MOD file",
  52.     "ARexx program",
  53.     "BASIC program",
  54.     "TeX file",
  55.     "MetaFONT file",
  56.     "GF file",
  57.     "TeX-Font file",
  58.     "TeX-DVI file",
  59.     "Font library",
  60.     "MANX Objectfile (V3.x)",
  61.     "MANX Objectfile (V5.x)",
  62.     "MANX Libraryfile (V3.x)",
  63.     "MANX Libraryfile (V5.x)",
  64.     "Objekt file",
  65.     ".LIB file (Object library)",
  66.     "Executable",
  67.     "Library",
  68.     "Device",
  69.     "Filesystem",
  70.     "Handler",
  71.     "GIF picture",
  72.     "ILBM graphic",
  73.     "Animation",
  74.     "8SVX song",
  75.     "SMUS-Song",
  76.     "FTXT format",
  77.     "Preferences",
  78.     "Term file",
  79.     "Imploder file",
  80.     "Powerpacker file",
  81.     "Arc archive",
  82.     "LHArc archive",
  83.     "Zoo archive",
  84.     "ZIP archive",
  85.     "DMS archive",
  86.     "WARP archive",
  87.     "ZOOM archive",
  88.     "WordPerfect document"
  89. };
  90.  
  91. struct Suffix
  92. {
  93.     char *Name;
  94.     UBYTE Type;
  95. };
  96.  
  97. /*
  98.  * Some file name suffixes for text files and the approriate file types.
  99.  */
  100.  
  101. struct Suffix TextSuffix[]=
  102. {
  103.     ".C", TYPE_C,
  104.     ".CP", TYPE_C,
  105.     ".CC", TYPE_C,
  106.     ".H", TYPE_H,
  107.     ".ASM", TYPE_ASM,
  108.     ".A", TYPE_ASM,
  109.     ".S", TYPE_ASM,
  110.     ".I", TYPE_I,
  111.     ".BAS", TYPE_BASIC,
  112.     ".GFA", TYPE_BASIC,
  113.     ".REXX", TYPE_REXX,
  114.     ".CED", TYPE_REXX,
  115.     ".VLT", TYPE_REXX,
  116.     ".CPR", TYPE_REXX,
  117.     ".TxEd", TYPE_REXX,
  118.     ".TEX", TYPE_TEX,
  119.     ".STY", TYPE_TEX,
  120.     ".MF", TYPE_METAFONT,
  121.     ".MOD", TYPE_MOD,
  122.     ".DEF", TYPE_MOD,
  123.     ".WP", TYPE_WORDPERFECT
  124. };
  125.  
  126. /*
  127.  * Some more file name suffixes for executable files and the approriate
  128.  * file types.
  129.  */
  130.  
  131. struct Suffix ExecutableSuffix[]=
  132. {
  133.     ".device", TYPE_DEVICE,
  134.     ".library", TYPE_LIBRARY,
  135.     "FileSystem", TYPE_FILESYS,
  136.     "Handler", TYPE_HANDLER
  137. };
  138.  
  139. /*
  140.  * Local2Upper(UBYTE c):
  141.  *
  142.  * Custom version of toupper, will also handle international characters.
  143.  */
  144.  
  145. static UBYTE
  146. Local2Upper(UBYTE c)
  147. {
  148.     return ((UBYTE) ((((c) >= 224 && (c) <= 254) || ((c) >= 'a' && (c) <= 'z')) ? (c) - 32 : c));
  149. }
  150.  
  151. /*
  152.  * StrCmp(UBYTE *a,UBYTE *b):
  153.  *
  154.  * Custom version of strcmp, compares ignoring case.
  155.  */
  156.  
  157. static UBYTE
  158. StrCmp(char *a, char *b)
  159. {
  160.     for (; Local2Upper((UBYTE) * a) == Local2Upper((UBYTE) * b); a++, b++)
  161.     {
  162.         if (!(*a)) return (0);
  163.     }
  164.  
  165.     return ((UBYTE) (Local2Upper((UBYTE) * a) - Local2Upper((UBYTE) * b)));
  166. }
  167.  
  168. static int
  169. IsDirectory(char *Name)
  170. {
  171.     struct FileInfoBlock *FileInfo;
  172.    int isdir = FALSE;
  173.  
  174.     DPOS;
  175.  
  176.     if (NOT(exist(Name))) return FALSE;
  177.  
  178.     if (FileInfo = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, TAG_DONE))
  179.     {
  180.         BPTR    FileLock;
  181.  
  182.         if (FileLock = Lock((UBYTE *) Name, ACCESS_READ))
  183.         {
  184.             if (Examine(FileLock, FileInfo)) isdir = (FileInfo->fib_DirEntryType > 0) ? TRUE : FALSE;
  185.  
  186.             UnLock(FileLock);
  187.         }
  188.  
  189.         FreeDosObject(DOS_FIB, FileInfo);
  190.     }
  191.  
  192.     return isdir;
  193. }
  194.  
  195. int
  196. filetype(char *Name)
  197. {
  198. /* A table of valid ASCII characters (7 bits). */
  199.  
  200.     BYTE    ValidTab[256] =
  201.     {
  202.         0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0,
  203.         0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
  204.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  205.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  206.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  207.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  208.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  209.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  210.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  211.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  212.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  213.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  214.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  215.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  216.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  217.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  218.     };
  219.  
  220. /* A table of clearly invalid ASCII characters (8 bits). */
  221.  
  222.     BYTE    InvalidTab[256] =
  223.     {
  224.         1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
  225.         1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
  226.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  227.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  228.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  229.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  230.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  231.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  232.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  233.         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
  234.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  235.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  236.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  237.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  238.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  239.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  240.     };
  241.     ULONG *Buffer;
  242.     int    Type = TYPE_FILE;
  243.     SHORT i,
  244.             Len = strlen(Name);
  245.  
  246.     DPOS;
  247. /*
  248.  * Allocate a buffer for the first 400 bytes of the file.
  249.  */
  250.  
  251.    if(IsDirectory(Name)) return TYPE_DIR;
  252.  
  253.     if (Buffer = (ULONG *) MyAllocVec(400, MEMF_CLEAR, NO_KILL))
  254.     {
  255.         BPTR    File,
  256.                 Size;
  257.  
  258.     /* Open the file. */
  259.  
  260.         if (File = Open((UBYTE *) Name, MODE_OLDFILE))
  261.         {
  262.         /* Read the first 400 bytes. */
  263.  
  264.             if ((Size = Read(File, (char *)Buffer, 400)) >= sizeof(ULONG))
  265.             {
  266.             /* Examine the first longword. */
  267.  
  268.                 switch (Buffer[0])
  269.                 {
  270.                     case 0x03E7:
  271.                         Type = TYPE_OBJECT;
  272.                         break;
  273.  
  274.                     case 0x03F3:
  275.                         Type = TYPE_EXECUTABLE;
  276.                         break;
  277.  
  278.                     case 0x03FA:
  279.                         Type = TYPE_LIB;
  280.                         break;
  281.  
  282.                     case 0xF7593647:
  283.                         Type = TYPE_TEXFONT;
  284.                         break;
  285.  
  286.                     case 0xF7020183:
  287.                         Type = TYPE_TEXDVI;
  288.                         break;
  289.  
  290.                     case 0xF7832020:
  291.                         Type = TYPE_GF;
  292.                         break;
  293.  
  294.                     case 'FLIB':
  295.                         Type = TYPE_FLIB;
  296.                         break;
  297.  
  298.                     case 'FORM':
  299.                         switch (Buffer[2])
  300.                         {
  301.                             case 'ILBM':
  302.                                 Type = TYPE_ILBM;
  303.                                 break;
  304.  
  305.                             case 'ANIM':
  306.                                 Type = TYPE_ANIM;
  307.                                 break;
  308.  
  309.                             case '8SVX':
  310.                                 Type = TYPE_8SVX;
  311.                                 break;
  312.  
  313.                             case 'SMUS':
  314.                                 Type = TYPE_SMUS;
  315.                                 break;
  316.  
  317.                             case 'FTXT':
  318.                                 Type = TYPE_FTXT;
  319.                                 break;
  320.  
  321.                             case 'PREF':
  322.                                 Type = TYPE_PREFS;
  323.                                 break;
  324.  
  325.                             case 'TERM':
  326.                                 Type = TYPE_TERM;
  327.                                 break;
  328.                         }
  329.  
  330.                         break;
  331.  
  332.                     case 'IMP!':
  333.                         Type = TYPE_IMPLODER;
  334.                         break;
  335.  
  336.                     case 'PP20':
  337.                         Type = TYPE_POWERPACKER;
  338.                         break;
  339.  
  340.                     case 'DMS!':
  341.                         Type = TYPE_DMS;
  342.                         break;
  343.  
  344.                     case 'Warp':
  345.                         Type = TYPE_WARP;
  346.                         break;
  347.  
  348.                     case 'ZOOM':
  349.                         Type = TYPE_ZOOM;
  350.                         break;
  351.  
  352.                     case 0x504B0304:
  353.                         Type = TYPE_ZIP;
  354.                         break;
  355.  
  356.                     case 'ZOO ':
  357.                         Type = TYPE_ZOO;
  358.                         break;
  359.  
  360.                     case 'GIF8':
  361.                         Type = TYPE_GIF;
  362.                         break;
  363.  
  364.                     default:
  365.                         break;
  366.                 }
  367.  
  368.             /*
  369.              * No match yet, see if it's an ASCII file.
  370.              */
  371.  
  372.                 if (Type == TYPE_FILE)
  373.                 {
  374.                     UBYTE *CharBuffer = (UBYTE *) Buffer;
  375.                     SHORT Count = 0;
  376.  
  377.                     for (i = 0; i < Size; i++)
  378.                     {
  379.                         if (ValidTab[CharBuffer[i]]) Count++;
  380.                         else
  381.                         {
  382.                             if (InvalidTab[CharBuffer[i]])
  383.                             {
  384.                                 Count = 0;
  385.                                 break;
  386.                             }
  387.                         }
  388.                     }
  389.  
  390.                 /*
  391.                  * If more than 75% of the characters in the first 400 bytes
  392.                  * are legal ASCII characters this file is supposed to be a
  393.                  * text file.
  394.                  */
  395.  
  396.                     if (Count > 3 * (Size / 4)) Type = TYPE_TEXT;
  397.                 }
  398.  
  399.             /* Still no match, have another try */
  400.  
  401.                 if (Type == TYPE_FILE)
  402.                 {
  403.                     if ((Buffer[0] & 0xFFFF0000) == 0x1A080000) Type = TYPE_ARC;
  404.                     else
  405.                     {
  406.                         if ((Buffer[0] & 0x0000FFFF) == 0x00002D6C && (Buffer[1] & 0xFF00FF00) == 0x68002D00)
  407.                             Type = TYPE_LHARC;
  408.                         else
  409.                         {
  410.                             switch (Buffer[0] & 0xFFFF0000)
  411.                             {
  412.                                 case 0x434A0000:
  413.                                     Type = TYPE_NEWMANX;
  414.                                     break;
  415.  
  416.                                 case 0x414A0000:
  417.                                     Type = TYPE_OLDMANX;
  418.                                     break;
  419.  
  420.                                 case 0x636A0000:
  421.                                     Type = TYPE_NEWMANXLIB;
  422.                                     break;
  423.  
  424.                                 case 0x616A0000:
  425.                                     Type = TYPE_OLDMANXLIB;
  426.                                     break;
  427.  
  428.                                 case 0xF5000000:
  429.                                     Type = TYPE_BASIC;
  430.                                     break;
  431.  
  432.                                 default:
  433.                                     break;
  434.                             }
  435.                         }
  436.                     }
  437.                 }
  438.  
  439.             /*
  440.              * Take a look at the file name suffixes.
  441.              */
  442.                 global_type = Type;
  443.  
  444.                 switch (Type)
  445.                 {
  446.                     case TYPE_TEXT:
  447.                         for (i = 0; i < sizeof(TextSuffix) / sizeof(struct Suffix); i++)
  448.                         {
  449.                             Size = strlen(TextSuffix[i].Name);
  450.  
  451.                             if (Len >= Size)
  452.                             {
  453.                                 if (!StrCmp(&Name[Len - Size], TextSuffix[i].Name))
  454.                                 {
  455.                                     Type = TextSuffix[i].Type;
  456.                                     break;
  457.                                 }
  458.                             }
  459.                         }
  460.  
  461.                         break;
  462.  
  463.                     case TYPE_EXECUTABLE:
  464.                         for (i = 0; i < sizeof(ExecutableSuffix) / sizeof(struct Suffix); i++)
  465.                         {
  466.                             Size = strlen(ExecutableSuffix[i].Name);
  467.  
  468.                             if (Len >= Size)
  469.                             {
  470.                                 if (!StrCmp(&Name[Len - Size], ExecutableSuffix[i].Name))
  471.                                 {
  472.                                     Type = ExecutableSuffix[i].Type;
  473.                                     break;
  474.                                 }
  475.                             }
  476.                         }
  477.  
  478.                         break;
  479.  
  480.                     case TYPE_OBJECT:
  481.                         if (Len >= 4)
  482.                             if (!StrCmp(&Name[Len - 4], ".LIB")) Type = TYPE_LIB;
  483.  
  484.                         break;
  485.  
  486.                     default:
  487.                         break;
  488.                 }
  489.             }
  490.  
  491.             Close(File);
  492.         }
  493.  
  494.         MyFreeVec(Buffer);
  495.     }
  496.  
  497.     return Type;
  498. }
  499.