Пример #1
0
static long
get_num_cpus()
{
        int err = 0;
        char* cpuinfo = NULL;
        unsigned int size = 0;
        unsigned int max = 0;

        err = readfile("/proc/cpuinfo", &cpuinfo, &size, &max);
        if (err || !cpuinfo)
        {
                return err;
        }

        return parse_cpuinfo(cpuinfo, size);
}
Пример #2
0
/*
 * check_cpuinfo -- validates CPU features detection
 */
static void
check_cpuinfo(void)
{
	/* detect supported CPU features */
	FILE *fp;
	if ((fp = fopen("/proc/cpuinfo", "r")) == NULL) {
		ERR("!/proc/cpuinfo");
	} else {
		char line[PROCMAXLEN];	/* for fgets() */

		while (fgets(line, PROCMAXLEN, fp) != NULL) {
			if (parse_cpuinfo(line))
				break;
		}

		fclose(fp);
	}
}
Пример #3
0
int main(int argc, char *argv[]) { // onions are fun, here we go
    signal(SIGTERM, terminate); // always let people kill

    if(argc < 2) // not enough arguments
        usage();

    // set up our initial values
    uint8_t daemon = 0, optimum = 0;
    uint32_t threads = 1, x = 1;
    char *file = 0;
    elim = DEFAULT_E_LIMIT;
    loop = 0;
    found = 0;
    monitor = 0;

#ifdef BSD                                   // my
    int mib[2] = { CTL_HW, HW_NCPU };            // how
    size_t size = sizeof(threads);               // easy
    if(sysctl(mib, 2, &threads, &size, NULL, 0)) // BSD
        error(X_SYSCTL_FAILED);                    // is

#elif defined(LINUX_PORT) // Oh no!  We're on Linux... :(
    // ...even *Windows 95* (gasp!) has a better way of doing this...
    // TODO: move this to linux.c
    char cpuinfo[CPUINFO_BUF_SIZE] = "";
    int fd = open(CPUINFO_PATH, O_RDONLY);

    if(fd < 0)
        error(X_BAD_FILE_DESC);

    threads--; // reset threads to 0
    size_t r = 0;
    ssize_t tmp = 1; // must not initially be 0!
    uint16_t used = 0;

    do {
        if(tmp)
            tmp = read(fd, &cpuinfo[r], CPUINFO_BUF_SIZE - r); // fill the buffer

        if(tmp < 0) // something went wrong
            error(X_ABNORMAL_READ);

        r += tmp; // add how much we read

        if(r < CPUINFO_BUF_SIZE)
            cpuinfo[r] = 0;

        threads += parse_cpuinfo(&cpuinfo[0], (uint16_t)r, &used);
        r -= used; // subtract what we parsed

        memmove(&cpuinfo[0], &cpuinfo[used], r);
    } while(used > 0);

    close(fd); // TODO: add error handling! (is there any point?)

    if(!threads) { // This is needed for Linux/ARM (do not remove!)
        printf("WARNING: No CPUs detected.  Defaulting to 1 thread... "
               "(or manually specify thread count with -t)\n");
        threads++;
    }

#elif defined(GENERIC)
    printf("WARNING: Threads will default to 1 unless specified with -t\n");
#endif

    for(; x < argc - 1; x++) { // options parsing
        if(argv[x][0] != '-') {
            fprintf(stderr, "Error: Options must start with '-'\n");
            usage();
        }
        uint32_t y = 1;
        for(; argv[x][y] != '\0'; y++) {
            uint8_t dbreak = 0;
            switch(argv[x][y]) {
            case 'd': { // daemonize
                daemon = 1;
                break;
            }
            case 'm': { // monitor
                monitor = 1;
                break;
            }
            case 'o': { // prime optimization
                optimum = 1;
                break;
            }
            case 'p': { // pattern help
                pattern();
                break;
            }
            case 'f': { // file <file>
                if((argv[x][y + 1] != '\0') || (x + 1 > argc)) {
                    fprintf(stderr, "Error: -f format is '-f <file>'\n");
                    usage();
                }
                file = argv[x + 1];
                dbreak = 1;
                break;
            }
            case 't': { // threads
                if((argv[x][y + 1] != '\0') || (x + 1 > argc)) {
                    fprintf(stderr, "Error: -t format is '-t threads'\n");
                    usage();
                }
                threads = strtoul(argv[x + 1], NULL, 0);
                dbreak = 1;
                break;
            }
            case 'x': { // maximum execution time
                if((argv[x][y + 1] != '\0') || (x + 1 > argc)) {
                    fprintf(stderr, "Error: -x format is '-x <max exec time in seconds>'\n");
                    usage();
                }
                maxexectime = strtoul(argv[x + 1], NULL, 0);
                dbreak = 1;
                break;
            }

            case 'e': { // e limit
                if((argv[x][y + 1] != '\0') || (x + 1 > argc)) {
                    fprintf(stderr, "Error: -e format is '-e limit'\n");
                    usage();
                }
                elim = strtoull(argv[x + 1], NULL, 0);
                dbreak = 1;
                break;
            }
            default: { // unrecognized
                fprintf(stderr, "Error: Unrecognized option - '%c'\n", argv[x][y]);
                usage();
                break; // redundant... but safe :)
            }
            }
            if(dbreak) {
                x++; // skip the next param
                break;
            }
        }
    }

    // now for our sanity checks
    if(threads < 1)
        error(X_INVALID_THRDS);

    if(monitor && file)
        error(X_EXCLUSIVE_OPT);

    if(!(elim & 1) || (elim < RSA_PK_EXPONENT) || (elim > MAXIMUM_E_LIMIT))
        error(X_INVALID_E_LIM);

    if(daemon && !file)
        error(X_NEED_FILE_OUT);

    // compile regular expression from argument
    char *pattern = argv[argc - 1];

    if(*pattern == '-')
        error(X_REGEX_INVALID);

    regex = malloc(REGEX_COMP_LMAX);

    if(regcomp(regex, pattern, REG_EXTENDED | REG_NOSUB))
        error(X_REGEX_COMPILE);

    if(file) {
        umask(077); // remove permissions to be safe

        // redirect output
        if (
            (freopen(file, "w", stdout) == NULL) ||
            (freopen(file, "w", stderr) == NULL)
        ) error(X_FILE_OPEN_ERR);
    }

    if(daemon && (getppid() != 1)) { // daemonize if we should
        pid_t pid = fork();

        if(pid < 0) // fork failed
            error(X_DAEMON_FAILED);

        if(pid) // exit on the parent process
            exit(0);

        if(setsid() < 0) // get a new SID
            error(X_DAEMON_FAILED);

        if(chdir("/") < 0) // cd to root
            error(X_DAEMON_FAILED);

        // block input
        if (freopen("/dev/null", "r", stdin) == NULL)
            error(X_FILE_OPEN_ERR);

        // ignore certain signals
        signal(SIGCHLD, SIG_IGN);
        signal(SIGTSTP, SIG_IGN);
        signal(SIGTTOU, SIG_IGN);
        signal(SIGTTIN, SIG_IGN);
        signal(SIGHUP,  SIG_IGN);

    } else signal(SIGINT, terminate); // die on CTRL-C

    pthread_t thrd;

    // create our threads for 2+ cores
    for(x = 1; x < threads; x++) {

        if(pthread_create(&thrd, NULL, worker, &optimum))
            error(X_THREAD_CREATE);
    }

    if(monitor) {
        // TODO: when support is added for -mv, put a message here
        if(pthread_create(&thrd, NULL, monitor_proc, NULL))
            error(X_THREAD_CREATE);
    }

    worker(&optimum); // use main thread for brute-forcing too

    if(pthread_self() != lucky_thread) { // be safe and avoid EDEADLK

        pthread_join(lucky_thread, NULL); // wait for the lucky thread to exit
    }

    regfree(regex);
    return 0;
}