home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 31 / CDASC_31_1996_juillet_aout.iso / internet / namnum1b.zip / NAME2NUM.C < prev    next >
C/C++ Source or Header  |  1996-05-14  |  13KB  |  455 lines

  1. /* name2num
  2.  * copyright 1996 David J. Binette
  3.  * ALL RIGHT RESERVED
  4.  * Possesion of this source code does not constitute ownership
  5.  */
  6.  
  7. /* written with Tab stops set to 4 */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <sys\stat.h>
  12. #include <string.h>
  13. #include <io.h>
  14.  
  15. typedef unsigned long dword;
  16. typedef unsigned char byte;
  17.  
  18. /* this logfile is created in the CURRENT directory */
  19. #define LOGFILE "name2num.log"
  20. #define    EOS    '\0'
  21.  
  22. /* maximum length of a Fully Qualified pathname */
  23. #define LENMAX    2048
  24.  
  25. /* ---------------------------------------------------------------- */
  26.  
  27. char * Progname;
  28. int    Crcerror;
  29. char * Dirstr;                /* directory component */
  30. char * Namstr;                /* filename component */
  31. char * Extstr;                /* file extension */
  32.  
  33. /* the path/filename seperator character
  34.  * this is for DOS
  35.  * For *nix, change it to: "/"
  36.  */
  37. char * Sepstr= "\\";        /* a 1 character string */
  38.  
  39. /* ---------------------------------------------------------------- */
  40.  
  41. /* this is the CRC32 lookup table
  42.  * thanks Gary S. Brown 
  43.  * 64 lines of 4 values for a 256 dword table (1024 bytes)
  44.  */
  45. dword crc_tab[256] =
  46. {                     /* CRC polynomial 0xedb88320 */
  47.     (dword)0x00000000, (dword)0x77073096, (dword)0xee0e612c, (dword)0x990951ba,
  48.     (dword)0x076dc419, (dword)0x706af48f, (dword)0xe963a535, (dword)0x9e6495a3,
  49.     (dword)0x0edb8832, (dword)0x79dcb8a4, (dword)0xe0d5e91e, (dword)0x97d2d988,
  50.     (dword)0x09b64c2b, (dword)0x7eb17cbd, (dword)0xe7b82d07, (dword)0x90bf1d91,
  51.     (dword)0x1db71064, (dword)0x6ab020f2, (dword)0xf3b97148, (dword)0x84be41de,
  52.     (dword)0x1adad47d, (dword)0x6ddde4eb, (dword)0xf4d4b551, (dword)0x83d385c7,
  53.     (dword)0x136c9856, (dword)0x646ba8c0, (dword)0xfd62f97a, (dword)0x8a65c9ec,
  54.     (dword)0x14015c4f, (dword)0x63066cd9, (dword)0xfa0f3d63, (dword)0x8d080df5,
  55.     (dword)0x3b6e20c8, (dword)0x4c69105e, (dword)0xd56041e4, (dword)0xa2677172,
  56.     (dword)0x3c03e4d1, (dword)0x4b04d447, (dword)0xd20d85fd, (dword)0xa50ab56b,
  57.     (dword)0x35b5a8fa, (dword)0x42b2986c, (dword)0xdbbbc9d6, (dword)0xacbcf940,
  58.     (dword)0x32d86ce3, (dword)0x45df5c75, (dword)0xdcd60dcf, (dword)0xabd13d59,
  59.     (dword)0x26d930ac, (dword)0x51de003a, (dword)0xc8d75180, (dword)0xbfd06116,
  60.     (dword)0x21b4f4b5, (dword)0x56b3c423, (dword)0xcfba9599, (dword)0xb8bda50f,
  61.     (dword)0x2802b89e, (dword)0x5f058808, (dword)0xc60cd9b2, (dword)0xb10be924,
  62.     (dword)0x2f6f7c87, (dword)0x58684c11, (dword)0xc1611dab, (dword)0xb6662d3d,
  63.     (dword)0x76dc4190, (dword)0x01db7106, (dword)0x98d220bc, (dword)0xefd5102a,
  64.     (dword)0x71b18589, (dword)0x06b6b51f, (dword)0x9fbfe4a5, (dword)0xe8b8d433,
  65.     (dword)0x7807c9a2, (dword)0x0f00f934, (dword)0x9609a88e, (dword)0xe10e9818,
  66.     (dword)0x7f6a0dbb, (dword)0x086d3d2d, (dword)0x91646c97, (dword)0xe6635c01,
  67.     (dword)0x6b6b51f4, (dword)0x1c6c6162, (dword)0x856530d8, (dword)0xf262004e,
  68.     (dword)0x6c0695ed, (dword)0x1b01a57b, (dword)0x8208f4c1, (dword)0xf50fc457,
  69.     (dword)0x65b0d9c6, (dword)0x12b7e950, (dword)0x8bbeb8ea, (dword)0xfcb9887c,
  70.     (dword)0x62dd1ddf, (dword)0x15da2d49, (dword)0x8cd37cf3, (dword)0xfbd44c65,
  71.     (dword)0x4db26158, (dword)0x3ab551ce, (dword)0xa3bc0074, (dword)0xd4bb30e2,
  72.     (dword)0x4adfa541, (dword)0x3dd895d7, (dword)0xa4d1c46d, (dword)0xd3d6f4fb,
  73.     (dword)0x4369e96a, (dword)0x346ed9fc, (dword)0xad678846, (dword)0xda60b8d0,
  74.     (dword)0x44042d73, (dword)0x33031de5, (dword)0xaa0a4c5f, (dword)0xdd0d7cc9,
  75.     (dword)0x5005713c, (dword)0x270241aa, (dword)0xbe0b1010, (dword)0xc90c2086,
  76.     (dword)0x5768b525, (dword)0x206f85b3, (dword)0xb966d409, (dword)0xce61e49f,
  77.     (dword)0x5edef90e, (dword)0x29d9c998, (dword)0xb0d09822, (dword)0xc7d7a8b4,
  78.     (dword)0x59b33d17, (dword)0x2eb40d81, (dword)0xb7bd5c3b, (dword)0xc0ba6cad,
  79.     (dword)0xedb88320, (dword)0x9abfb3b6, (dword)0x03b6e20c, (dword)0x74b1d29a,
  80.     (dword)0xead54739, (dword)0x9dd277af, (dword)0x04db2615, (dword)0x73dc1683,
  81.     (dword)0xe3630b12, (dword)0x94643b84, (dword)0x0d6d6a3e, (dword)0x7a6a5aa8,
  82.     (dword)0xe40ecf0b, (dword)0x9309ff9d, (dword)0x0a00ae27, (dword)0x7d079eb1,
  83.     (dword)0xf00f9344, (dword)0x8708a3d2, (dword)0x1e01f268, (dword)0x6906c2fe,
  84.     (dword)0xf762575d, (dword)0x806567cb, (dword)0x196c3671, (dword)0x6e6b06e7,
  85.     (dword)0xfed41b76, (dword)0x89d32be0, (dword)0x10da7a5a, (dword)0x67dd4acc,
  86.     (dword)0xf9b9df6f, (dword)0x8ebeeff9, (dword)0x17b7be43, (dword)0x60b08ed5,
  87.     (dword)0xd6d6a3e8, (dword)0xa1d1937e, (dword)0x38d8c2c4, (dword)0x4fdff252,
  88.     (dword)0xd1bb67f1, (dword)0xa6bc5767, (dword)0x3fb506dd, (dword)0x48b2364b,
  89.     (dword)0xd80d2bda, (dword)0xaf0a1b4c, (dword)0x36034af6, (dword)0x41047a60,
  90.     (dword)0xdf60efc3, (dword)0xa867df55, (dword)0x316e8eef, (dword)0x4669be79,
  91.     (dword)0xcb61b38c, (dword)0xbc66831a, (dword)0x256fd2a0, (dword)0x5268e236,
  92.     (dword)0xcc0c7795, (dword)0xbb0b4703, (dword)0x220216b9, (dword)0x5505262f,
  93.     (dword)0xc5ba3bbe, (dword)0xb2bd0b28, (dword)0x2bb45a92, (dword)0x5cb36a04,
  94.     (dword)0xc2d7ffa7, (dword)0xb5d0cf31, (dword)0x2cd99e8b, (dword)0x5bdeae1d,
  95.     (dword)0x9b64c2b0, (dword)0xec63f226, (dword)0x756aa39c, (dword)0x026d930a,
  96.     (dword)0x9c0906a9, (dword)0xeb0e363f, (dword)0x72076785, (dword)0x05005713,
  97.     (dword)0x95bf4a82, (dword)0xe2b87a14, (dword)0x7bb12bae, (dword)0x0cb61b38,
  98.     (dword)0x92d28e9b, (dword)0xe5d5be0d, (dword)0x7cdcefb7, (dword)0x0bdbdf21,
  99.     (dword)0x86d3d2d4, (dword)0xf1d4e242, (dword)0x68ddb3f8, (dword)0x1fda836e,
  100.     (dword)0x81be16cd, (dword)0xf6b9265b, (dword)0x6fb077e1, (dword)0x18b74777,
  101.     (dword)0x88085ae6, (dword)0xff0f6a70, (dword)0x66063bca, (dword)0x11010b5c,
  102.     (dword)0x8f659eff, (dword)0xf862ae69, (dword)0x616bffd3, (dword)0x166ccf45,
  103.     (dword)0xa00ae278, (dword)0xd70dd2ee, (dword)0x4e048354, (dword)0x3903b3c2,
  104.     (dword)0xa7672661, (dword)0xd06016f7, (dword)0x4969474d, (dword)0x3e6e77db,
  105.     (dword)0xaed16a4a, (dword)0xd9d65adc, (dword)0x40df0b66, (dword)0x37d83bf0,
  106.     (dword)0xa9bcae53, (dword)0xdebb9ec5, (dword)0x47b2cf7f, (dword)0x30b5ffe9,
  107.     (dword)0xbdbdf21c, (dword)0xcabac28a, (dword)0x53b39330, (dword)0x24b4a3a6,
  108.     (dword)0xbad03605, (dword)0xcdd70693, (dword)0x54de5729, (dword)0x23d967bf,
  109.     (dword)0xb3667a2e, (dword)0xc4614ab8, (dword)0x5d681b02, (dword)0x2a6f2b94,
  110.     (dword)0xb40bbe37, (dword)0xc30c8ea1, (dword)0x5a05df1b, (dword)0x2d02ef8d
  111. };
  112.  
  113. /* ---------------------------------------------------------------- */
  114.  
  115. void usage(int longhelp)
  116. {
  117.     fprintf(stderr,
  118.             "%s, Version 1.0 Beta, copyright 1996 David J. Binette\n"
  119.             "ALL RIGHTS RESERVED\n"
  120.             "email to dbin@sce.de\n"
  121.             "CRC32 code courtesy Gary S. Brown\n",
  122.             Progname);
  123.  
  124.     fprintf(stderr,
  125.             "usage: %s [-d] [-f] [-h] [-n] [-u] [-v] {[path\\]filename}....\n",
  126.             Progname);
  127.  
  128.     if(!longhelp)
  129.     {
  130.     fprintf(stderr,
  131.             "Use %s -h for license and usage information BEFORE using.\n",
  132.             Progname);
  133.     fprintf(stderr,
  134.             "sample usage for automated non-interactive use:\n"
  135.             "%s -d -f -v *.jpg *.gif\n",
  136.             Progname);
  137.     }
  138.     else
  139.     {
  140.     fprintf(stderr,
  141.             "-d   Delete, delete duplicate files\n"
  142.             "-f   Force, do not display startup warning\n"
  143.             "-n   NoLog, Do not append log info to %s (in current dir)\n"
  144.             "-u   Update file comment (not yet implimented)\n"
  145.             "-v   Verbose output\n"
  146.             "-h   This Help\n",
  147.             LOGFILE);
  148.     fprintf(stderr,
  149.             "Renames files to CRC32 of contents with the original filename extension.\n"
  150.             "Multiple identical copies of the same file can optionally be deleted.\n"
  151.             "NOTE: It is highly unlikely but NOT impossible that two files\n"
  152.             "      will have the same CRC32. If -d is specified the NEW copy is discarded.\n");
  153.  
  154.     fprintf(stderr,
  155.             "      !-!-!-!-!-! USE AT YOUR OWN RISK !-!-!-!-!-!\n"
  156.             "Use of this program is restricted to personal private use\n"
  157.             "and not for profit organizations.  Other use requires payment of $100(US)\n"
  158.             "Make cheques payable to:\n"
  159.             "David J. Binette\n"
  160.             "Box 12 Kootenay Bay\n"
  161.             "British Columbia\n"
  162.             "Canada V0B 1X0\n");
  163.     }
  164.     exit(1);
  165. }
  166.  
  167. /* ---------------------------------------------------------------- */
  168.  
  169. char *basename(char *s)
  170. {
  171.     char *p;
  172.     p = strrchr(s,*Sepstr);
  173.     if(p && *p)
  174.     {
  175.         char *q;
  176.         p++;
  177.         q = strrchr(p, '.');
  178.         if(q && *q)
  179.             *q = EOS;
  180.     }
  181.     return p;
  182. }
  183.  
  184. /* ---------------------------------------------------------------- */
  185.  
  186. /* open a file
  187.  * calculate the CRC32 of the entire contents
  188.  * return the CRC
  189.  * if there is an error rdet the global variable Crcerror
  190.  */
  191. dword readfilecrc(char *fname)
  192. {
  193.     register int c;
  194.     register dword crc;
  195.     FILE *fp;
  196.  
  197.     Crcerror=0;
  198.  
  199.     if((fp = fopen(fname, "rb")) == (FILE*)0)
  200.     {
  201.         perror(fname);
  202.         Crcerror=1;
  203.         return -1;
  204.     }
  205.  
  206.     crc = (dword)0xFFFFFFFF;
  207.  
  208.     while((c = getc(fp)) != EOF)
  209.         crc =  ~(crc_tab[(int)((crc ^ c) & 0xff)] ^ ((crc >> 8) & (dword)0x00FFFFFF));
  210.  
  211.     fclose(fp);
  212.     return crc;
  213. }
  214.  
  215. /* ---------------------------------------------------------------- */
  216.  
  217. /* apply the existing Directory
  218.  * and filename extension
  219.  * to the specified filename
  220.  * and return the fully qualified name
  221.  */
  222. char * DNE2fqn(char *name)
  223. {
  224.     static char tmp[LENMAX+1];
  225.     tmp[0] = EOS;
  226.  
  227.     if(Dirstr && *Dirstr)
  228.     {
  229.         strcat(tmp,Dirstr);
  230.         strcat(tmp,Sepstr);
  231.     }
  232.  
  233.     if(name && *name)
  234.         strcat(tmp,name);
  235.     
  236.     if(Extstr && *Extstr)
  237.     {
  238.         strcat(tmp,".");
  239.         strcat(tmp,Extstr);
  240.     }
  241.     return tmp;
  242. }
  243.  
  244. /* ---------------------------------------------------------------- */
  245.  
  246. /* Given a fully qualified name
  247.  * break it up into 3 parts, for Directory ,FileName and Extension
  248.  * The global variables for 
  249.  * Dirstr to the directory name
  250.  * Namstr to the file name
  251.  * Extstr to the extension
  252.  * return 0 if OK, 1 if error 
  253.  */
  254.  
  255.  
  256. int fqn2DNE(char *fqn)
  257. {
  258.     static char tmp[LENMAX+1];
  259.     char *p1;
  260.     char *p2;
  261.  
  262.     Dirstr = NULL;
  263.     Namstr = NULL;
  264.     Extstr = NULL;
  265.  
  266.     if(!fqn || !*fqn)
  267.         return 1;
  268.  
  269.     if(strlen(fqn) > LENMAX)
  270.         return 1;
  271.  
  272.     strcpy(tmp, fqn);
  273.  
  274.     p1 = strrchr(tmp,*Sepstr);
  275.     p2 = strrchr(tmp,'.');
  276.  
  277.     if((p2 && *p2) && (p2 > p1))
  278.     {
  279.         *p2 = EOS;
  280.         Extstr = p2+1;
  281.     }
  282.  
  283.     if(p1 && *p1)
  284.     {
  285.         *p1 = EOS;
  286.         Namstr = p1+1;
  287.         Dirstr = tmp;
  288.     }
  289.     else
  290.         Namstr = tmp;
  291.     return 0;
  292. }
  293.  
  294. /* ---------------------------------------------------------------- */
  295.  
  296. void main(int argc, char *argv[])
  297. {
  298.     struct stat statbuf;
  299.     dword crc;
  300.     int arg = 0;
  301.     char *origname;
  302.     char newname[9];
  303.     char *newfqn;
  304.     char tmp[80];
  305.     int    wantlog        = 1;
  306.     int    wantforce    = 0;
  307.     int    wantdelete    = 0;
  308.     int    wantverbose    = 0;
  309.     int    flagger        = 0;
  310.  
  311.     Progname = basename(argv[0]);
  312.  
  313.     if(argc == 1)
  314.         usage(0);
  315.  
  316.     /* process the command line */
  317.     while(++arg < argc)
  318.     {
  319.         /* stop processing option on first filename */
  320.         if(argv[arg][0] != '-')
  321.             break;
  322.  
  323.         /* process command line options */
  324.         switch(argv[arg][1])
  325.         {
  326.         case 'd': wantdelete=1;    break;
  327.         case 'f': wantforce=1;    break;
  328.         case 'n': wantlog=0;    break;
  329.         case 'u':                 break;
  330.         case 'v': wantverbose=1;break;
  331.         default:    usage(1);    break;
  332.         }
  333.     }
  334.     arg--;
  335.  
  336.     /* ask user if its OK to do it */
  337.     if(!wantforce)
  338.     {
  339.         fprintf(stderr,
  340.             "%s:Enter 'y' to process %d FILES : ",
  341.             Progname,
  342.             argc-1);
  343.  
  344.         gets(tmp);
  345.         if((*tmp != 'y') && (*tmp != 'Y'))
  346.         {
  347.             fprintf(stderr,"Quitting\n");
  348.             exit(1);
  349.         }
  350.     }
  351.  
  352.     /* process each specifie file */
  353.     while(++arg < argc)
  354.     {
  355.         /* when processing many files this is a progress indicator */
  356.         if(wantverbose)
  357.         {
  358.             if((++flagger) & 1)
  359.                 write(1,"+\r",2);
  360.             else
  361.                 write(1,"-\r",2);
  362.         }
  363.  
  364.         origname = argv[arg];
  365.  
  366.         /* dont handle NAME2NUM.log */
  367.         if(!stricmp(origname,LOGFILE))
  368.             continue;
  369.  
  370.         if(stat(origname, &statbuf))
  371.         {
  372.             perror(origname);
  373.             continue;
  374.         }
  375.  
  376.         /* only process normal files */
  377.         if((statbuf.st_mode & S_IFREG) == 0)
  378.         {
  379.             if(wantverbose)
  380.                 fprintf(stderr,"%s is not a plain file.\n", origname);
  381.             continue;
  382.         }
  383.  
  384.         /* split up oldfilename into Directory, Name and Extension */
  385.         if(fqn2DNE(origname))
  386.             continue;
  387.  
  388.         /* calculate the CRC of the entire file contents */
  389.         crc = readfilecrc(origname);
  390.         if(Crcerror)
  391.             continue;
  392.  
  393.         sprintf(newname,"%08lX", crc);
  394.  
  395.         /* if the name IS the CRC, we can skip to the next file */
  396.         if(!strcmp(newname, Namstr))
  397.             continue;
  398.  
  399.         /* Generate the new filename with the original Dir and extension */
  400.         newfqn = DNE2fqn(newname);
  401.  
  402.         /* if the new file already exists, handle that */
  403.         if(access(newfqn,0) == 0)
  404.         {
  405.             if(!wantdelete)
  406.             {
  407.                 fprintf(stderr,
  408.                     "%s EXISTS AS %s\n"
  409.                     "delete %s (y/N)? ",
  410.                     origname,
  411.                     newfqn,
  412.                     origname);
  413.                 *tmp = '\0';
  414.                 gets(tmp);    /* hope the user isn't keyboard happy */
  415.             }
  416.             else
  417.                 *tmp = 'y';
  418.  
  419.             if((*tmp == 'y') || (*tmp != 'Y'))
  420.             {
  421.                 if(wantverbose)
  422.                     fprintf(stderr,"deleting      %s\n", origname);
  423.  
  424.                 if(unlink(origname))
  425.                     perror(origname);
  426.             }
  427.             continue;
  428.         }
  429.  
  430.         /* handle rename of file */
  431.  
  432.  
  433.         if(rename(origname, newfqn))
  434.             fprintf(stderr,"rename FAILED %s <- %s\n", newfqn, origname);
  435.         else
  436.         {
  437.             if(wantverbose)
  438.                 fprintf(stderr,"rename OK     %s <- %s\n", newfqn, origname);
  439.         }
  440.  
  441.         if(wantlog)
  442.         {
  443.             FILE *fp;
  444.             if((fp = fopen(LOGFILE,"a")) != (FILE*)0)
  445.             {
  446.                 fprintf(fp,"rename %s %s\n", newfqn, origname);
  447.                 fclose(fp);
  448.             }
  449.         }
  450.     }
  451.     exit(0);
  452. }
  453.  
  454. /* ---------------------------------------------------------------- */
  455.