#include // printf #include // memcpy #include // getopt #include // dirname/basename #include // realpath #include // realpath #ifdef USE_SYSLOG #include #endif #include "hasher.h" #include "log.h" #include "main.h" #include "manipulations.h" #define PATHBUF 4097 #define BUFLEN 2048 int run_verbose = 0; int run_terse = 0; int force_print_parameters = 0; FILE * get_outfile(FILE *infile, const char * filepath){ FILE* outfile; if(infile == stdin){ outfile = stdout; } else { //Taken from man dirname(3) const char * extension = ".aux"; size_t extlen = sizeof(extension); char * filepath2 = realpath(filepath, NULL); if(run_verbose){ printf("Realpath for infile is %s\n", filepath2); } size_t outpathlen = strlen(filepath2) + 3 + extlen; char * outpath = (char*)malloc(outpathlen); char *dirc = strdup(filepath2); char *basec = strdup(filepath2); char *dir = dirname(dirc); char *base = basename(basec); int pathlen; snprintf(outpath, outpathlen, "%s/.%s%s", dir, base, extension); free(dirc); free(basec); free(filepath2); if(run_verbose){ printf("Committing hash to auxiliary file %s\n", outpath); } (void)pathlen; outfile = fopen(outpath, "w"); } return outfile; } /* Give blocks of data to the message digest algorithm. */ size_t digest_file(FILE * infile){ /* Set up input buffers */ // unsigned char * in stores the unsigned version of signin unsigned char * in = (unsigned char*)malloc(BUFLEN * sizeof *in); /* End set up buffers*/ size_t bytesdigested = 0; unsigned int round = 0; while(!feof(infile) && !ferror(infile)){ round++; size_t bytesread = fread((unsigned char*)in, sizeof(char), sizeof(char) * BUFLEN, infile); if(bytesread==0){ verb("0 bytes read, breaking"); break; } digest_part(in, bytesread); bytesdigested += bytesread; verb("Passed %lu bytes to digest algorithm in round %u, %lu bytes passed so far", bytesread, round, bytesdigested); } if(run_verbose){ printf("Input:\n\t"); for(int i = 0; i < bytesdigested; i++){ printf("%02x ", in[i]); } printf("\n"); } free(in); return bytesdigested; } int main(int argc, char *const argv[]){ #ifdef USE_SYSLOG openlog(PROGNAME, 0, LOG_USER); #endif char *filepath = (char*)malloc(PATHBUF * sizeof *filepath); int opt; while((opt = getopt(argc, argv, "vhtpf:")) != -1) { switch(opt){ case 'v': run_verbose = 1; break; case 'h': print_help(); return 0; case 't': run_terse = 1; break; case 'p': force_print_parameters = 1; break; case 'f': memcpy(filepath, optarg, strlen(optarg)); break; default: printf("Literally how could you pass an unspecified argument to this program\n"); } } /** Print run parameters at startup */ if(force_print_parameters) { if(run_terse && run_verbose){ printf(PROGNAME " called with arguments to run both tersely and verbosely, the author legitimately cannot tell what you want her to do\n"); } else if(run_terse) { printf(PROGNAME " will run tersely\n"); } else if(run_verbose) { printf(PROGNAME " will run verbosely\n"); } if(!run_terse){ if(filepath != NULL){ printf(PROGNAME " will read input from file %s\n", filepath); } else { printf(PROGNAME " will read input from standard input\n"); } } } if(!init_hasher()){ log(LOG_INFO, "Error encountered while initializing hasher"); } begin_digest(); /* Set up the input stream Try to open file pointed to by filepath, or else use stdin */ FILE * infile; if(strlen(filepath) >= 0){ log(LOG_DEBUG, "Trying to open file %s for input", filepath); infile = fopen(filepath, "r"); } if(infile == NULL){ infile = stdin; } /* End set up the input stream */ size_t bytesdigested = digest_file(infile); (void)bytesdigested; if(infile != stdin){ fclose(infile); } unsigned int len; unsigned char * a = get_digest(&len); unsigned int aalen; char *aa = atohex(a, len, &aalen); FILE * outfile = get_outfile(infile, filepath); /* Commit hash to auxiliary file */ if(run_verbose){ printf("Output:\n\t"); } if(run_verbose && outfile != stdout){ fwrite(aa, sizeof(*aa), aalen, stdout); } size_t bytes_written = 0; size_t bytes_round; while(bytes_written < aalen && !ferror(outfile)){ bytes_round = fwrite(aa + bytes_written, sizeof(*aa), aalen - bytes_written, outfile); bytes_written += bytes_round; verb("Round wrote %lu bytes\n", bytes_round); } /* End commit hash to auxiliary file*/ OPENSSL_free(a); free(aa); if(deinit_hasher()){ log(LOG_INFO, "Error encountered while deinitializing hasher"); } #ifdef USE_SYSLOG closelog(); #endif return 0; }