home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / file.lzh / file.c < prev    next >
Text File  |  1995-04-27  |  17KB  |  737 lines

  1. /************************************************************************
  2.  * file.c                                                               *
  3.  ************************************************************************
  4.  * A utility to determine the type of a file.                           *
  5.  ************************************************************************
  6.  * Original code: Scott McGee  4/1/93                                   *
  7.  ***********************************************************************/
  8.  
  9.  /***********************************************************************
  10.  revision history:
  11.  
  12.  ed who when     what
  13.  ------------------------------------------------------------------------
  14.     sam 12/03/93 major rewrite to allow the use of magic db files
  15.     sam 12/20/93 added leshort, beshort, lelong, and belong types
  16.     sam 12/23/93 fixed -z option to read magic file
  17.     sam 12/24/93 added support for MAGIC_FILE environment variable
  18.     sam 12/26/93 added -r option
  19.     sam 12/28/93 added tar file identification using istar.c
  20.     sam 12/31/93 added OS-9 Module id (hard coded) w/ module name
  21.     sam 01/01/94 added -help option
  22.   1 sam 01/07/94 added -x option
  23.     sam 01/08/94 handle both OS-9 and OS-9000 files under both OS's
  24.   2 sam 01/22/94 given to Microware for review
  25.     sam 03/22/95 Microware released rights back to me
  26.   3 sam 04/04/95 edition number code moved to file.c from help.c
  27.     sam 04/04/95 readFile fixed to pass size to istar() and checkMagic()
  28.   4 sam 04/27/95 moved OS-9/9K modhead structs to file.h
  29.  ***********************************************************************/
  30.  
  31. #define MAIN
  32. #include <file.h>
  33. #undef MAIN
  34.  
  35.  
  36. #define edition_number 4
  37.  
  38. /* set the edition number */
  39. #if defined(_OSK) || defined(_OS9000)
  40. #if !defined(_BSD)
  41. _asm("_sysedit: equ %0", edition_number);
  42. #endif
  43. #endif
  44.  
  45.  
  46.  
  47. char *byteSwap(buf, count)
  48.   char *buf;
  49.   int  count;
  50. {
  51.     int  i;
  52.     char new[32];
  53.  
  54.     count--;
  55.     for(i=0;i<=count;i++){
  56.         new[i] = buf[count - i];
  57.     }
  58.     return(new);
  59. }
  60.  
  61.  
  62.  
  63. int strucmp(str1, str2)
  64.   char *str1;
  65.   char *str2;
  66. {
  67.     char *new1;
  68.     char *new2;
  69.     char *ptr;
  70.     int  result;
  71.  
  72.     if(str1 == NULL)
  73.         return(-1);
  74.  
  75.     if(str2 == NULL)
  76.         return(1);
  77.  
  78.     new1 = (char *) grab(strlen(str1)*sizeof(char));
  79.     strcpy(new1, str1);
  80.     ptr = new1;
  81.  
  82.     while(*ptr != '\0'){
  83.         *ptr = tolower(*ptr);
  84.         ptr++;
  85.     }
  86.  
  87.     new2 = (char *) grab(strlen(str2)*sizeof(char));
  88.     strcpy(new2, str2);
  89.     ptr = new2;
  90.  
  91.     while(*ptr != '\0'){
  92.         *ptr = tolower(*ptr);
  93.         ptr++;
  94.     }
  95.  
  96.     result = strcmp(new1, new2);
  97.     free(new1);
  98.     free(new2);
  99.     return(result);
  100. }
  101.  
  102.  
  103.  
  104. int struncmp(str1, str2, cnt)
  105.   char *str1;
  106.   char *str2;
  107.   int  cnt;
  108. {
  109.     char *new1;
  110.     char *new2;
  111.     char *ptr;
  112.     int  result;
  113.  
  114.     if(str1 == NULL)
  115.         return(-1);
  116.  
  117.     if(str2 == NULL)
  118.         return(1);
  119.  
  120.     new1 = (char *) grab(strlen(str1)*sizeof(char));
  121.     strcpy(new1, str1);
  122.     ptr = new1;
  123.  
  124.     while(*ptr != '\0'){
  125.         *ptr = tolower(*ptr);
  126.         ptr++;
  127.     }
  128.  
  129.     new2 = (char *) grab(strlen(str2)*sizeof(char));
  130.     strcpy(new2, str2);
  131.     ptr = new2;
  132.  
  133.     while(*ptr != '\0'){
  134.         *ptr = tolower(*ptr);
  135.         ptr++;
  136.     }
  137.  
  138.     result = strncmp(new1, new2, cnt);
  139.     free(new1);
  140.     free(new2);
  141.     return(result);
  142. }
  143.  
  144.  
  145. void readFile(filename)
  146.   char *filename;
  147. {
  148.     struct modhead *mh;
  149.     static char buf[BUFSIZ];
  150.     static char buf2[BUFSIZ];
  151.     char *name;
  152.     DIR  *dp;
  153.     FILE *fp = NULL;
  154.     int  path;
  155.     int  offset;
  156.     int  result;
  157.     int  size;
  158.     int  len;
  159.     int  text;
  160.     int  cntrl;
  161.     int  i;
  162.     unsigned short test;
  163.     fType type = UNKNOWN; 
  164.  
  165.     /* check for trailing '/' from ls command */
  166.     if(filename[strlen(filename)-1] == '/')
  167.         filename[strlen(filename)-1] = '\0';
  168.  
  169.     /* Check to see if it is a directory */
  170.     dp = opendir(filename);
  171.     if(dp != NULL){
  172.         printf("%-16s    directory\n", filename);
  173.         if(recursive == TRUE)
  174.             dirFiles(filename, dp);
  175.         closedir(dp);
  176.         return;
  177.     }
  178.  
  179.     /* Not a directory, read start of file for type checks */
  180.     if(exec_relative == TRUE){
  181.         fp = fopen(filename, "rx");
  182.         if(fp != NULL)
  183.             path = fileno(fp);
  184.         else
  185.             path = -1;
  186.     }else
  187.         path = open(filename, READ_ONLY);
  188.     if(path == -1) {
  189. #if defined(_OSK) || defined(_OS9000)
  190.         if((errno == E_BPNAM) || (errno == E_PNNF)){
  191. #else
  192.         if(errno == ENOENT){
  193. #endif
  194.             printf("%-16s    file not found\n", filename);
  195.             return;
  196.         }else{
  197.             printf("%-16s    error %d reading file\n", filename, errno);
  198.             return;
  199.         }
  200.     }
  201.  
  202.     result = size = read(path, buf, BUFSIZ);
  203.  
  204.     if(result == 0){
  205.         close(path);
  206.         type = EMPTY;
  207.         goto NAME_CHECKS;
  208.     }else if(result < 0){
  209.         close(path);
  210.         type = NOPERMIT;
  211.         goto NAME_CHECKS;
  212.     }
  213.  
  214.     /* check for OS-9/OS-9000 (native) Module */
  215.     if(*(short *) buf == 0x4afc){
  216. #ifndef _LIL_END
  217.         mh = (modhead *) buf;
  218.         printf("%-16s    OS-9 ", filename);
  219.         switch((mh->tylan & 0xff00) >> 8){
  220. #else
  221.         mh = (modhead *) buf;
  222.         printf("%-16s    OS-9000 ", filename);
  223.         switch((mh->tylan & 0xff00) >> 8){
  224. #endif
  225.             case 1:  printf("Program ");
  226.                      break;
  227.             case 2:  printf("Subroutine ");
  228.                      break;
  229.             case 4:  printf("Data ");
  230.                      break;
  231.             case 11: printf("Trap Library ");
  232.                      break;
  233.             case 12: printf("System ");
  234.                      break;
  235.             case 13: printf("File Manager ");
  236.                      break;
  237.             case 14: printf("Device Driver ");
  238.                      break;
  239.             case 15: printf("Device Descriptor ");
  240.         }
  241.         printf("Module");
  242.         offset = *((int *) (buf+0x000c));
  243.         if(offset < size - 32)
  244.             printf(" \"%s\"", buf+offset);
  245.         else{
  246.             if(fp == NULL)
  247.                 fp = fdopen(path, "r");
  248.             result = fseek(fp, offset, SEEK_SET);
  249.             if(result == 0){
  250.                     result = size = read(path, buf2, BUFSIZ);
  251.                     if(result != 0)
  252.                         printf(" \"%s\"", buf2);
  253.             }
  254.         }
  255.         offset = *((int *) (buf+0x0004));
  256.         if((offset < size) && (*(short *) buf == 0x4afc))
  257.             printf(" (...)");
  258.         else{
  259.             fp = fdopen(path, "r");
  260.             result = fseek(fp, offset, SEEK_SET);
  261.             if(result == 0){
  262.                     result = size = read(path, buf2, BUFSIZ);
  263.                     if((result != 0) && (*(short *) buf2 == 0x4afc))
  264.                         printf(" (...)");
  265.             }
  266.         }
  267.         printf("\n");
  268.         close(path);
  269.         return;
  270.     }else if(*(unsigned short *) buf == 0xfc4a){
  271. #ifdef _LIL_END
  272.         mh = (modhhead *) buf;
  273.         printf("%-16s    OS-9 ", filename);
  274.         switch((mh->tylan & 0xff00) >> 8){
  275. #else
  276.         mh = (modhead *) buf;
  277.         printf("%-16s    OS-9000 ", filename);
  278.         switch((mh->tylan & 0xff00) >> 8){
  279. #endif
  280.             case 1:  printf("Program ");
  281.                      break;
  282.             case 2:  printf("Subroutine ");
  283.                      break;
  284.             case 4:  printf("Data ");
  285.                      break;
  286.             case 11: printf("Trap Library ");
  287.                      break;
  288.             case 12: printf("System ");
  289.                      break;
  290.             case 13: printf("File Manager ");
  291.                      break;
  292.             case 14: printf("Device Driver ");
  293.                      break;
  294.             case 15: printf("Device Descriptor ");
  295.         }
  296.         printf("Module");
  297.         offset = *((int *) (buf+0x000c));
  298.         offset = *((int *)byteSwap((char *) &offset, sizeof(int)));
  299.         if(offset < size - 32)
  300.             printf(" \"%s\"", buf+offset);
  301.         else{
  302.             fp = fdopen(path, "r");
  303.             result = fseek(fp, offset, SEEK_SET);
  304.             if(result == 0){
  305.                     result = size = read(path, buf2, BUFSIZ);
  306.                     if(result != 0)
  307.                         printf(" \"%s\"", buf2);
  308.             }
  309.         }
  310.         offset = *((int *) (buf+0x0004));
  311.         offset = *((int *)byteSwap((char *) &offset, sizeof(int)));
  312.         if((offset < size) && (*(unsigned short *) buf == 0xfc4a))
  313.             printf(" (...)");
  314.         else{
  315.             fp = fdopen(path, "r");
  316.             result = fseek(fp, offset, SEEK_SET);
  317.             if(result == 0){
  318.                     result = size = read(path, buf2, BUFSIZ);
  319.                     if(result != 0){
  320.                         test = *(byteSwap(buf2, sizeof(short)));
  321.                         if(*(unsigned short *) test == 0xfc4a)
  322.                             printf(" (...)");
  323.                     }
  324.             }
  325.         }
  326.         printf("\n");
  327.         close(path);
  328.         return;
  329.     }else
  330.       close(path);
  331.  
  332.     /* check for tar file */
  333.     result = istar(buf, size);
  334.     if(result == POSIX_TAR){
  335.         printf("%-16s    POSIX tar file\n", filename);
  336.         return;
  337.     }else if(result == OLD_TAR){
  338.         printf("%-16s    tar file\n", filename);
  339.         return;
  340.     }    
  341.  
  342.     /* check magic file here */
  343.     if(checkMagic(filename, buf, size) == TRUE)
  344.         return;
  345.  
  346.     /* OK, magic file hasn't identified it, so lets see if it is a BIN
  347.        or TEXT and then do name checks */
  348.     text = 0;
  349.     cntrl = 0;
  350.     for(i=0;i<result;i++){
  351.         if(buf[i] == '\n')
  352.             text++;
  353.         else if(buf[i] == '\t')
  354.             text++;
  355.         else if(iscntrl(buf[i]))
  356.             cntrl++;
  357.         else
  358.             text++;
  359.     }
  360.     if((cntrl != 0) && ((text / cntrl) < 7))
  361.         type = BIN;
  362.     else
  363.         type = MISC;
  364.  
  365. NAME_CHECKS:
  366.     name = strrchr(filename, '/');
  367.     if(name == NULL)
  368.         name = filename;
  369.     else
  370.         name++;
  371.     len = strlen(name);
  372.     if(len > 2){
  373.         if(strcmp(&(name[len-2]), ".c") == 0)
  374.             type = C_SOURCE;
  375.         else if(strcmp(&(name[len-2]), ".h") == 0)
  376.             type = C_HEADER;
  377.         else if(strcmp(&(name[len-2]), ".a") == 0)
  378.             type = ASM_SOURCE;
  379.     }
  380.  
  381.     if(len > 4){
  382.         if(strucmp(&name[len-4], ".doc") == 0)
  383.             type = TEXT;
  384.         else if(strucmp(&name[len-4], ".txt") == 0)
  385.             type = TEXT;
  386.         else if(strucmp(&name[len-4], ".asc") == 0)
  387.             type = TEXT;
  388.  
  389.         else if(strucmp(&name[len-4], ".ume") == 0)
  390.             type = UME;
  391.     }
  392.  
  393.     if(len > 6){
  394.         if(struncmp(name, "readme", 6) == 0)
  395.             type = TEXT;
  396.         else if(strucmp(&name[len-6], "readme") == 0)
  397.             type = TEXT;
  398.     }
  399.  
  400.     if(len >= 8){
  401.         if(struncmp(name, "makefile", 8) == 0)
  402.             type = MAKEFILE;
  403.         else if(strucmp(&name[len-8], "makefile") == 0)
  404.             type = MAKEFILE;
  405.     }
  406.  
  407.     /* OK, we identified it as best we can, print out the results */
  408.     switch(type){
  409.         case EMPTY:
  410.             printf("%-16s    an empty (zero length) file\n", filename);
  411.             break;
  412.         case NOPERMIT:
  413.             printf("%-16s    permission denied\n", filename);
  414.             break;
  415.         case MISC:
  416.             printf("%-16s    unidentified text file\n", filename);
  417.             break;
  418.         case BIN:
  419.             printf("%-16s    unidentified binary file\n", filename);
  420.             break;
  421.         case ASM_SOURCE:
  422.             printf("%-16s    assembly source file\n", filename);
  423.             break;
  424.         case MAKEFILE:
  425.             printf("%-16s    makefile\n", filename);
  426.             break;
  427.         case TEXT:
  428.             printf("%-16s    text file\n", filename);
  429.             break;
  430.         case C_SOURCE:
  431.             printf("%-16s    C Source file\n", filename);
  432.             break;
  433.         case C_HEADER:
  434.             printf("%-16s    C Header file\n", filename);
  435.             break;
  436.         case UME:
  437.             printf("%-16s    Ultimuse music file\n", filename);
  438.             break;
  439.         default:
  440.             printf("%-16s    unknown file type\n", filename);
  441.     }
  442. }
  443.  
  444. void getFileNames(filename)
  445.   char *filename;
  446. {
  447.     FILE *fp;
  448.     char file[MAXLINELEN];
  449.     int  result;
  450.  
  451.     if(filename != NULL){
  452.         fp = fopen(filename, "r");
  453.         if(fp == NULL){
  454.             _errmsg(0, "Cannot open file \"%s\" for input\n", filename);
  455.             return;
  456.         }
  457.     }else
  458.         fp = stdin;
  459.  
  460.     result = fscanf(fp, " %s", file);
  461.     while((result != EOF) && (result != 0)){
  462.         readFile(file);
  463.         result = fscanf(fp, " %s", file);
  464.     }
  465.  
  466.     fclose(fp);
  467. }
  468.  
  469.  
  470. int checkMagic(filename, buf, size)
  471.   char *filename;
  472.   char *buf;
  473.   int  size;
  474. {
  475.     MagicList *magic;
  476.     int            match = FALSE;
  477.     int            local_match;
  478.     char           byte_value;
  479.     unsigned short short_value;
  480.     long           long_value;
  481.  
  482.     magic = magicList;
  483.  
  484.     while(magic != NULL){
  485.         while((match == FALSE) && (magic->continuation == TRUE)){
  486.             if(magic->next == NULL)
  487.               return(match);
  488.             magic = magic->next;
  489.         }
  490.             
  491.         if(magic->offset >= size){
  492.             magic = magic->next;
  493.             continue;
  494.         }
  495.  
  496.         if((match == TRUE) && (magic->continuation == FALSE))
  497.             return(match);
  498.  
  499.         local_match = FALSE;
  500.         
  501.         switch(magic->type){
  502.             case BYTE:
  503.             byte_value = buf[magic->offset];
  504.             if(magic->maskFlag == TRUE)
  505.                 byte_value = byte_value & (char) magic->mask;
  506.             switch(magic->op){
  507.                 case LESS:
  508.                 if(byte_value < magic->value) {
  509.                     local_match = TRUE;
  510.                 }
  511.                 break;
  512.                 
  513.                 case GREATER:
  514.                 if(byte_value > magic->value) {
  515.                     local_match = TRUE;
  516.                 }
  517.                 break;
  518.                 
  519.                 case AND:
  520.                 if((byte_value & (char) magic->value) == (char) magic->value) {
  521.                     local_match = TRUE;
  522.                 }
  523.                 break;
  524.                 
  525.                 case OR:
  526.                 if((byte_value & (char) magic->value) != (char) magic->value) {
  527.                     local_match = TRUE;
  528.                 }
  529.                 break;
  530.                 
  531.                 case ANY:
  532.                 local_match = TRUE;
  533.                 break;
  534.                 
  535.                 default:
  536.                 if(byte_value == magic->value) {
  537.                     local_match = TRUE;
  538.                 }
  539.             }
  540.             if(local_match == TRUE){
  541.                 if(magic->continuation != TRUE)
  542.                     printf("%-16s\t", filename);
  543.                 printf(magic->message, byte_value);
  544.             }
  545.             break;
  546.  
  547.             case LESHORT:
  548.             short_value = (unsigned short) *((unsigned short *) &buf[magic->offset]);
  549. #ifndef _LIL_END
  550.             short_value = *(unsigned short *)byteSwap((char *)&short_value, sizeof(short));
  551. #endif
  552.             if(magic->maskFlag == TRUE)
  553.                 short_value = short_value & (unsigned short) magic->mask;
  554.             goto DOSHORT;
  555.  
  556.             case BESHORT:
  557.             short_value = (unsigned short) *((unsigned short *) &buf[magic->offset]);
  558. #ifdef _LIL_END
  559.             short_value = *(unsigned short *)byteSwap((char *)&short_value, sizeof(short));
  560. #endif
  561.             if(magic->maskFlag == TRUE)
  562.                 short_value = short_value & (unsigned short) magic->mask;
  563.             goto DOSHORT;
  564.  
  565.             case SHORT:
  566.             short_value = (unsigned short) *((unsigned short *) &buf[magic->offset]);
  567.             short_value = *(unsigned short *)swap((char *)&short_value, sizeof(short));
  568.             if(magic->maskFlag == TRUE)
  569.                 short_value = short_value & (unsigned short) magic->mask;
  570. DOSHORT:
  571.             switch(magic->op){
  572.                 case LESS:
  573.                 if(short_value < magic->value) {
  574.                     local_match = TRUE;
  575.                 }
  576.                 break;
  577.                 
  578.                 case GREATER:
  579.                 if(short_value > magic->value) {
  580.                     local_match = TRUE;
  581.                 }
  582.                 break;
  583.                 
  584.                 case AND:
  585.                 if((short_value & (char) magic->value) == (char) magic->value) {
  586.                     local_match = TRUE;
  587.                 }
  588.                 break;
  589.                 
  590.                 case OR:
  591.                 if((short_value & (char) magic->value) != (char) magic->value) {
  592.                     local_match = TRUE;
  593.                 }
  594.                 break;
  595.                 
  596.                 case ANY:
  597.                 local_match = TRUE;
  598.                 break;
  599.                 
  600.                 default:
  601.                 if(short_value == magic->value) {
  602.                     local_match = TRUE;
  603.                 }
  604.             }
  605.             if(local_match == TRUE){
  606.                 if(magic->continuation != TRUE)
  607.                   printf("%-16s\t", filename);
  608.                 printf(magic->message, short_value);
  609.             }
  610.             break;
  611.  
  612.             case LELONG:
  613.             long_value = (unsigned long) *((unsigned long *) &buf[magic->offset]);
  614. #ifndef _LIL_END
  615.             long_value = *(unsigned long *)byteSwap((char *)&long_value, sizeof(long));
  616. #endif
  617.             if(magic->maskFlag == TRUE)
  618.                 long_value = long_value & (unsigned long) magic->mask;
  619.             goto DOLONG;
  620.  
  621.             case BELONG:
  622.             long_value = (unsigned long) *((unsigned long *) &buf[magic->offset]);
  623. #ifdef _LIL_END
  624.             long_value = *(unsigned long *)byteSwap((char *)&long_value, sizeof(long));
  625. #endif
  626.             if(magic->maskFlag == TRUE)
  627.                 long_value = long_value & (unsigned long) magic->mask;
  628.             goto DOLONG;
  629.  
  630.             case LONG:
  631.             long_value = *((long *) &buf[magic->offset]);
  632.             long_value = *(unsigned long *)swap((char *)&long_value, sizeof(long));
  633.             if(magic->maskFlag == TRUE)
  634.                 long_value = long_value & magic->mask;
  635. DOLONG:
  636.             switch(magic->op){
  637.                 case LESS:
  638.                 if(long_value < magic->value) {
  639.                     local_match = TRUE;
  640.                 }
  641.                 break;
  642.                 
  643.                 case GREATER:
  644.                 if(long_value > magic->value) {
  645.                     local_match = TRUE;
  646.                 }
  647.                 break;
  648.                 
  649.                 case AND:
  650.                 if((long_value & (char) magic->value) == (char) magic->value) {
  651.                     local_match = TRUE;
  652.                 }
  653.                 break;
  654.                 
  655.                 case OR:
  656.                 if((long_value & (char) magic->value) != (char) magic->value) {
  657.                     local_match = TRUE;
  658.                 }
  659.                 break;
  660.                 
  661.                 case ANY:
  662.                 local_match = TRUE;
  663.                 break;
  664.                 
  665.                 default:
  666.                 if(long_value == magic->value) {
  667.                     local_match = TRUE;
  668.                 }
  669.             }
  670.             if(local_match == TRUE){
  671.                 if(magic->continuation != TRUE)
  672.                   printf("%-16s\t", filename);
  673.                 printf(magic->message, long_value);
  674.             }
  675.             break;
  676.  
  677.             case STRING:
  678.             if(strncmp(&buf[magic->offset], magic->stringValue,
  679.                        strlen(magic->stringValue)) == 0) {
  680.                 if(magic->continuation != TRUE)
  681.                   printf("%-16s\t", filename);
  682.                 printf(magic->message, magic->stringValue);
  683.                 local_match = TRUE;
  684.             }
  685.  
  686.             break;
  687.             default: fprintf(stderr, "Error! Bad magic file type!\n");
  688.                      return(FALSE);
  689.         }
  690.  
  691.         if(local_match == TRUE)
  692.             match = TRUE;
  693.  
  694.         if(match == TRUE){
  695.             if((magic->next == NULL) || (magic->next->continuation == FALSE))
  696.                 printf("\n");
  697.             else if(local_match == TRUE)
  698.                 printf(" ");
  699.  
  700.             magic = magic->next;
  701.  
  702.             if((magic != NULL) && (magic->continuation != TRUE))
  703.                 magic = NULL;
  704.         }else{
  705.             magic = magic->next;
  706.         }
  707.     }
  708.         
  709.     return(match);
  710. }
  711.  
  712.  
  713. void dirFiles(filename, dp)
  714.   char *filename;
  715.   DIR  *dp;
  716. {
  717. #if (defined(_OSK) || defined(_OS9000))
  718.     struct direct *entry;
  719. #else
  720.     struct dirent *entry;
  721. #endif
  722.     char          *path;
  723.  
  724.     while((entry = readdir(dp)) != NULL){
  725.         if(entry->d_name[0] != '.'){
  726.             path = (char *) grab(sizeof(char) * (strlen(filename) +
  727.                                                  strlen(entry->d_name) + 2));
  728.             strcpy(path, filename);
  729.             strcat(path, "/");
  730.             strcat(path, entry->d_name);
  731.             readFile(path);
  732.             free(path);
  733.         }
  734.     }
  735. }
  736.  
  737.