#include #include #include #include #ifndef SEEK_SET #define SEEK_SET 0 #endif #ifndef SEEK_END #define SEEK_END 2 #endif #if defined(MSDOS) || defined(_MSDOS) || defined(_MSDOS_) || defined(__MSDOS__) #define MSDOSEXE #endif static char tri[]="000"; static char *code="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int debug = 0; #define STREQ(a,b) (*(a) == *(b) ? !strcmp((a),(b)) : 0) #define STREQN(a,b,n) (*(a) == *(b) ? !strncmp((a),(b),(n)) : 0) #define STRNEQ(a,b) (*(a) == *(b) ? strcmp((a),(b)) : 1) #define STRNEQN(a,b,n) (*(a) == *(b) ? strncmp((a),(b),(n)) : 1) #define COPYRIGHTF "C (C) Copr." #define COPYRIGHTC "/* (C) Copr." int lencopyf = sizeof(COPYRIGHTF)-1; int lencopyc = sizeof(COPYRIGHTC)-1; #define UNDEF "#undef" int lenundef = sizeof(UNDEF)-1; void encode(fhash, tri) unsigned long fhash; char tri[]; { int i; for (i=0;i<3;i++) { tri[i] = code[fhash % 36]; fhash /= 36; } } unsigned long hash_buffer(buffer, length) char *buffer; unsigned int length; { #define islf(c) (c == 10 || c == 13) #define TAB 9 #define SPACE 32 unsigned long sum = 199992L; unsigned int i; char c; int hashing = 0, saw_white = 0; /* Not non-null based on the off chance that it gets used for */ /* some binary data someday. It's remote, and the procedure wouldn't */ /* work well for binaries, but better it should work at all than not */ for (i=0;i= 2) && (STREQN(dot-2,".f",2) || STREQN(dot-2,".F",2))) { /* If end in .f, look for .for */ strcat(basename,"or"); infile = fopen(basename,"r"); if (infile == NULL) break; else f_hack = 1; } else if ((dot - basename >= 4) && (STREQN(dot-4,".for",4) || STREQN(dot-4,".FOR",4))) { /* If end in .for, look for .f */ dot[-2] = '\0'; infile = fopen(basename,"r"); if (infile == NULL) break; else f_hack = -1; } else break; /* File isn't present */ } fclose(infile); fhash = hash_file(basename, error); hashed = 1; dot = strrchr(basename,'.'); encode(fhash, tri); } namep = NULL; dot = strrchr(name,'.')+1; if (STREQN(tri, dot, 3)) { out = 1; } } namep = name; linep++; /* Move to next char */ while (*linep && linep - line < 256 && (*linep == 10 || *linep == 13)) linep++; /* Move past CR or LF chars */ continue; } if (*linep != 32) { if (namep == NULL) namep = name; *namep++ = *linep++; } } continue; } if (out) { if (f_hack) { /* Rewrite Index: file.f to Index: file.for if needed */ f_hack = 0; if (STREQN("Index:", line, 6)) { dot = strrchr(line,'.'); if (dot == NULL) { fprintf(stderr,"Inconsistency in Index line: %s", line); exit(5); } if (strlen(line) <= strlen(dot)) { fprintf(stderr,"Length problem in Index line: %s", line); exit(5); } if (dot[1] != 'f') { fprintf(stderr,"Wrong extension in Index line: %s", line); exit(5); } *dot = '\0'; fputs(line, stdout); fputs((f_hack == 1 ? ".for\n" : ".f\n"), stdout); continue; } } fputs(line, stdout); } } return fhash; } char *use_message[] = { #ifndef MSDOSEXE "Usage: NRident [-r | -u | -c text] file file ...\n", #else "Usage: NRident [-c text] file file ...\n", #endif " Or NRident -p patchfile \n", " Lists to standard output the checksum-encoding-names for NR files.\n", #ifndef MSDOSEXE " -r renames files to the checksum-encoding-name\n", " -u un-renames back to original names\n", #endif " -c takes next arg as a comment to be appended to each line of list\n", " -p output patches for files in current directory \n", " (Useful when redirecting output to a file.)\n", "" }; #define RENAME 0x1 #define COMMENT 0x2 #define OUTPUT 0x4 #define UNDO 0x8 #define PATCH 0x10 main(argc,argv) char **argv; int argc; { unsigned int action = OUTPUT; /* Default action */ int nextarg=0, error; unsigned long fhash; char newname[64], *dot, *comment, *null_comment=""; char **use; comment = null_comment; if (argc < 2) { use = use_message; while (**use != '\0') fputs(*use++,stderr); exit(1); } if (!strcmp(argv[1],"-c")) { action = COMMENT; comment = argv[2]; nextarg += 2; } if (!strcmp(argv[1],"-p")) { action = PATCH; nextarg++; } #ifndef MSDOSEXE if (!strcmp(argv[1],"-r")) { action = RENAME; nextarg++; } if (!strcmp(argv[1],"-u")) { action = UNDO; nextarg++; } #endif while (++nextarg < argc) { if (!(action == PATCH)) { dot = strrchr(argv[nextarg],'.'); if (dot == NULL) { fprintf(stderr, "NRident: skipping file %s: not of form file.ext\n",argv[nextarg]); continue; } } if ((action == OUTPUT) || (action == RENAME) || (action == COMMENT)) { /* normal operation */ fhash = hash_file(argv[nextarg], &error); if (error) continue; encode(fhash, tri); if (strlen(argv[nextarg]) > 60) { fprintf(stderr,"Name %s longer than internal assumption",argv[nextarg]); continue; } strncpy(newname,argv[nextarg],64); strcat(newname,"."); strcat(newname,tri); #ifdef OLD dot = strrchr(newname,'.'); if (dot) { strcpy(dot+1,tri); } else { fprintf(stderr, "NRident: file %s not of form file.ext\n",argv[nextarg]); continue; } #endif if (action == RENAME) { rename(argv[nextarg],newname); fprintf(stdout,"%-15s %-15s (renaming)\n",argv[nextarg],newname); } else if (action == OUTPUT) { fprintf(stdout,"%-15s %-15s\n",argv[nextarg],newname); } else if (action == COMMENT) { fprintf(stdout,"%-15s %-15s %s\n",argv[nextarg],newname,comment); } } else if (action == UNDO) { strncpy(newname,argv[nextarg],64); dot = strrchr(newname,'.'); /* Check for properly encoded name */ if (dot == NULL || strlen(dot) != 4 || strchr(code,dot[1]) == NULL || strchr(code,dot[2]) == NULL || strchr(code,dot[3]) == NULL) { fprintf(stderr, "NRident: skipping %s: not an ident name\n",argv[nextarg]); continue; } *dot = '\0'; rename(argv[nextarg],newname); fprintf(stdout,"%-15s %-15s (renaming)\n",argv[nextarg],newname); } else if (action == PATCH) { read_patchfile(argv[nextarg],&error); } } exit(0); }