static void propagate(Mstate state) { while (state->ok && state->first_job != NULL) { /* Negative propagation is applied to all types. Positive propagation is applied to ASSIGNMENT only. */ int type = state->first_job->type; int id = state->first_job->id; Term alpha = state->first_job->alpha; Term beta = state->first_job->beta; int pos = state->first_job->pos; job_pop(state); if (type == ASSIGNMENT) propagate_positive(id, state); if (state->ok && flag(Opt->negprop)) propagate_negative(type, id, alpha, beta, pos, state); } if (!state->ok) { zap_jobs(state); restore_from_stack(state->stack); state->stack = NULL; } } /* propagate */
int main(int argc, char **argv) { uint8_t difficulty = 18; uint32_t salt = 0; bool binary = false; bool gen_salt = true; /* Parse command line. */ int opt; while ((opt = getopt(argc, argv, "ibd:s:p:v:")) >= 0) { switch (opt) { case 'i': job_push(slurp(stdin), NULL); break; case 'b': binary = true; break; case 'd': difficulty = strtol(optarg, NULL, 10); break; case 's': gen_salt = false; salt = htonl(strtoll(optarg, NULL, 16)); break; case 'p': job_push(xstrdup(optarg), NULL); break; case 'v': if (jobs == NULL) { fprintf(stderr, "error: specify password option before hash\n"); exit(EXIT_FAILURE); } else if (job_last()->hash == NULL) { job_last()->hash = optarg; } else { job_push(xstrdup(job_last()->password), optarg); } break; case '?': print_usage(stderr); exit(EXIT_FAILURE); } } jobs_validate(); /* Process all jobs. */ while (jobs != NULL) { struct job *job = job_pop(); if (job->hash != NULL) { /* Verify */ struct rc4hash hash; rc4hash_parse(&hash, job->hash); if (rc4hash_verify(&hash, job->password)) { printf("valid\n"); } else { printf("invalid\n"); exit(EXIT_FAILURE); } } else { /* Hash */ struct rc4hash hash = {gen_salt ? salt_generate() : salt, difficulty}; rc4hash(&hash, job->password); if (binary) { char buffer[RC4HASH_SIZE]; rc4hash_pack(&hash, buffer); fwrite(buffer, RC4HASH_SIZE, 1, stdout); } else { rc4hash_print(&hash, stdout); putchar('\n'); } } free(job->password); free(job); } return EXIT_SUCCESS; }