コード例 #1
0
ファイル: main.c プロジェクト: harningt/optparse
void try_optparse(char **argv)
{
    print_argv(argv);
    struct optparse options;
    optparse_init(&options, argv);
    int opt;
    while ((opt = optparse(&options, "abc:d::")) != -1) {
        if (opt == '?')
            printf("%s: %s\n", argv[0], options.errmsg);
        printf("%c (%d) = '%s'\n", opt, options.optind, options.optarg);
    }
    printf("optind = %d\n", options.optind);
    char *arg;
    while ((arg = optparse_arg(&options)))
        printf("argument: %s\n", arg);
}
コード例 #2
0
ファイル: optparse.cpp プロジェクト: chaosink/RGB-YUV
static int
long_fallback(struct optparse *options,
              const struct optparse_long *longopts,
              int *longindex)
{
    char optstring[96 * 3 + 1]; /* 96 ASCII printable characters */
    optstring_from_long(longopts, optstring);
    int result = optparse(options, optstring);
    if (longindex != 0) {
        *longindex = -1;
        if (result != -1)
            for (int i = 0; !longopts_end(longopts, i); i++)
                if (longopts[i].shortname == options->optopt)
                    *longindex = i;
    }
    return result;
}
コード例 #3
0
ファイル: turtle.cpp プロジェクト: chaosink/turtle-graphics
void OptParse(char** argv) {
	struct optparse options;
	optparse_init(&options, argv);
	int option;

	while((option = optparse(&options, "n:s: dfrw: h")) != -1) {
		switch(option) {
			case 'n':
				N = atoi(options.optarg);
				break;
			case 's':
				step = atof(options.optarg);
				break;

			case 'd':
				decoration = 0;
				break;
			case 'f':
				fullscreen = 1;
				break;
			case 'r':
				resizable = 0;
				break;	
			case 'w':
				window_width = atoi(options.optarg);
				window_height = atoi(options.optarg + Digit(window_width) + 1);
				window_ratio = window_height * 1.0 / window_width;
				break;

			case 'h':
				printf(
"None\n");
				return;
				break;
		}
	}

	if(fullscreen) {
		window_width = 1920;
		window_height = 1080;
		window_ratio = window_height * 1.0 / window_width;
	}
}
コード例 #4
0
ファイル: main.c プロジェクト: bueti/my_gol
/*
 * Main
 */
int main(int argc, char *argv[]) {
  // Parse command line
  if(!optparse(argc, argv))
    abort();

  /* Nanosleep Setup */
  int milisec = 250; // length of time to sleep, in miliseconds
  struct timespec req = {0};
  req.tv_sec = 0;
  req.tv_nsec = milisec * 1000000L;

  // Initialisieren der Welt und den Zellen
  world_t world;

  /* Allocate Memory */
  allocateMemory(&world);

  /* Welt befüllen */
  if(path) {
    read_world(&world, path);
  } else if (!create_world(&world)) {
      printf("error creating world\n");
      exit(-2);
  } else {
    fillWorld(&world);
  }

  /* Welt ausgeben */
  printWorld(&world);

  /*
   * Nächster Schritt ausführen
   * TODO: Beenden der Schleife wenn sich nichts mehr ändert
   */
  while (true) {
    (automode) ? nanosleep(&req, (struct timespec *)NULL) : bwait();
    nextStep(&world);
    printWorld(&world);
  }
  return 0;
}
コード例 #5
0
ファイル: main.c プロジェクト: nil0x42/duplicut
int             main(int argc, char **argv)
{
    optparse(argc, argv); /* set g_conf options */

    if (isatty(STDIN_FILENO))
        watch_user_input();

    update_status(FCOPY_START);
    init_file(g_conf.infile_name, g_conf.outfile_name);
    config(); /* configure g_conf options */

    init_hmap(g_conf.hmap_size);
    update_status(TAGDUP_START);
    tag_duplicates();
    destroy_hmap();

    update_status(FCLEAN_START);
    remove_duplicates();
    destroy_file();
    return (0);
}
コード例 #6
0
ファイル: clamd.c プロジェクト: bknowles/clamav-devel
int main(int argc, char **argv)
{
        static struct cl_engine *engine = NULL;
	const struct optstruct *opt;
#ifndef	_WIN32
        struct passwd *user = NULL;
	struct sigaction sa;
	struct rlimit rlim;
#endif
	time_t currtime;
	const char *dbdir, *cfgfile;
	char *pua_cats = NULL, *pt;
	int ret, tcpsock = 0, localsock = 0, i, min_port, max_port;
	unsigned int sigs = 0;
	int lsockets[2], nlsockets = 0;
	unsigned int dboptions = 0;
#ifdef C_LINUX
	STATBUF sb;
#endif

    if(check_flevel())
	exit(1);

#ifndef _WIN32
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = SIG_IGN;
    sigaction(SIGHUP, &sa, NULL);
    sigaction(SIGUSR2, &sa, NULL);
#endif

    if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) {
	mprintf("!Can't parse command line options\n");
	return 1;
    }

    if(optget(opts, "help")->enabled) {
    	help();
	optfree(opts);
	return 0;
    }

    if(optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
	/* [email protected]: create a dump if needed */
	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
	    perror("setrlimit");
#endif
	debug_mode = 1;
    }

    /* parse the config file */
    cfgfile = optget(opts, "config-file")->strarg;
    pt = strdup(cfgfile);
    if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) {
	fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt);
	free(pt);
	return 1;
    }
    free(pt);

    if(optget(opts, "version")->enabled) {
	print_version(optget(opts, "DatabaseDirectory")->strarg);
	optfree(opts);
	return 0;
    }

    /* drop privileges */
#ifndef _WIN32
    if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
	if((user = getpwnam(opt->strarg)) == NULL) {
	    fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
	    optfree(opts);
	    return 1;
	}

	if(optget(opts, "AllowSupplementaryGroups")->enabled) {
#ifdef HAVE_INITGROUPS
	    if(initgroups(opt->strarg, user->pw_gid)) {
		fprintf(stderr, "ERROR: initgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#else
	    mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups in %s\n", cfgfile);
	    optfree(opts);
	    return 1;
#endif
	} else {
#ifdef HAVE_SETGROUPS
	    if(setgroups(1, &user->pw_gid)) {
		fprintf(stderr, "ERROR: setgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#endif
	}

	if(setgid(user->pw_gid)) {
	    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
	    optfree(opts);
	    return 1;
	}

	if(setuid(user->pw_uid)) {
	    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
	    optfree(opts);
	    return 1;
	}
    }
#endif

    /* initialize logger */
    logg_lock = !optget(opts, "LogFileUnlock")->enabled;
    logg_time = optget(opts, "LogTime")->enabled;
    logok = optget(opts, "LogClean")->enabled;
    logg_size = optget(opts, "LogFileMaxSize")->numarg;
    logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled;
    if (logg_size)
        logg_rotate = optget(opts, "LogRotate")->enabled;
    mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg;

    do { /* logger initialized */

    if((opt = optget(opts, "LogFile"))->enabled) {
	char timestr[32];
	logg_file = opt->strarg;
	if(!cli_is_abspath(logg_file)) {
	    fprintf(stderr, "ERROR: LogFile requires full path.\n");
	    ret = 1;
	    break;
	}
	time(&currtime);
	if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) {
	    fprintf(stderr, "ERROR: Can't initialize the internal logger\n");
	    ret = 1;
	    break;
	}
    } else
	logg_file = NULL;

    if (optget(opts,"DevLiblog")->enabled)
	cl_set_clcb_msg(msg_callback);
    if((ret = cl_init(CL_INIT_DEFAULT))) {
	logg("!Can't initialize libclamav: %s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if(optget(opts, "Debug")->enabled) /* enable debug messages in libclamav */ {
	cl_debug();
	logg_verbose = 2;
    }

#if defined(USE_SYSLOG) && !defined(C_AIX)
    if(optget(opts, "LogSyslog")->enabled) {
	    int fac = LOG_LOCAL6;

	opt = optget(opts, "LogFacility");
	if((fac = logg_facility(opt->strarg)) == -1) {
	    logg("!LogFacility: %s: No such facility.\n", opt->strarg);
	    ret = 1;
	    break;
	}

	openlog("clamd", LOG_PID, fac);
	logg_syslog = 1;
    }
#endif

#ifdef C_LINUX
    procdev = 0;
    if(CLAMSTAT("/proc", &sb) != -1 && !sb.st_size)
	procdev = sb.st_dev;
#endif

    /* check socket type */

    if(optget(opts, "TCPSocket")->enabled)
	tcpsock = 1;

    if(optget(opts, "LocalSocket")->enabled)
	localsock = 1;

    if(!tcpsock && !localsock) {
	logg("!Please define server type (local and/or TCP).\n");
	ret = 1;
	break;
    }

    logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());

#ifndef _WIN32
    if(user)
	logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid);
#endif

#if defined(RLIMIT_DATA) && defined(C_BSD)
    if (getrlimit(RLIMIT_DATA, &rlim) == 0) {
       /* bb #1941.
        * On 32-bit FreeBSD if you set ulimit -d to >2GB then mmap() will fail
        * too soon (after ~120 MB).
        * Set limit lower than 2G if on 32-bit */
       uint64_t lim = rlim.rlim_cur;
       if (sizeof(void*) == 4 &&
           lim > (1ULL << 31)) {
           rlim.rlim_cur = 1ULL << 31;
           if (setrlimit(RLIMIT_DATA, &rlim) < 0)
               logg("!setrlimit(RLIMIT_DATA) failed: %s\n", strerror(errno));
           else
               logg("Running on 32-bit system, and RLIMIT_DATA > 2GB, lowering to 2GB!\n");
       }
    }
#endif


    if(logg_size)
	logg("#Log file size limited to %u bytes.\n", logg_size);
    else
	logg("#Log file size limit disabled.\n");

    min_port = optget(opts, "StreamMinPort")->numarg;
    max_port = optget(opts, "StreamMaxPort")->numarg;
    if (min_port < 1024 || min_port > max_port || max_port > 65535) {
	logg("!Invalid StreamMinPort/StreamMaxPort: %d, %d\n", min_port, max_port);
	ret = 1;
	break;
    }

    if(!(engine = cl_engine_new())) {
	logg("!Can't initialize antivirus engine\n");
	ret = 1;
	break;
    }

    /* load the database(s) */
    dbdir = optget(opts, "DatabaseDirectory")->strarg;
    logg("#Reading databases from %s\n", dbdir);

    if(optget(opts, "DetectPUA")->enabled) {
	dboptions |= CL_DB_PUA;

	if((opt = optget(opts, "ExcludePUA"))->enabled) {
	    dboptions |= CL_DB_PUA_EXCLUDE;
	    i = 0;
	    logg("#Excluded PUA categories:");
	    while(opt) {
		if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
		    logg("!Can't allocate memory for pua_cats\n");
		    cl_engine_free(engine);
		    ret = 1;
		    break;
		}
		logg("# %s", opt->strarg);
		sprintf(pua_cats + i, ".%s", opt->strarg);
		i += strlen(opt->strarg) + 1;
		pua_cats[i] = 0;
		opt = opt->nextarg;
	    }
	    if (ret)
		break;
	    logg("#\n");
	    pua_cats[i] = '.';
	    pua_cats[i + 1] = 0;
	}

	if((opt = optget(opts, "IncludePUA"))->enabled) {
	    if(pua_cats) {
		logg("!ExcludePUA and IncludePUA cannot be used at the same time\n");
		free(pua_cats);
		ret = 1;
		break;
	    }
	    dboptions |= CL_DB_PUA_INCLUDE;
	    i = 0;
	    logg("#Included PUA categories:");
	    while(opt) {
		if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
		    logg("!Can't allocate memory for pua_cats\n");
		    ret = 1;
		    break;
		}
		logg("# %s", opt->strarg);
		sprintf(pua_cats + i, ".%s", opt->strarg);
		i += strlen(opt->strarg) + 1;
		pua_cats[i] = 0;
		opt = opt->nextarg;
	    }
	    if (ret)
		break;
	    logg("#\n");
	    pua_cats[i] = '.';
	    pua_cats[i + 1] = 0;
	}

	if(pua_cats) {
	    if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
		logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret));
		free(pua_cats);
		ret = 1;
		break;
	    }
	    free(pua_cats);
	}
    } else {
	logg("#Not loading PUA signatures.\n");
    }

    if(optget(opts, "OfficialDatabaseOnly")->enabled) {
	dboptions |= CL_DB_OFFICIAL_ONLY;
	logg("#Only loading official signatures.\n");
    }

    /* set the temporary dir */
    if((opt = optget(opts, "TemporaryDirectory"))->enabled) {
	if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) {
	    logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret));
	    ret = 1;
	    break;
	}
    }

    cl_engine_set_clcb_hash(engine, hash_callback);
    detstats_clear();

    if(optget(opts, "LeaveTemporaryFiles")->enabled)
	cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1);

    if(optget(opts, "PhishingSignatures")->enabled)
	dboptions |= CL_DB_PHISHING;
    else
	logg("#Not loading phishing signatures.\n");

    if(optget(opts,"Bytecode")->enabled) {
	dboptions |= CL_DB_BYTECODE;
	if((opt = optget(opts,"BytecodeSecurity"))->enabled) {
	    enum bytecode_security s;
	    if (!strcmp(opt->strarg, "TrustSigned")) {
		s = CL_BYTECODE_TRUST_SIGNED;
		logg("#Bytecode: Security mode set to \"TrustSigned\".\n");
	    } else if (!strcmp(opt->strarg, "Paranoid")) {
		s = CL_BYTECODE_TRUST_NOTHING;
		logg("#Bytecode: Security mode set to \"Paranoid\".\n");
	    } else {
		logg("!Unable to parse bytecode security setting:%s\n",
		    opt->strarg);
		ret = 1;
		break;
	    }
	    if ((ret = cl_engine_set_num(engine, CL_ENGINE_BYTECODE_SECURITY, s))) {
		logg("^Invalid bytecode security setting %s: %s\n", opt->strarg, cl_strerror(ret));
		ret = 1;
		break;
	    }
	}
	if((opt = optget(opts,"BytecodeUnsigned"))->enabled) {
	    dboptions |= CL_DB_BYTECODE_UNSIGNED;
	    logg("#Bytecode: Enabled support for unsigned bytecode.\n");
	}
	if((opt = optget(opts,"BytecodeMode"))->enabled) {
	    enum bytecode_mode mode;
	    if (!strcmp(opt->strarg, "ForceJIT"))
		mode = CL_BYTECODE_MODE_JIT;
	    else if(!strcmp(opt->strarg, "ForceInterpreter"))
		mode = CL_BYTECODE_MODE_INTERPRETER;
	    else if(!strcmp(opt->strarg, "Test"))
		mode = CL_BYTECODE_MODE_TEST;
	    else
		mode = CL_BYTECODE_MODE_AUTO;
	    cl_engine_set_num(engine, CL_ENGINE_BYTECODE_MODE, mode);
	}
	if((opt = optget(opts,"BytecodeTimeout"))->enabled) {
	    cl_engine_set_num(engine, CL_ENGINE_BYTECODE_TIMEOUT, opt->numarg);
	}
    } else
	logg("#Bytecode support disabled.\n");

    if(optget(opts,"PhishingScanURLs")->enabled)
	dboptions |= CL_DB_PHISHING_URLS;
    else
	logg("#Disabling URL based phishing detection.\n");

    if(optget(opts,"DevACOnly")->enabled) {
	logg("#Only using the A-C matcher.\n");
	cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1);
    }

    if((opt = optget(opts, "DevACDepth"))->enabled) {
        cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, opt->numarg);
	logg("#Max A-C depth set to %u\n", (unsigned int) opt->numarg);
    }

    if((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
	logg("!%s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if (optget(opts, "DisableCertCheck")->enabled)
        engine->dconf->pe |= PE_CONF_DISABLECERT;

    logg("#Loaded %u signatures.\n", sigs);
    if((ret = cl_engine_compile(engine)) != 0) {
	logg("!Database initialization error: %s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if(tcpsock) {
	if ((lsockets[nlsockets] = tcpserver(opts)) == -1) {
	    ret = 1;
	    break;
	}
	nlsockets++;
    }
#ifndef _WIN32
    if(localsock) {
	mode_t sock_mode, umsk = umask(0777); /* socket is created with 000 to avoid races */
	if ((lsockets[nlsockets] = localserver(opts)) == -1) {
	    ret = 1;
	    umask(umsk);
	    break;
	}
	umask(umsk); /* restore umask */
	if(optget(opts, "LocalSocketGroup")->enabled) {
	    char *gname = optget(opts, "LocalSocketGroup")->strarg, *end;
	    gid_t sock_gid = strtol(gname, &end, 10);
	    if(*end) {
		struct group *pgrp = getgrnam(gname);
		if(!pgrp) {
		    logg("!Unknown group %s\n", gname);
		    ret = 1;
		    break;
		}
		sock_gid = pgrp->gr_gid;
	    }
	    if(chown(optget(opts, "LocalSocket")->strarg, -1, sock_gid)) {
		logg("!Failed to change socket ownership to group %s\n", gname);
		ret = 1;
		break;
	    }
	}
	if(optget(opts, "LocalSocketMode")->enabled) {
	    char *end;
	    sock_mode = strtol(optget(opts, "LocalSocketMode")->strarg, &end, 8);
	    if(*end) {
		logg("!Invalid LocalSocketMode %s\n", optget(opts, "LocalSocketMode")->strarg);
		ret = 1;
		break;
	    }
	} else
	    sock_mode = 0777 /* & ~umsk*/; /* conservative default: umask was 0 in clamd < 0.96 */

	if(chmod(optget(opts, "LocalSocket")->strarg, sock_mode & 0666)) {
	    logg("!Cannot set socket permission to %s\n", optget(opts, "LocalSocketMode")->strarg);
	    ret = 1;
	    break;
	}

	nlsockets++;
    }

    /* fork into background */
    if(!optget(opts, "Foreground")->enabled) {
#ifdef C_BSD	    
	/* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */
	for(ret=0;ret<nlsockets;ret++) {
		if (fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) | O_NONBLOCK) == -1) {
            logg("!fcntl for lsockets[] failed\n");
            close(lsockets[ret]);
            ret = 1;
            break;
        }
	}
#endif
	gengine = engine;
	atexit(free_engine);
	if(daemonize() == -1) {
	    logg("!daemonize() failed: %s\n", strerror(errno));
	    ret = 1;
	    break;
	}
	gengine = NULL;
#ifdef C_BSD
	for(ret=0;ret<nlsockets;ret++) {
		if (fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) & ~O_NONBLOCK) == -1) {
            logg("!fcntl for lsockets[] failed\n");
            close(lsockets[ret]);
            ret = 1;
            break;
        }
	}
#endif
	if(!debug_mode)
	    if(chdir("/") == -1)
		logg("^Can't change current working directory to root\n");

    } else
        foreground = 1;
#endif

    ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts);

    } while (0);

    logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : "");

    for (i = 0; i < nlsockets; i++) {
	closesocket(lsockets[i]);
    }

#ifndef _WIN32
    if(nlsockets && localsock) {
	opt = optget(opts, "LocalSocket");
	if(unlink(opt->strarg) == -1)
	    logg("!Can't unlink the socket file %s\n", opt->strarg);
	else
	    logg("Socket file removed.\n");
    }
#endif

    logg_close();
    optfree(opts);

    return ret;
}
コード例 #7
0
ファイル: main.c プロジェクト: samus250/random-c
int main(int argc, char *argv[])
{
    CURL *curl;
    char curl_error[CURL_ERROR_SIZE];
    char update_path[PATH_MAX]; // path for update download
    char download_path[PATH_MAX]; // path for video download
    
    // first of all
    welcome();
    
    if(!optparse(argc, argv))
        return 0;
    
    // immediately check for paths and copy them
    if(!(pathcpy(update_path, options.update_downdir))) {
        fprintf(stderr, 
            "The path to download the update is not accessible.\n"
            "You entered: %s.\n", options.update_downdir
        );
        return 0;
    }
    
    if(!(pathcpy(download_path, options.downdir))) {
        fprintf(stderr,
            "The path to download the videos is not accessible.\n"
            "You entered: %s.\n", options.downdir
        );
        return 0;
    }
    
    // first you must check if it was specified
    if(options.llist) {
        if(!(check_existance(options.llist))) {
            fprintf(stderr,
                "The link list file given is not accessible.\n"
                "You entered: %s.\n", options.llist
            );
            return 0;
        }
    }
    
    //! after all the path parsing and shit, we begin
    if(!(curl = curl_easy_init())) {
        fprintf(stderr, "Something went horribly wrong!\n");
        fprintf(stderr, "Aborting...\n");
        return 0;
    }
    
    // the first thing after initializing, would be to check for updates
    if(options.update) {
        char update_ver[UPDATE_VER_SIZE];
        int new_update_res;
        
        fprintf(stderr, "Checking for updates...\n");
        new_update_res = new_update(curl, YD_UPDATECHECKLINK, update_ver, UPDATE_VER_SIZE - 1, curl_error);
        if(new_update_res == UPDATE_YES) {
            int tries = 0;
            bool done = true;
            
            fprintf(stderr, "\nA new update was found!\n"
                            "Current Version: "PROGRAM_VERSION"\n"
                            "New Version:     %s\n\n", update_ver
            );
            fprintf(stderr, "Do you want to download the update? [Y/n]: ");
            
            do {
                char ans;
                char update_basename[UPDATE_BASENAME_SIZE];
                char *up_url = NULL;
                FILE *fp = NULL;
                
                scanf("%1s", &ans);
                switch(toupper(ans)) {
                    case 'Y':
                        // prepare the download path, up_url was malloced by update_url
                        if(!(up_url = update_url(curl, YD_UPDATELINK, update_basename, UPDATE_BASENAME_SIZE - 1, curl_error))) { 
                            fprintf(stderr, "Error: %s\n", curl_error);
                            fprintf(stderr, "Update not downloaded successfully.\n");
                            break;
                        }
                        
                        // just cat the base to the path (being careful not to overlap)
                        strncat(update_path, update_basename, PATH_MAX - strlen(update_path) - 1);
                        
                        if(!(fp = fopen(update_path, "wb"))) {
                            fprintf(stderr, "Error Opening file for writing.\n");
                            fprintf(stderr, "Update will not be downloaded.\n");
                        } else {
                            fprintf(stderr, "Downloading update...\n");
                            int perform_update_res = perform_update(curl, up_url, fp, curl_error);
                            if(perform_update_res == UPDATE_OK) {
                                fprintf(stderr, "\n\nUpdate successfully downloaded!\n");
                                fclose(fp);
                            } else {
                                fprintf(stderr, "\n\nError: %s\n", curl_error);
                                fprintf(stderr, "Update not downloaded successfully.\n");
                            }
                            free(up_url);
                        }
                        
                        done = true;
                        break;
                    
                    case 'N':
                        fprintf(stderr, "Not downloading update...\n");
                        done = true;
                        break;
                    
                    default:
                        done = false;
                        if(++tries > 3) // number of tries for a stupid user
                            done = true;
                        else {
                            fprintf(stderr, "That is not a valid option. Enter only [Y/n]: ");
                            tries++;
                        }
                        break;
                }
            } while(!done);
            
        } else if(new_update_res == UPDATE_ERR) {
            fprintf(stderr, "%s\n", curl_error);
        } else if(new_update_res == UPDATE_NO) {
            fprintf(stderr, "No update found.\n");
        }
        fprintf(stderr, "\n");
    }
    
    // ok, that was all the update process
    // all those stupid vars have finally been destroyed
    // next, we start getting links one by one...
    fprintf(stderr, "Ready for downloading. Waiting for input...\n");
    
    char input_buffer[URL_PATH_SIZE]; // buffer for each line of url
    char line_buffer[URL_PATH_SIZE];
    int nread;
    FILE *fp = NULL;
    
    // even though we already checked it, the file might have changed
    // so check it again!
    if(options.llist) {
        if(!(fp = fopen(options.llist, "r"))) {
            fprintf(stderr, "Error opening link list for reading.\n");
            return 0;
        }
    }
    
    // before reading, we might want to flush stdin
    fflush(stdin);
    int i, j = 0;
    do {
        //int i, j = 0; this causes a bug... j can be re-initialized ONLY when the string is capped.
        
        if(options.llist)
            nread = fread(input_buffer, sizeof(char), URL_PATH_SIZE, fp);
        else
            nread = fread(input_buffer, sizeof(char), URL_PATH_SIZE, stdin);
        
        for(i = 0; i < nread; i++) {
            for(; input_buffer[i] != '\n' && i < nread; i++, j++)
                line_buffer[j] = input_buffer[i];
            
            // if we haven't finished reading the line, but the buffer filled up...
            if(i == nread && nread == URL_PATH_SIZE) continue;
            
            // we cap the line, and reinit j
            line_buffer[j] = '\0';
            j = 0;
            
            // until here, we have successfully gotten all the information
            // into line buffer, now entering actual download phase
            {
                FILE *out_file = NULL;
                char video_link[URL_PATH_SIZE];
                char title[URL_PATH_SIZE];
                
                // added in 0.2.0a, found a bug in which the download_path would only be catted
                // oh and make errors continue!
                char out_file_path[PATH_MAX];
                memset(out_file_path, '\0', PATH_MAX);
                strncpy(out_file_path, download_path, PATH_MAX - 1);
                
                fprintf(stderr, "Looking for title...\n");
                if(!(video_title(curl, TITLE_LOOKUP_URL, line_buffer, title, curl_error))) {
                    fprintf(stderr, "\n\nError: %s.\n", curl_error);
                    fprintf(stderr, "Skipping this video..\n\n");
                    continue;
                }
                
                fprintf(stderr, "Title is \"%s\".\n", title);
                fprintf(stderr, "Looking for a direct link to the video...\n");
                
                if(!(generate_link(curl, LINK_LOOKUP_URL, line_buffer, video_link, curl_error))) {
                    fprintf(stderr, "\n\nError: %s.\n", curl_error);
                    fprintf(stderr, "Skipping this video...\n\n");
                    continue;
                }
                
                strncat(out_file_path, title, MAX_PATH - strlen(out_file_path) - 1);
                if(!(out_file = fopen(out_file_path, "wb"))) {
                    fprintf(stderr, "Error opening video file for writing!\n");
                    fprintf(stderr, "Skipping this video...\n\n");
                    continue;
                }
                
                fprintf(stderr, "Downloading...\n");
                if(!(download_vid(curl, video_link, out_file, curl_error)))
                    fprintf(stderr, "\n\nError: %s.\n", curl_error);
                else
                    fprintf(stderr, "\nVideo Sucessfully Downloaded!!!\n\n");
                
                fclose(out_file);
            }
        }
    } while(nread == URL_PATH_SIZE);
    
    return 0;
}
コード例 #8
0
ファイル: notify.c プロジェクト: Yuyue/clamav-devel
int
clamd_connect (const char *cfgfile, const char *option)
{
#ifndef	_WIN32
    struct sockaddr_un server;
#endif
#ifdef HAVE_GETADDRINFO
    struct addrinfo hints, *res;
    char port[6];
    const char *addr;
    int ret;
#else
    struct sockaddr_in server2;
    struct hostent *he;
#endif
    struct optstruct *opts;
    const struct optstruct *opt;
    int sockd;
    const char *socktype;


    if ((opts = optparse (cfgfile, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL)
    {
        logg ("!%s: Can't find or parse configuration file %s\n", option,
              cfgfile);
        return -11;
    }

#ifndef	_WIN32
    if ((opt = optget (opts, "LocalSocket"))->enabled)
    {
        socktype = "UNIX";
        server.sun_family = AF_UNIX;
        strncpy (server.sun_path, opt->strarg, sizeof (server.sun_path));
        server.sun_path[sizeof (server.sun_path) - 1] = '\0';

        if ((sockd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
        {
            logg ("^Clamd was NOT notified: Can't create socket endpoint for %s\n", opt->strarg);
            perror ("socket()");
            optfree (opts);
            return -1;
        }

        if (connect
            (sockd, (struct sockaddr *) &server,
             sizeof (struct sockaddr_un)) < 0)
        {
            closesocket (sockd);
            logg ("^Clamd was NOT notified: Can't connect to clamd through %s\n", opt->strarg);
            perror ("connect()");
            optfree (opts);
            return -11;
        }

    }
    else
#endif
    if ((opt = optget (opts, "TCPSocket"))->enabled)
    {
        socktype = "TCP";

#ifdef HAVE_GETADDRINFO
        memset (&hints, 0, sizeof (hints));
/*
#ifdef SUPPORT_IPv6
	hints.ai_family = AF_UNSPEC;
#else
*/
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        snprintf (port, sizeof (port), "%u", (unsigned int) opt->numarg);
        port[5] = 0;

        if ((opt = optget (opts, "TCPAddr"))->enabled)
            addr = opt->strarg;
        else
            addr = NULL;

        ret = getaddrinfo (addr, port, &hints, &res);

        if (ret)
        {
            logg ("!%s: Can't resolve hostname %s (%s)\n", option,
                  addr ? addr : "",
                  (ret ==
                   EAI_SYSTEM) ? strerror (errno) : gai_strerror (ret));
            optfree (opts);
            return -1;
        }

        if ((sockd = socket (res->ai_family, SOCK_STREAM, 0)) < 0)
        {
            perror ("socket()");
            logg ("!%s: Can't create TCP socket\n", option);
            optfree (opts);
            freeaddrinfo (res);
            return -1;
        }

        if (connect (sockd, res->ai_addr, res->ai_addrlen) == -1)
        {
            perror ("connect()");
            closesocket (sockd);
            logg ("!%s: Can't connect to clamd on %s:%s\n", option,
                  addr ? addr : "localhost", port);
            optfree (opts);
            freeaddrinfo (res);
            return -1;
        }
        freeaddrinfo (res);

#else /* IPv4 */

        if ((sockd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
        {
            logg ("!%s: Can't create TCP socket\n", option);
            perror ("socket()");
            optfree (opts);
            return -1;
        }

        server2.sin_family = AF_INET;
        server2.sin_port = htons (opt->numarg);

        if ((opt = optget (opts, "TCPAddr"))->enabled)
        {
            if ((he = gethostbyname (opt->strarg)) == 0)
            {
                perror ("gethostbyname()");
                logg ("^Clamd was NOT notified: Can't resolve hostname '%s'\n", opt->strarg);
                optfree (opts);
                closesocket (sockd);
                return -1;
            }
            server2.sin_addr = *(struct in_addr *) he->h_addr_list[0];
        }
        else
            server2.sin_addr.s_addr = inet_addr ("127.0.0.1");


        if (connect
            (sockd, (struct sockaddr *) &server2,
             sizeof (struct sockaddr_in)) < 0)
        {
            closesocket (sockd);
            logg ("^Clamd was NOT notified: Can't connect to clamd on %s:%d\n", inet_ntoa (server2.sin_addr), ntohs (server2.sin_port));
            perror ("connect()");
            optfree (opts);
            return -1;
        }

#endif

    }
    else
    {
        logg ("!%s: No communication socket specified in %s\n", option,
              cfgfile);
        optfree (opts);
        return 1;
    }

    optfree (opts);
    return sockd;
}
コード例 #9
0
ファイル: clamd.c プロジェクト: gittestusername/uClinux
int main(int argc, char **argv)
{
	const struct optstruct *opt;
#ifndef	C_WINDOWS
        struct passwd *user = NULL;
#endif
	time_t currtime;
	const char *dbdir, *cfgfile;
	char *pua_cats = NULL, *pt;
	int ret, tcpsock = 0, localsock = 0, i, min_port, max_port;
	unsigned int sigs = 0;
	int lsockets[2], nlsockets = 0;
	unsigned int dboptions = 0;
#ifdef C_LINUX
	struct stat sb;
#endif

#ifdef C_WINDOWS
    if(!pthread_win32_process_attach_np()) {
	mprintf("!Can't start the win32 pthreads layer\n");
        return 1;
    }
#endif

    if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMD, 0, NULL)) == NULL) {
	mprintf("!Can't parse command line options\n");
	return 1;
    }

    if(optget(opts, "help")->enabled) {
    	help();
	optfree(opts);
	return 0;
    }

    if(optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
	    /* [email protected]: create a dump if needed */
	    struct rlimit rlim;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
	    perror("setrlimit");
#endif
	debug_mode = 1;
    }

    /* parse the config file */
    cfgfile = optget(opts, "config-file")->strarg;
    pt = strdup(cfgfile);
    if((opts = optparse(cfgfile, 0, NULL, 1, OPT_CLAMD, 0, opts)) == NULL) {
	fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", pt);
	free(pt);
	return 1;
    }
    free(pt);

    if(optget(opts, "version")->enabled) {
	print_version(optget(opts, "DatabaseDirectory")->strarg);
	optfree(opts);
	return 0;
    }

    umask(0);

    /* drop privileges */
#if (!defined(C_OS2)) && (!defined(C_WINDOWS))
    if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
	if((user = getpwnam(opt->strarg)) == NULL) {
	    fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
	    optfree(opts);
	    return 1;
	}

	if(optget(opts, "AllowSupplementaryGroups")->enabled) {
#ifdef HAVE_INITGROUPS
	    if(initgroups(opt->strarg, user->pw_gid)) {
		fprintf(stderr, "ERROR: initgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#else
	    mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups in %s\n", cfgfile);
	    optfree(opts);
	    return 1;
#endif
	} else {
#ifdef HAVE_SETGROUPS
	    if(setgroups(1, &user->pw_gid)) {
		fprintf(stderr, "ERROR: setgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#endif
	}

	if(setgid(user->pw_gid)) {
	    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
	    optfree(opts);
	    return 1;
	}

	if(setuid(user->pw_uid)) {
	    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
	    optfree(opts);
	    return 1;
	}
    }
#endif

    /* initialize logger */
    logg_lock = !optget(opts, "LogFileUnlock")->enabled;
    logg_time = optget(opts, "LogTime")->enabled;
    logok = optget(opts, "LogClean")->enabled;
    logg_size = optget(opts, "LogFileMaxSize")->numarg;
    logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled;
    mprintf_send_timeout = optget(opts, "SendBufTimeout")->numarg;

    do { /* logger initialized */

    if((opt = optget(opts, "LogFile"))->enabled) {
	char timestr[32];
	logg_file = opt->strarg;
	if(strlen(logg_file) < 2 || (logg_file[0] != '/' && logg_file[0] != '\\' && logg_file[1] != ':')) {
	    fprintf(stderr, "ERROR: LogFile requires full path.\n");
	    ret = 1;
	    break;
	}
	time(&currtime);
	if(logg("#+++ Started at %s", cli_ctime(&currtime, timestr, sizeof(timestr)))) {
	    fprintf(stderr, "ERROR: Can't initialize the internal logger\n");
	    ret = 1;
	    break;
	}
    } else
	logg_file = NULL;

    if((ret = cl_init(CL_INIT_DEFAULT))) {
	logg("!Can't initialize libclamav: %s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if(optget(opts, "Debug")->enabled) /* enable debug messages in libclamav */ {
	cl_debug();
	logg_verbose = 2;
    }

#if defined(USE_SYSLOG) && !defined(C_AIX)
    if(optget(opts, "LogSyslog")->enabled) {
	    int fac = LOG_LOCAL6;

	opt = optget(opts, "LogFacility");
	if((fac = logg_facility(opt->strarg)) == -1) {
	    logg("!LogFacility: %s: No such facility.\n", opt->strarg);
	    ret = 1;
	    break;
	}

	openlog("clamd", LOG_PID, fac);
	logg_syslog = 1;
    }
#endif

#ifdef C_LINUX
    procdev = 0;
    if(stat("/proc", &sb) != -1 && !sb.st_size)
	procdev = sb.st_dev;
#endif

    /* check socket type */

    if(optget(opts, "TCPSocket")->enabled)
	tcpsock = 1;

    if(optget(opts, "LocalSocket")->enabled)
	localsock = 1;

    if(!tcpsock && !localsock) {
	logg("!Please define server type (local and/or TCP).\n");
	ret = 1;
	break;
    }

    logg("#clamd daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());

#ifndef C_WINDOWS
    if(user)
	logg("#Running as user %s (UID %u, GID %u)\n", user->pw_name, user->pw_uid, user->pw_gid);
#endif

    if(logg_size)
	logg("#Log file size limited to %d bytes.\n", logg_size);
    else
	logg("#Log file size limit disabled.\n");

    min_port = optget(opts, "StreamMinPort")->numarg;
    max_port = optget(opts, "StreamMaxPort")->numarg;
    if (min_port < 1024 || min_port > max_port || max_port > 65535) {
	logg("!Invalid StreamMinPort/StreamMaxPort: %d, %d\n", min_port, max_port);
	ret = 1;
	break;
    }

    if(!(engine = cl_engine_new())) {
	logg("!Can't initialize antivirus engine\n");
	ret = 1;
	break;
    }

    /* load the database(s) */
    dbdir = optget(opts, "DatabaseDirectory")->strarg;
    logg("#Reading databases from %s\n", dbdir);

    if(optget(opts, "DetectPUA")->enabled) {
	dboptions |= CL_DB_PUA;

	if((opt = optget(opts, "ExcludePUA"))->enabled) {
	    dboptions |= CL_DB_PUA_EXCLUDE;
	    i = 0;
	    logg("#Excluded PUA categories:");
	    while(opt) {
		if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
		    logg("!Can't allocate memory for pua_cats\n");
		    cl_engine_free(engine);
		    ret = 1;
		    break;
		}
		logg("# %s", opt->strarg);
		sprintf(pua_cats + i, ".%s", opt->strarg);
		i += strlen(opt->strarg) + 1;
		pua_cats[i] = 0;
		opt = opt->nextarg;
	    }
	    if (ret)
		break;
	    logg("#\n");
	    pua_cats[i] = '.';
	    pua_cats[i + 1] = 0;
	}

	if((opt = optget(opts, "IncludePUA"))->enabled) {
	    if(pua_cats) {
		logg("!ExcludePUA and IncludePUA cannot be used at the same time\n");
		free(pua_cats);
		ret = 1;
		break;
	    }
	    dboptions |= CL_DB_PUA_INCLUDE;
	    i = 0;
	    logg("#Included PUA categories:");
	    while(opt) {
		if(!(pua_cats = realloc(pua_cats, i + strlen(opt->strarg) + 3))) {
		    logg("!Can't allocate memory for pua_cats\n");
		    ret = 1;
		    break;
		}
		logg("# %s", opt->strarg);
		sprintf(pua_cats + i, ".%s", opt->strarg);
		i += strlen(opt->strarg) + 1;
		pua_cats[i] = 0;
		opt = opt->nextarg;
	    }
	    if (ret)
		break;
	    logg("#\n");
	    pua_cats[i] = '.';
	    pua_cats[i + 1] = 0;
	}

	if(pua_cats) {
	    if((ret = cl_engine_set_str(engine, CL_ENGINE_PUA_CATEGORIES, pua_cats))) {
		logg("!cli_engine_set_str(CL_ENGINE_PUA_CATEGORIES) failed: %s\n", cl_strerror(ret));
		free(pua_cats);
		ret = 1;
		break;
	    }
	    free(pua_cats);
	}
    } else {
	logg("#Not loading PUA signatures.\n");
    }

    /* set the temporary dir */
    if((opt = optget(opts, "TemporaryDirectory"))->enabled) {
	if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, opt->strarg))) {
	    logg("!cli_engine_set_str(CL_ENGINE_TMPDIR) failed: %s\n", cl_strerror(ret));
	    ret = 1;
	    break;
	}
    }

    if(optget(opts, "LeaveTemporaryFiles")->enabled)
	cl_engine_set_num(engine, CL_ENGINE_KEEPTMP, 1);

    if(optget(opts, "PhishingSignatures")->enabled)
	dboptions |= CL_DB_PHISHING;
    else
	logg("#Not loading phishing signatures.\n");

    if(optget(opts,"PhishingScanURLs")->enabled)
	dboptions |= CL_DB_PHISHING_URLS;
    else
	logg("#Disabling URL based phishing detection.\n");

    if(optget(opts,"DevACOnly")->enabled) {
	logg("#Only using the A-C matcher.\n");
	cl_engine_set_num(engine, CL_ENGINE_AC_ONLY, 1);
    }

    if((opt = optget(opts, "DevACDepth"))->enabled) {
        cl_engine_set_num(engine, CL_ENGINE_AC_MAXDEPTH, opt->numarg);
	logg("#Max A-C depth set to %u\n", (unsigned int) opt->numarg);
    }

    if((ret = cl_load(dbdir, engine, &sigs, dboptions))) {
	logg("!%s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    logg("#Loaded %u signatures.\n", sigs);
    if((ret = cl_engine_compile(engine)) != 0) {
	logg("!Database initialization error: %s\n", cl_strerror(ret));
	ret = 1;
	break;
    }

    if(tcpsock) {
#ifdef C_WINDOWS
	    WSADATA wsaData;

	if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
	    logg("!Error at WSAStartup(): %d\n", WSAGetLastError());
	    ret = 1;
	    break;
	}
#endif
	if ((lsockets[nlsockets] = tcpserver(opts)) == -1) {
	    ret = 1;
	    break;
	}
	nlsockets++;
    }

    if(localsock) {
	if ((lsockets[nlsockets] = localserver(opts)) == -1) {
	    ret = 1;
	    break;
	}
	nlsockets++;
    }

    /* fork into background */
    if(!optget(opts, "Foreground")->enabled) {
#ifdef C_BSD	    
	/* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */
	for(ret=0;ret<nlsockets;ret++) {
		fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) | O_NONBLOCK);
	}
#endif
	if(daemonize() == -1) {
	    logg("!daemonize() failed\n");
	    ret = 1;
	    break;
	}
#ifdef C_BSD
	for(ret=0;ret<nlsockets;ret++) {
		fcntl(lsockets[ret], F_SETFL, fcntl(lsockets[ret], F_GETFL) & ~O_NONBLOCK);
	}
#endif
	if(!debug_mode)
	    if(chdir("/") == -1)
		logg("^Can't change current working directory to root\n");

    } else
        foreground = 1;

    ret = recvloop_th(lsockets, nlsockets, engine, dboptions, opts);

    } while (0);

    logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : "");

    for (i = 0; i < nlsockets; i++) {
	closesocket(lsockets[i]);
    }

#ifndef C_OS2
    if(nlsockets && localsock) {
	opt = optget(opts, "LocalSocket");
	if(unlink(opt->strarg) == -1)
	    logg("!Can't unlink the socket file %s\n", opt->strarg);
	else
	    logg("Socket file removed.\n");
    }
#endif

#ifdef C_WINDOWS
    if(tcpsock)
	WSACleanup();

    if(!pthread_win32_process_detach_np()) {
	logg("!Can't stop the win32 pthreads layer\n");
	logg_close();
	optfree(opts);
	return 1;
    }
#endif

    logg_close();
    optfree(opts);

    return ret;
}
コード例 #10
0
ファイル: clamav-milter.c プロジェクト: OPSF/uClinux
int main(int argc, char **argv) {
    char *my_socket, *pt;
    const struct optstruct *opt;
    struct optstruct *opts;
    time_t currtime;
    int ret;

    memset(&descr, 0, sizeof(struct smfiDesc));
    descr.xxfi_name = "ClamAV";			/* filter name */
    descr.xxfi_version = SMFI_VERSION;		/* milter version */
    descr.xxfi_flags = SMFIF_QUARANTINE;	/* flags */
    descr.xxfi_connect = clamfi_connect;	/* connection info filter */
    descr.xxfi_envfrom = clamfi_envfrom;	/* envelope sender filter */
    descr.xxfi_envrcpt = clamfi_envrcpt;	/* envelope recipient filter */
    descr.xxfi_header = clamfi_header;		/* header filter */
    descr.xxfi_body = clamfi_body;		/* body block */
    descr.xxfi_eom = clamfi_eom;		/* end of message */
    descr.xxfi_abort = clamfi_abort;		/* message aborted */

    opts = optparse(NULL, argc, argv, 1, OPT_MILTER, 0, NULL);
    if (!opts) {
	mprintf("!Can't parse command line options\n");
	return 1;
    }

    if(optget(opts, "help")->enabled) {
	printf("Usage: %s [-c <config-file>]\n\n", argv[0]);
	printf("    --help                   -h       Show this help\n");
	printf("    --version                -V       Show version and exit\n");
	printf("    --config-file <file>     -c       Read configuration from file\n\n");
	optfree(opts);
	return 0;
    }

    if(opts->filename) {
	int x;
	for(x = 0; opts->filename[x]; x++)
	    mprintf("^Ignoring option %s\n", opts->filename[x]);
    }

    if(optget(opts, "version")->enabled) {
	printf("clamav-milter %s\n", get_version());
	optfree(opts);
	return 0;
    }

    pt = strdup(optget(opts, "config-file")->strarg);
    if((opts = optparse(pt, 0, NULL, 1, OPT_MILTER, 0, opts)) == NULL) {
	printf("%s: cannot parse config file %s\n", argv[0], pt);
	free(pt);
	return 1;
    }
    free(pt);

    if((opt = optget(opts, "Chroot"))->enabled) {
	if(chdir(opt->strarg) != 0) {
	    logg("!Cannot change directory to %s\n", opt->strarg);
	    return 1;
	}
	if(chroot(opt->strarg) != 0) {
	    logg("!chroot to %s failed. Are you root?\n", opt->strarg);
	    return 1;
	}
    }

    if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
        struct passwd *user = NULL;
	if((user = getpwnam(opt->strarg)) == NULL) {
	    fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
	    optfree(opts);
	    return 1;
	}

	if(optget(opts, "AllowSupplementaryGroups")->enabled) {
#ifdef HAVE_INITGROUPS
	    if(initgroups(opt->strarg, user->pw_gid)) {
		fprintf(stderr, "ERROR: initgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#else
	    mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups\n");
	    optfree(opts);
	    return 1;
#endif
	} else {
#ifdef HAVE_SETGROUPS
	    if(setgroups(1, &user->pw_gid)) {
		fprintf(stderr, "ERROR: setgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#endif
	}

	if(setgid(user->pw_gid)) {
	    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
	    optfree(opts);
	    return 1;
	}

	if(setuid(user->pw_uid)) {
	    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
	    optfree(opts);
	    return 1;
	}
    }

    logg_lock = !optget(opts, "LogFileUnlock")->enabled;
    logg_time = optget(opts, "LogTime")->enabled;
    logg_size = optget(opts, "LogFileMaxSize")->numarg;
    logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled;

    if((opt = optget(opts, "LogFile"))->enabled) {
	logg_file = opt->strarg;
	if(strlen(logg_file) < 2 || logg_file[0] != '/') {
	    fprintf(stderr, "ERROR: LogFile requires full path.\n");
	    logg_close();
	    optfree(opts);
	    return 1;
	}
    } else
	logg_file = NULL;

#if defined(USE_SYSLOG) && !defined(C_AIX)
    if(optget(opts, "LogSyslog")->enabled) {
	int fac;

	opt = optget(opts, "LogFacility");
	if((fac = logg_facility(opt->strarg)) == -1) {
	    logg("!LogFacility: %s: No such facility.\n", opt->strarg);
	    logg_close();
	    optfree(opts);
	    return 1;
	}

	openlog("clamav-milter", LOG_PID, fac);
	logg_syslog = 1;
    }
#endif

    time(&currtime);
    if(logg("#+++ Started at %s", ctime(&currtime))) {
	fprintf(stderr, "ERROR: Can't initialize the internal logger\n");
	logg_close();
	optfree(opts);
	return 1;
    }
    if((opt = optget(opts, "TemporaryDirectory"))->enabled)
	tempdir = opt->strarg;

    if(localnets_init(opts) || init_actions(opts)) {
	logg_close();
	optfree(opts);
	return 1;
    }

    if((opt = optget(opts, "Whitelist"))->enabled && whitelist_init(opt->strarg)) {
	localnets_free();
	logg_close();
	optfree(opts);
	return 1;
    }

    if((opt = optget(opts, "SkipAuthenticated"))->enabled && smtpauth_init(opt->strarg)) {
	localnets_free();
	whitelist_free();
	logg_close();
	optfree(opts);
	return 1;
    }

    pt = optget(opts, "AddHeader")->strarg;
    if(strcasecmp(pt, "No")) {
	char myname[255];

	if(!gethostname(myname, sizeof(myname))) {
	    myname[sizeof(myname)-1] = '\0';
	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s at %s", get_version(), myname);
	    xvirushdr[sizeof(xvirushdr)-1] = '\0';
	} else {
	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s", get_version());
	    xvirushdr[sizeof(xvirushdr)-1] = '\0';
	}

	descr.xxfi_flags |= SMFIF_ADDHDRS;

	if(strcasecmp(pt, "Add")) { /* Replace or Yes */
	    descr.xxfi_flags |= SMFIF_CHGHDRS;
	    addxvirus = 1;
	} else { /* Add */
	    addxvirus = 2;
	}
    }
    
    if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
	logg("!Please configure the MilterSocket directive\n");
	localnets_free();
	whitelist_free();
	logg_close();
	optfree(opts);
	return 1;
    }

    if(!optget(opts, "Foreground")->enabled) {
	if(daemonize() == -1) {
	    logg("!daemonize() failed\n");
	    localnets_free();
	    whitelist_free();
	    cpool_free();
	    logg_close();
	    optfree(opts);
	    return 1;
	}
	if(chdir("/") == -1)
	    logg("^Can't change current working directory to root\n");
    }

    if(smfi_setconn(my_socket) == MI_FAILURE) {
	logg("!smfi_setconn failed\n");
	localnets_free();
	whitelist_free();
	logg_close();
	optfree(opts);
	return 1;
    }
    if(smfi_register(descr) == MI_FAILURE) {
	logg("!smfi_register failed\n");
	localnets_free();
	whitelist_free();
	logg_close();
	optfree(opts);
	return 1;
    }
    opt = optget(opts, "FixStaleSocket");
    if(smfi_opensocket(opt->enabled) == MI_FAILURE) {
	logg("!Failed to create socket %s\n", my_socket);
	localnets_free();
	whitelist_free();
	logg_close();
	optfree(opts);
	return 1;
    }

    maxfilesize = optget(opts, "MaxFileSize")->numarg;
    readtimeout = optget(opts, "ReadTimeout")->numarg;

    cpool_init(opts);
    if (!cp) {
	logg("!Failed to init the socket pool\n");
	localnets_free();
	whitelist_free();
	logg_close();
	optfree(opts);
	return 1;
    }	

    if((opt = optget(opts, "PidFile"))->enabled) {
	FILE *fd;
	mode_t old_umask = umask(0006);

	if((fd = fopen(opt->strarg, "w")) == NULL) {
	    logg("!Can't save PID in file %s\n", opt->strarg);
	} else {
	    if (fprintf(fd, "%u", (unsigned int)getpid())<0) {
	    	logg("!Can't save PID in file %s\n", opt->strarg);
	    }
	    fclose(fd);
	}
	umask(old_umask);
    }

    ret = smfi_main();

    optfree(opts);

    logg_close();
    cpool_free();
    localnets_free();
    whitelist_free();

    return ret;
}
コード例 #11
0
ファイル: manager.c プロジェクト: OPSF/uClinux
/*
 * TODO:
 * - strptime() is most likely not portable enough
 */
int submitstats(const char *clamdcfg, const struct optstruct *opts)
{
	int fd, sd, bread, lread = 0, cnt, ret;
	char post[SUBMIT_MIN_ENTRIES * 256 + 512];
	char query[SUBMIT_MIN_ENTRIES * 256];
	char buff[512], statsdat[512], newstatsdat[512], uastr[128];
	char logfile[256], fbuff[FILEBUFF];
	char *pt, *pt2, *auth = NULL;
	const char *line, *country = NULL, *user, *proxy = NULL;
	struct optstruct *clamdopt;
	const struct optstruct *opt;
	struct stat sb;
	struct tm tms;
	time_t epoch;
	unsigned int qcnt, entries, submitted = 0, permfail = 0, port = 0;


    if((opt = optget(opts, "DetectionStatsCountry"))->enabled) {
	if(strlen(opt->strarg) != 2 || !isalpha(opt->strarg[0]) || !isalpha(opt->strarg[1])) {
	    logg("!SubmitDetectionStats: DetectionStatsCountry requires a two-letter country code\n");
	    return 56;
	}
	country = opt->strarg;
    }

    if(!(clamdopt = optparse(clamdcfg, 0, NULL, 1, OPT_CLAMD, 0, NULL))) {
	logg("!SubmitDetectionStats: Can't open or parse configuration file %s\n", clamdcfg);
	return 56;
    }

    if(!(opt = optget(clamdopt, "LogFile"))->enabled) {
	logg("!SubmitDetectionStats: LogFile needs to be enabled in %s\n", clamdcfg);
	optfree(clamdopt);
	return 56;
    }
    strncpy(logfile, opt->strarg, sizeof(logfile));
    logfile[sizeof(logfile) - 1] = 0;

    if(!optget(clamdopt, "LogTime")->enabled) {
	logg("!SubmitDetectionStats: LogTime needs to be enabled in %s\n", clamdcfg);
	optfree(clamdopt);
	return 56;
    }
    optfree(clamdopt);

    if((fd = open("stats.dat", O_RDONLY)) != -1) {
	if((bread = read(fd, statsdat, sizeof(statsdat) - 1)) == -1) {
	    logg("^SubmitDetectionStats: Can't read stats.dat\n");
	    bread = 0;
	}
	statsdat[bread] = 0;
	close(fd);
    } else {
	*statsdat = 0;
    }

    if((fd = open(logfile, O_RDONLY)) == -1) {
	logg("!SubmitDetectionStats: Can't open %s for reading\n", logfile);
	return 56;
    }

    if(fstat(fd, &sb) == -1) {
	logg("!SubmitDetectionStats: fstat() failed\n");
	close(fd);
	return 56;
    }

    while((line = readbline(fd, fbuff, FILEBUFF, sb.st_size, &lread)))
	if(strlen(line) >= 32 && !strcmp(&line[strlen(line) - 6], " FOUND"))
	    break;

    if(!line) {
	logg("SubmitDetectionStats: No detection records found\n");
	close(fd);
	return 1;
    }

    if(*statsdat && !strcmp(line, statsdat)) {
	logg("SubmitDetectionStats: No new detection records found\n");
	close(fd);
	return 1;
    } else {
	strncpy(newstatsdat, line, sizeof(newstatsdat));
    }

    if((opt = optget(opts, "HTTPUserAgent"))->enabled)
	strncpy(uastr, opt->strarg, sizeof(uastr));
    else
	snprintf(uastr, sizeof(uastr), PACKAGE"/%s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")%s%s", get_version(), country ? ":" : "", country ? country : "");
    uastr[sizeof(uastr) - 1] = 0;

    if((opt = optget(opts, "HTTPProxyServer"))->enabled) {
	proxy = opt->strarg;
	if(!strncasecmp(proxy, "http://", 7))
	    proxy += 7;

	if((opt = optget(opts, "HTTPProxyUsername"))->enabled) {
	    user = opt->strarg;
	    if(!(opt = optget(opts, "HTTPProxyPassword"))->enabled) {
		logg("!SubmitDetectionStats: HTTPProxyUsername requires HTTPProxyPassword\n");
		close(fd);
		return 56;
	    }
	    auth = proxyauth(user, opt->strarg);
	    if(!auth) {
		close(fd);
		return 56;
	    }
	}

	if((opt = optget(opts, "HTTPProxyPort"))->enabled)
	    port = opt->numarg;

	logg("*Connecting via %s\n", proxy);
    }

    ret = 0;
    memset(query, 0, sizeof(query));
    qcnt = 0;
    entries = 0;
    do {
	if(strlen(line) < 32 || strcmp(&line[strlen(line) - 6], " FOUND"))
	    continue;

	if(*statsdat && !strcmp(line, statsdat))
	    break;

	strncpy(buff, line, sizeof(buff));
	buff[sizeof(buff) - 1] = 0;

	if(!(pt = strstr(buff, " -> "))) {
	    logg("*SubmitDetectionStats: Skipping detection entry logged without time\b");
	    continue;
	}
	*pt = 0;
	pt += 4;

	if(!strptime(buff, "%a %b  %d %H:%M:%S %Y", &tms) || (epoch = mktime(&tms)) == -1) {
	    logg("!SubmitDetectionStats: Failed to convert date string\n");
	    ret = 1;
	    break;
	}

	pt2 = &pt[strlen(pt) - 6];
	*pt2 = 0;

	if(!(pt2 = strrchr(pt, ':'))) {
	    logg("!SubmitDetectionStats: Incorrect format of the log file (1)\n");
	    ret = 1;
	    break;
	}
	*pt2 = 0;
	pt2 += 2;

#ifdef C_WINDOWS
	if((pt = strrchr(pt, '\\')))
#else
	if((pt = strrchr(pt, '/')))
#endif
	    *pt++ = 0;
	if(!pt)
	    pt = (char*) "NOFNAME";

	qcnt += snprintf(&query[qcnt], sizeof(query) - qcnt, "ts[]=%u&fname[]=%s&virus[]=%s&", (unsigned int) epoch, pt, pt2);
	entries++;

	if(entries == SUBMIT_MIN_ENTRIES) {
	    sd = wwwconnect("stats.clamav.net", proxy, port, NULL, optget(opts, "LocalIPAddress")->strarg, optget(opts, "ConnectTimeout")->numarg, NULL, 0, 0);
	    if(sd == -1) {
		logg("!SubmitDetectionStats: Can't connect to server\n");
		ret = 52;
		break;
	    }

	    query[sizeof(query) - 1] = 0;
	    snprintf(post, sizeof(post),
		"POST http://stats.clamav.net/submit.php HTTP/1.0\r\n"
		"Host: stats.clamav.net\r\n%s"
		"Content-Type: application/x-www-form-urlencoded\r\n"
		"User-Agent: %s\r\n"
		"Content-Length: %u\r\n\n"
		"%s",
	    auth ? auth : "", uastr, (unsigned int) strlen(query), query);

	    if(send(sd, post, strlen(post), 0) < 0) {
		logg("!SubmitDetectionStats: Can't write to socket\n");
		ret = 52;
		closesocket(sd);
		break;
	    }

	    pt = post;
	    cnt = sizeof(post) - 1;
#ifdef SO_ERROR
	    while((bread = wait_recv(sd, pt, cnt, 0, optget(opts, "ReceiveTimeout")->numarg)) > 0) {
#else
	    while((bread = recv(sd, pt, cnt, 0)) > 0) {
#endif
		pt += bread;
		cnt -= bread;
		if(cnt <= 0)
		    break;
	    }
	    *pt = 0;
	    closesocket(sd);

	    if(bread < 0) {
		logg("!SubmitDetectionStats: Can't read from socket\n");
		ret = 52;
		break;
	    }

	    if(strstr(post, "SUBMIT_OK")) {
		submitted += entries;
		if(submitted + SUBMIT_MIN_ENTRIES > SUBMIT_MAX_ENTRIES)
		    break;
		qcnt = 0;
		entries = 0;
		memset(query, 0, sizeof(query));
		continue;
	    }

	    ret = 52;
	    if((pt = strstr(post, "SUBMIT_PERMANENT_FAILURE"))) {
		if(!submitted) {
		    permfail = 1;
		    if((pt + 32 <= post + sizeof(post)) && pt[24] == ':')
			logg("!SubmitDetectionStats: Remote server reported permanent failure: %s\n", &pt[25]);
		    else
			logg("!SubmitDetectionStats: Remote server reported permanent failure\n");
		}
	    } else if((pt = strstr(post, "SUBMIT_TEMPORARY_FAILURE"))) {
		if(!submitted) {
		    if((pt + 32 <= post + sizeof(post)) && pt[24] == ':')
			logg("!SubmitDetectionStats: Remote server reported temporary failure: %s\n", &pt[25]);
		    else
			logg("!SubmitDetectionStats: Remote server reported temporary failure\n");
		}
	    } else {
		if(!submitted)
		    logg("!SubmitDetectionStats: Incorrect answer from server\n");
	    }

	    break;
	}

    } while((line = readbline(fd, fbuff, FILEBUFF, sb.st_size, &lread)));

    close(fd);
    if(auth)
	free(auth);

    if(submitted || permfail) {
	if((fd = open("stats.dat", O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1) {
	    logg("^SubmitDetectionStats: Can't open stats.dat for writing\n");
	} else {
	    if((bread = write(fd, newstatsdat, sizeof(newstatsdat))) != sizeof(newstatsdat))
		logg("^SubmitDetectionStats: Can't write to stats.dat\n");
	    close(fd);
	}
    }

    if(ret == 0) {
	if(!submitted)
	    logg("SubmitDetectionStats: Not enough recent data for submission\n");
	else
	    logg("SubmitDetectionStats: Submitted %u records\n", submitted);
    }

    return ret;
}

static int Rfc2822DateTime(char *buf, time_t mtime)
{
	struct tm *gmt;

    gmt = gmtime(&mtime);
    return strftime(buf, 36, "%a, %d %b %Y %X GMT", gmt);
}

static struct cl_cvd *remote_cvdhead(const char *cvdfile, const char *localfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int *ims, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
{
	char cmd[512], head[513], buffer[FILEBUFF], ipaddr[46], *ch, *tmp;
	int bread, cnt, sd;
	unsigned int i, j;
	char *remotename = NULL, *authorization = NULL;
	struct cl_cvd *cvd;
	char last_modified[36], uastr[128];


    if(proxy) {
        remotename = malloc(strlen(hostname) + 8);
	if(!remotename) {
	    logg("!remote_cvdhead: Can't allocate memory for 'remotename'\n");
	    return NULL;
	}
        sprintf(remotename, "http://%s", hostname);

	if(user) {
	    authorization = proxyauth(user, pass);
	    if(!authorization) {
		free(remotename);
		return NULL;
	    }
	}
    }

    if(!access(localfile, R_OK)) {
	cvd = cl_cvdhead(localfile);
	if(!cvd) {
	    logg("!remote_cvdhead: Can't parse file %s\n", localfile);
	    free(remotename);
	    free(authorization);
	    return NULL;
	}
	Rfc2822DateTime(last_modified, (time_t) cvd->stime);
	cl_cvdfree(cvd);
    } else {
	    time_t mtime = 1104119530;

	Rfc2822DateTime(last_modified, mtime);
	logg("*Assuming modification time in the past\n");
    }

    logg("*If-Modified-Since: %s\n", last_modified);

    logg("Reading CVD header (%s): ", cvdfile);

    if(uas)
	strncpy(uastr, uas, sizeof(uastr));
    else
	snprintf(uastr, sizeof(uastr), PACKAGE"/%s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")", get_version());
    uastr[sizeof(uastr) - 1] = 0;

    snprintf(cmd, sizeof(cmd),
	"GET %s/%s HTTP/1.0\r\n"
	"Host: %s\r\n%s"
	"User-Agent: %s\r\n"
	"Connection: close\r\n"
	"Range: bytes=0-511\r\n"
        "If-Modified-Since: %s\r\n"
        "\r\n", (remotename != NULL) ? remotename : "", cvdfile, hostname, (authorization != NULL) ? authorization : "", uastr, last_modified);

    free(remotename);
    free(authorization);

    memset(ipaddr, 0, sizeof(ipaddr));

    if(ip[0]) /* use ip to connect */
	sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
    else
	sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);

    if(sd < 0) {
	return NULL;
    } else {
	logg("*Connected to %s (IP: %s).\n", hostname, ipaddr);
	logg("*Trying to retrieve CVD header of http://%s/%s\n", hostname, cvdfile);
    }

    if(!ip[0])
	strcpy(ip, ipaddr);

    if(send(sd, cmd, strlen(cmd), 0) < 0) {
	logg("%cremote_cvdhead: write failed\n", logerr ? '!' : '^');
	closesocket(sd);
	return NULL;
    }

    tmp = buffer;
    cnt = FILEBUFF;
#ifdef SO_ERROR
    while((bread = wait_recv(sd, tmp, cnt, 0, rtimeout)) > 0) {
#else
    while((bread = recv(sd, tmp, cnt, 0)) > 0) {
#endif
	tmp += bread;
	cnt -= bread;
	if(cnt <= 0)
	    break;
    }
    closesocket(sd);

    if(bread == -1) {
	logg("%cremote_cvdhead: Error while reading CVD header from %s\n", logerr ? '!' : '^', hostname);
	mirman_update(mdat->currip, mdat->af, mdat, 1);
	return NULL;
    }

    if((strstr(buffer, "HTTP/1.1 404")) != NULL || (strstr(buffer, "HTTP/1.0 404")) != NULL) { 
	logg("%cCVD file not found on remote server\n", logerr ? '!' : '^');
	mirman_update(mdat->currip, mdat->af, mdat, 2);
	return NULL;
    }

    /* check whether the resource is up-to-date */
    if((strstr(buffer, "HTTP/1.1 304")) != NULL || (strstr(buffer, "HTTP/1.0 304")) != NULL) { 
	*ims = 0;
	logg("OK (IMS)\n");
	mirman_update(mdat->currip, mdat->af, mdat, 0);
	return NULL;
    } else {
	*ims = 1;
    }

    if(!strstr(buffer, "HTTP/1.1 200") && !strstr(buffer, "HTTP/1.0 200") &&
       !strstr(buffer, "HTTP/1.1 206") && !strstr(buffer, "HTTP/1.0 206")) {
	logg("%cUnknown response from remote server\n", logerr ? '!' : '^');
	mirman_update(mdat->currip, mdat->af, mdat, 1);
	return NULL;
    }

    i = 3;
    ch = buffer + i;
    while(i < sizeof(buffer)) {
	if (*ch == '\n' && *(ch - 1) == '\r' && *(ch - 2) == '\n' && *(ch - 3) == '\r') {
	    ch++;
	    i++;
	    break;
	}
	ch++;
	i++;
    }

    if(sizeof(buffer) - i < 512) {
	logg("%cremote_cvdhead: Malformed CVD header (too short)\n", logerr ? '!' : '^');
	mirman_update(mdat->currip, mdat->af, mdat, 1);
	return NULL;
    }

    memset(head, 0, sizeof(head));

    for(j = 0; j < 512; j++) {
	if(!ch || (ch && !*ch) || (ch && !isprint(ch[j]))) {
	    logg("%cremote_cvdhead: Malformed CVD header (bad chars)\n", logerr ? '!' : '^');
	    mirman_update(mdat->currip, mdat->af, mdat, 1);
	    return NULL;
	}
	head[j] = ch[j];
    }

    if(!(cvd = cl_cvdparse(head))) {
	logg("%cremote_cvdhead: Malformed CVD header (can't parse)\n", logerr ? '!' : '^');
	mirman_update(mdat->currip, mdat->af, mdat, 1);
    } else {
	logg("OK\n");
	mirman_update(mdat->currip, mdat->af, mdat, 0);
    }

    return cvd;
}

static int getfile(const char *srcfile, const char *destfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
{
	char cmd[512], uastr[128], buffer[FILEBUFF], *ch;
	int bread, fd, totalsize = 0,  rot = 0, totaldownloaded = 0,
	    percentage = 0, sd;
	unsigned int i;
	char *remotename = NULL, *authorization = NULL, *headerline, ipaddr[46];
	const char *rotation = "|/-\\";
#ifdef FILTER_RULES
	pid_t pid = -1;
#endif


    if(proxy) {
        remotename = malloc(strlen(hostname) + 8);
	if(!remotename) {
	    logg("!getfile: Can't allocate memory for 'remotename'\n");
	    return 75; /* FIXME */
	}
        sprintf(remotename, "http://%s", hostname);

	if(user) {
	    authorization = proxyauth(user, pass);
	    if(!authorization) {
		free(remotename);
		return 75; /* FIXME */
	    }
	}
    }

    if(uas)
	strncpy(uastr, uas, sizeof(uastr));
    else
	snprintf(uastr, sizeof(uastr), PACKAGE"/%s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")", get_version());
    uastr[sizeof(uastr) - 1] = 0;

    snprintf(cmd, sizeof(cmd),
	"GET %s/%s HTTP/1.0\r\n"
	"Host: %s\r\n%s"
	"User-Agent: %s\r\n"
#ifdef FRESHCLAM_NO_CACHE
	"Cache-Control: no-cache\r\n"
#endif
	"Connection: close\r\n"
	"\r\n", (remotename != NULL) ? remotename : "", srcfile, hostname, (authorization != NULL) ? authorization : "", uastr);

    if(remotename)
	free(remotename);

    if(authorization)
	free(authorization);

    memset(ipaddr, 0, sizeof(ipaddr));
    if(ip[0]) /* use ip to connect */
	sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
    else
	sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);

    if(sd < 0) {
	return 52;
    } else {
	logg("*Trying to download http://%s/%s (IP: %s)\n", hostname, srcfile, ipaddr);
    }

    if(!ip[0])
	strcpy(ip, ipaddr);

    if(send(sd, cmd, strlen(cmd), 0) < 0) {
	logg("%cgetfile: Can't write to socket\n", logerr ? '!' : '^');
	closesocket(sd);
	return 52;
    }

    /* read http headers */
    ch = buffer;
    i = 0;
    while(1) {
	/* recv one byte at a time, until we reach \r\n\r\n */
#ifdef SO_ERROR
	if((i >= sizeof(buffer) - 1) || wait_recv(sd, buffer + i, 1, 0, rtimeout) == -1) {
#else
	if((i >= sizeof(buffer) - 1) || recv(sd, buffer + i, 1, 0) == -1) {
#endif
	    logg("%cgetfile: Error while reading database from %s (IP: %s)\n", logerr ? '!' : '^', hostname, ipaddr);
	    mirman_update(mdat->currip, mdat->af, mdat, 1);
	    closesocket(sd);
	    return 52;
	}

	if(i > 2 && *ch == '\n' && *(ch - 1) == '\r' && *(ch - 2) == '\n' && *(ch - 3) == '\r') {
	    i++;
	    break;
	}
	ch++;
	i++;
    }

    buffer[i] = 0;

    /* check whether the resource actually existed or not */
    if((strstr(buffer, "HTTP/1.1 404")) != NULL || (strstr(buffer, "HTTP/1.0 404")) != NULL) { 
	logg("^getfile: %s not found on remote server (IP: %s)\n", srcfile, ipaddr);
	mirman_update(mdat->currip, mdat->af, mdat, 2);
	closesocket(sd);
	return 58;
    }

    if(!strstr(buffer, "HTTP/1.1 200") && !strstr(buffer, "HTTP/1.0 200") &&
       !strstr(buffer, "HTTP/1.1 206") && !strstr(buffer, "HTTP/1.0 206")) {
	logg("%cgetfile: Unknown response from remote server (IP: %s)\n", logerr ? '!' : '^', ipaddr);
	mirman_update(mdat->currip, mdat->af, mdat, 1);
	closesocket(sd);
	return 58;
    }

    /* get size of resource */
    for(i = 0; (headerline = cli_strtok(buffer, i, "\n")); i++){
        if(strstr(headerline, "Content-Length:")) { 
	    if((ch = cli_strtok(headerline, 1, ": "))) {
		totalsize = atoi(ch);
		free(ch);
	    } else {
		totalsize = 0;
	    }
        }
	free(headerline);
    }

#ifdef FILTER_RULES
    {
        int pfd[2];

    	if (pipe(pfd) == -1) {
	    logg("!getfile: Can't create pipe to filter\n");
	    closesocket(sd);
	    return 57;
	}
	pid = fork();
	if (pid == -1) {
	    logg("!getfile: Can't filter fork failed\n");
	    closesocket(sd);
	    return 57;
	}
	if (pid == 0) {
	    /* Child */
	    close(pfd[1]);
	    dup2(pfd[0], 0);
	    close(pfd[0]);
	    execl("/bin/clamfilter", "clamfilter", destfile, NULL);
	    _exit(1);
	}
	/* Parent */
	close(pfd[0]);
	fd = pfd[1];
	destfile = "clam-filter";
    }
#else
    if((fd = open(destfile, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644)) == -1) {
	    char currdir[512];

	if(getcwd(currdir, sizeof(currdir)))
	    logg("!getfile: Can't create new file %s in %s\n", destfile, currdir);
	else
	    logg("!getfile: Can't create new file %s in the current directory\n", destfile);

	logg("Hint: The database directory must be writable for UID %d or GID %d\n", getuid(), getgid());
	closesocket(sd);
	return 57;
    }
#endif

#ifdef SO_ERROR
    while((bread = wait_recv(sd, buffer, FILEBUFF, 0, rtimeout)) > 0) {
#else
    while((bread = recv(sd, buffer, FILEBUFF, 0)) > 0) {
#endif
        if(write(fd, buffer, bread) != bread) {
	    logg("getfile: Can't write %d bytes to %s\n", bread, destfile);
#ifdef FILTER_RULES
//	    if (pid == -1)
//	        unlink(destfile);
#else
	    unlink(destfile);
#endif
	    close(fd);
	    closesocket(sd);
	    return 57; /* FIXME */
	}

        if(totalsize > 0) {
	    totaldownloaded += bread;
            percentage = (int) (100 * (float) totaldownloaded / totalsize);
	}

        if(!mprintf_quiet) {
            if(totalsize > 0) {
                mprintf("Downloading %s [%3i%%]\r", srcfile, percentage);
            } else {
                mprintf("Downloading %s [%c]\r", srcfile, rotation[rot]);
                rot++;
                rot %= 4;
            }
            fflush(stdout);
        }
    }
    closesocket(sd);
    close(fd);

#ifdef FILTER_RULES
    /*if (pid != -1)*/ {
	    int status;

	waitpid(pid, &status, 0);
	if (! WIFEXITED(status) || WEXITSTATUS(status) != 0) {
	    logg("!getfile: Filter failed\n");
	    return 57;
	}
    }
#endif

    if(totalsize > 0)
        logg("Downloading %s [%i%%]\n", srcfile, percentage);
    else
        logg("Downloading %s [*]\n", srcfile);

    mirman_update(mdat->currip, mdat->af, mdat, 0);
    return 0;
}

static int getcvd(const char *cvdfile, const char *newfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, unsigned int newver, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
{
	struct cl_cvd *cvd;
	int ret;


    logg("*Retrieving http://%s/%s\n", hostname, cvdfile);
    if((ret = getfile(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr, can_whitelist))) {
        logg("%cCan't download %s from %s\n", logerr ? '!' : '^', cvdfile, hostname);
        unlink(newfile);
        return ret;
    }

    if((ret = cl_cvdverify(newfile))) {
        logg("!Verification: %s\n", cl_strerror(ret));
        unlink(newfile);
        return 54;
    }

    if(!(cvd = cl_cvdhead(newfile))) {
	logg("!Can't read CVD header of new %s database.\n", cvdfile);
	unlink(newfile);
	return 54;
    }

    if(cvd->version < newver) {
	logg("^Mirror %s is not synchronized.\n", ip);
	mirman_update(mdat->currip, mdat->af, mdat, 2);
    	cl_cvdfree(cvd);
	unlink(newfile);
	return 59;
    }

    cl_cvdfree(cvd);
    return 0;
}

static int chdir_tmp(const char *dbname, const char *tmpdir)
{
	char cvdfile[32];


    if(access(tmpdir, R_OK|W_OK) == -1) {
	sprintf(cvdfile, "%s.cvd", dbname);
	if(access(cvdfile, R_OK) == -1) {
	    sprintf(cvdfile, "%s.cld", dbname);
	    if(access(cvdfile, R_OK) == -1) {
		logg("!chdir_tmp: Can't access local %s database\n", dbname);
		return -1;
	    }
	}

	if(mkdir(tmpdir, 0755) == -1) {
	    logg("!chdir_tmp: Can't create directory %s\n", tmpdir);
	    return -1;
	}

	if(cli_cvdunpack(cvdfile, tmpdir) == -1) {
	    logg("!chdir_tmp: Can't unpack %s into %s\n", cvdfile, tmpdir);
	    cli_rmdirs(tmpdir);
	    return -1;
	}
    }

    if(chdir(tmpdir) == -1) {
	logg("!chdir_tmp: Can't change directory to %s\n", tmpdir);
	return -1;
    }

    return 0;
}

static int getpatch(const char *dbname, const char *tmpdir, int version, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
{
	char *tempname, patch[32], olddir[512];
	int ret, fd;


    if(!getcwd(olddir, sizeof(olddir))) {
	logg("!getpatch: Can't get path of current working directory\n");
	return 50; /* FIXME */
    }

    if(chdir_tmp(dbname, tmpdir) == -1)
	return 50;

    tempname = cli_gentemp(".");
    snprintf(patch, sizeof(patch), "%s-%d.cdiff", dbname, version);

    logg("*Retrieving http://%s/%s\n", hostname, patch);
    if((ret = getfile(patch, tempname, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr, can_whitelist))) {
        logg("%cgetpatch: Can't download %s from %s\n", logerr ? '!' : '^', patch, hostname);
        unlink(tempname);
        free(tempname);
	CHDIR_ERR(olddir);
        return ret;
    }

    if((fd = open(tempname, O_RDONLY|O_BINARY)) == -1) {
	logg("!getpatch: Can't open %s for reading\n", tempname);
        unlink(tempname);
        free(tempname);
	CHDIR_ERR(olddir);
	return 55;
    }

    if(cdiff_apply(fd, 1) == -1) {
	logg("!getpatch: Can't apply patch\n");
	close(fd);
        unlink(tempname);
        free(tempname);
	CHDIR_ERR(olddir);
	return 70; /* FIXME */
    }

    close(fd);
    unlink(tempname);
    free(tempname);
    if(chdir(olddir) == -1) {
	logg("!getpatch: Can't chdir to %s\n", olddir);
	return 50; /* FIXME */
    }
    return 0;
}
コード例 #12
0
ファイル: clamav-milter.c プロジェクト: Distrotech/clamav
int main(int argc, char **argv) {
    char *my_socket, *pt;
    const struct optstruct *opt;
    struct optstruct *opts;
    time_t currtime;
    mode_t umsk;
    int ret;

    cl_initialize_crypto();

    memset(&descr, 0, sizeof(struct smfiDesc));
    descr.xxfi_name = "ClamAV";			/* filter name */
    descr.xxfi_version = SMFI_VERSION;		/* milter version */
    descr.xxfi_flags = SMFIF_QUARANTINE;	/* flags */
    descr.xxfi_connect = clamfi_connect;	/* connection info filter */
    descr.xxfi_envfrom = clamfi_envfrom;	/* envelope sender filter */
    descr.xxfi_envrcpt = clamfi_envrcpt;	/* envelope recipient filter */
    descr.xxfi_header = clamfi_header;		/* header filter */
    descr.xxfi_body = clamfi_body;		/* body block */
    descr.xxfi_eom = clamfi_eom;		/* end of message */
    descr.xxfi_abort = clamfi_abort;		/* message aborted */

    opts = optparse(NULL, argc, argv, 1, OPT_MILTER, 0, NULL);
    if (!opts) {
	mprintf("!Can't parse command line options\n");
	return 1;
    }

    if(optget(opts, "help")->enabled) {
	printf("Usage: %s [-c <config-file>]\n\n", argv[0]);
	printf("    --help                   -h       Show this help\n");
	printf("    --version                -V       Show version and exit\n");
	printf("    --config-file <file>     -c       Read configuration from file\n\n");
	optfree(opts);
	return 0;
    }

    if(opts->filename) {
	int x;
	for(x = 0; opts->filename[x]; x++)
	    mprintf("^Ignoring option %s\n", opts->filename[x]);
    }

    if(optget(opts, "version")->enabled) {
	printf("clamav-milter %s\n", get_version());
	optfree(opts);
	return 0;
    }

    pt = strdup(optget(opts, "config-file")->strarg);
    if (pt == NULL) {
	printf("Unable to allocate memory for config file\n");
	return 1;
    }
    if((opts = optparse(pt, 0, NULL, 1, OPT_MILTER, 0, opts)) == NULL) {
	printf("%s: cannot parse config file %s\n", argv[0], pt);
	free(pt);
	return 1;
    }
    free(pt);

    if((opt = optget(opts, "Chroot"))->enabled) {
	if(chdir(opt->strarg) != 0) {
	    logg("!Cannot change directory to %s\n", opt->strarg);
	    return 1;
	}
	if(chroot(opt->strarg) != 0) {
	    logg("!chroot to %s failed. Are you root?\n", opt->strarg);
	    return 1;
	}
    }

    pt = optget(opts, "AddHeader")->strarg;
    if (strcasecmp(pt, "No")) {
	char myname[255];

	if (((opt = optget(opts, "ReportHostname"))->enabled &&
	     strncpy(myname, opt->strarg, sizeof(myname))) ||
	    !gethostname(myname, sizeof(myname))) {

	    myname[sizeof(myname)-1] = '\0';
	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s at %s",
		     get_version(), myname);
	} else {
	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s",
		     get_version());
	}
	xvirushdr[sizeof(xvirushdr)-1] = '\0';

	descr.xxfi_flags |= SMFIF_ADDHDRS;

	if (strcasecmp(pt, "Add")) { /* Replace or Yes */
	    descr.xxfi_flags |= SMFIF_CHGHDRS;
	    addxvirus = 1;
	} else { /* Add */
	    addxvirus = 2;
	}
    }

    if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
	logg("!Please configure the MilterSocket directive\n");
	logg_close();
	optfree(opts);
	return 1;
    }

    if(smfi_setconn(my_socket) == MI_FAILURE) {
	logg("!smfi_setconn failed\n");
	logg_close();
	optfree(opts);
	return 1;
    }
    if(smfi_register(descr) == MI_FAILURE) {
	logg("!smfi_register failed\n");
	logg_close();
	optfree(opts);
	return 1;
    }
    opt = optget(opts, "FixStaleSocket");
    umsk = umask(0777); /* socket is created with 000 to avoid races */
    if(smfi_opensocket(opt->enabled) == MI_FAILURE) {
	logg("!Failed to create socket %s\n", my_socket);
	logg_close();
	optfree(opts);
	return 1;
    }
    umask(umsk); /* restore umask */
    if(strncmp(my_socket, "inet:", 5) && strncmp(my_socket, "inet6:", 6)) {
	/* set group ownership and perms on the local socket */
	char *sock_name = my_socket;
	mode_t sock_mode;
	if(!strncmp(my_socket, "unix:", 5))
	    sock_name += 5;
	if(!strncmp(my_socket, "local:", 6))
	    sock_name += 6;
	if(*my_socket == ':')
	    sock_name ++;

	if(optget(opts, "MilterSocketGroup")->enabled) {
	    char *gname = optget(opts, "MilterSocketGroup")->strarg, *end;
	    gid_t sock_gid = strtol(gname, &end, 10);
	    if(*end) {
		struct group *pgrp = getgrnam(gname);
		if(!pgrp) {
		    logg("!Unknown group %s\n", gname);
		    logg_close();
		    optfree(opts);
		    return 1;
		}
		sock_gid = pgrp->gr_gid;
	    }
	    if(chown(sock_name, -1, sock_gid)) {
		logg("!Failed to change socket ownership to group %s\n", gname);
		logg_close();
		optfree(opts);
		return 1;
	    }
	}

	if ((opt = optget(opts, "User"))->enabled) {
	    struct passwd *user;
	    if ((user = getpwnam(opt->strarg)) == NULL) {
		logg("ERROR: Can't get information about user %s.\n",
			opt->strarg);
		logg_close();
		optfree(opts);
		return 1;
	    }

	    if(chown(sock_name, user->pw_uid, -1)) {
		logg("!Failed to change socket ownership to user %s\n", user->pw_name);
		optfree(opts);
		logg_close();
		return 1;
	    }
	}

	if(optget(opts, "MilterSocketMode")->enabled) {
	    char *end;
	    sock_mode = strtol(optget(opts, "MilterSocketMode")->strarg, &end, 8);
	    if(*end) {
		logg("!Invalid MilterSocketMode %s\n", optget(opts, "MilterSocketMode")->strarg);
		logg_close();
		optfree(opts);
		return 1;
	    }
	} else
	    sock_mode = 0777 & ~umsk;

	if(chmod(sock_name, sock_mode & 0666)) {
	    logg("!Cannot set milter socket permission to %s\n", optget(opts, "MilterSocketMode")->strarg);
	    logg_close();
	    optfree(opts);
	    return 1;
	}
    }

    if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
        struct passwd *user = NULL;
	if((user = getpwnam(opt->strarg)) == NULL) {
	    fprintf(stderr, "ERROR: Can't get information about user %s.\n", opt->strarg);
	    optfree(opts);
	    return 1;
	}

	if(optget(opts, "AllowSupplementaryGroups")->enabled) {
#ifdef HAVE_INITGROUPS
	    if(initgroups(opt->strarg, user->pw_gid)) {
		fprintf(stderr, "ERROR: initgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#else
	    mprintf("!AllowSupplementaryGroups: initgroups() is not available, please disable AllowSupplementaryGroups\n");
	    optfree(opts);
	    return 1;
#endif
	} else {
#ifdef HAVE_SETGROUPS
	    if(setgroups(1, &user->pw_gid)) {
		fprintf(stderr, "ERROR: setgroups() failed.\n");
		optfree(opts);
		return 1;
	    }
#endif
	}

	if(setgid(user->pw_gid)) {
	    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
	    optfree(opts);
	    return 1;
	}

	if(setuid(user->pw_uid)) {
	    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
	    optfree(opts);
	    return 1;
	}
    }

    logg_lock = !optget(opts, "LogFileUnlock")->enabled;
    logg_time = optget(opts, "LogTime")->enabled;
    logg_size = optget(opts, "LogFileMaxSize")->numarg;
    logg_verbose = mprintf_verbose = optget(opts, "LogVerbose")->enabled;
    if (logg_size)
        logg_rotate = optget(opts, "LogRotate")->enabled;

    if((opt = optget(opts, "LogFile"))->enabled) {
	logg_file = opt->strarg;
	if(!cli_is_abspath(logg_file)) {
	    fprintf(stderr, "ERROR: LogFile requires full path.\n");
	    logg_close();
	    optfree(opts);
	    return 1;
	}
    } else
	logg_file = NULL;

#if defined(USE_SYSLOG) && !defined(C_AIX)
    if(optget(opts, "LogSyslog")->enabled) {
	int fac;

	opt = optget(opts, "LogFacility");
	if((fac = logg_facility(opt->strarg)) == -1) {
	    logg("!LogFacility: %s: No such facility.\n", opt->strarg);
	    logg_close();
	    optfree(opts);
	    return 1;
	}

	openlog("clamav-milter", LOG_PID, fac);
	logg_syslog = 1;
    }
#endif

    time(&currtime);
    if(logg("#+++ Started at %s", ctime(&currtime))) {
	fprintf(stderr, "ERROR: Can't initialize the internal logger\n");
	logg_close();
	optfree(opts);
	return 1;
    }
    if((opt = optget(opts, "TemporaryDirectory"))->enabled)
	tempdir = opt->strarg;

    if(localnets_init(opts) || init_actions(opts)) {
	logg_close();
	optfree(opts);
	return 1;
    }

    if((opt = optget(opts, "Whitelist"))->enabled && whitelist_init(opt->strarg)) {
	localnets_free();
	logg_close();
	optfree(opts);
	return 1;
    }

    if((opt = optget(opts, "SkipAuthenticated"))->enabled && smtpauth_init(opt->strarg)) {
	localnets_free();
	whitelist_free();
	logg_close();
	optfree(opts);
	return 1;
    }

    multircpt = optget(opts, "SupportMultipleRecipients")->enabled;
    
    if(!optget(opts, "Foreground")->enabled) {
	if(daemonize() == -1) {
	    logg("!daemonize() failed\n");
	    localnets_free();
	    whitelist_free();
	    cpool_free();
	    logg_close();
	    optfree(opts);
	    return 1;
	}
	if(chdir("/") == -1)
	    logg("^Can't change current working directory to root\n");
    }

    maxfilesize = optget(opts, "MaxFileSize")->numarg;
    if(!maxfilesize) {
	logg("^Invalid MaxFileSize, using default (%d)\n", CLI_DEFAULT_MAXFILESIZE);
	maxfilesize = CLI_DEFAULT_MAXFILESIZE;
    }
    readtimeout = optget(opts, "ReadTimeout")->numarg;

    cpool_init(opts);
    if (!cp) {
	logg("!Failed to init the socket pool\n");
	localnets_free();
	whitelist_free();
	logg_close();
	optfree(opts);
	return 1;
    }	

    if((opt = optget(opts, "PidFile"))->enabled) {
	FILE *fd;
	mode_t old_umask = umask(0002);

	if((fd = fopen(opt->strarg, "w")) == NULL) {
	    logg("!Can't save PID in file %s\n", opt->strarg);
	} else {
	    if (fprintf(fd, "%u\n", (unsigned int)getpid())<0) {
	    	logg("!Can't save PID in file %s\n", opt->strarg);
	    }
	    fclose(fd);
	}
	umask(old_umask);
    }

    ret = smfi_main();

    optfree(opts);

    logg_close();
    cpool_free();
    localnets_free();
    whitelist_free();

    return ret;
}
コード例 #13
0
ファイル: clamdtop.c プロジェクト: Jyang772/clamav-devel
/* -------------------------- Initialization ---------------- */
static void setup_connections(int argc, char *argv[])
{
    struct optstruct *opts;
    struct optstruct *clamd_opts;
    unsigned i;
    char *conn = NULL;

    opts = optparse(NULL, argc, argv, 1, OPT_CLAMDTOP, 0, NULL);
    if (!opts) {
        fprintf(stderr, "ERROR: Can't parse command line options\n");
        EXIT_PROGRAM(FAIL_CMDLINE);
    }

    if(optget(opts, "help")->enabled) {
        optfree(opts);
        help();
        normal_exit = 1;
        exit(0);
    }

    if(optget(opts, "version")->enabled) {
        printf("Clam AntiVirus Monitoring Tool %s\n", get_version());
        optfree(opts);
        normal_exit = 1;
        exit(0);
    }

    if(optget(opts, "defaultcolors")->enabled)
        default_colors = 1;

    memset(&global, 0, sizeof(global));
    if (!opts->filename || !opts->filename[0]) {
        const struct optstruct *opt;
        const char *clamd_conf = optget(opts, "config-file")->strarg;

        if ((clamd_opts = optparse(clamd_conf, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
            fprintf(stderr, "Can't parse clamd configuration file %s\n", clamd_conf);
            EXIT_PROGRAM(FAIL_CMDLINE);
        }

        if((opt = optget(clamd_opts, "LocalSocket"))->enabled) {
            conn = strdup(opt->strarg);
            if (!conn) {
                fprintf(stderr, "Can't strdup LocalSocket value\n");
                EXIT_PROGRAM(FAIL_INITIAL_CONN);
            }
        } else if ((opt = optget(clamd_opts, "TCPSocket"))->enabled) {
            char buf[512];
            const struct optstruct *opt_addr;
            const char *host = "localhost";
            if ((opt_addr = optget(clamd_opts, "TCPAddr"))->enabled) {
                host = opt_addr->strarg;
            }
            snprintf(buf, sizeof(buf), "%lld", opt->numarg);
            conn = make_ip(host, buf);
        } else {
            fprintf(stderr, "Can't find how to connect to clamd\n");
            EXIT_PROGRAM(FAIL_INITIAL_CONN);
        }

        optfree(clamd_opts);
        global.num_clamd = 1;
    } else {
        unsigned i = 0;
        while (opts->filename[i]) { i++; }
        global.num_clamd = i;
    }

#ifdef _WIN32
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) {
        fprintf(stderr, "Error at WSAStartup(): %d\n", WSAGetLastError());
        EXIT_PROGRAM(FAIL_INITIAL_CONN);
    }
#endif
    /* clamdtop */
    puts( "        __                    ____");
    puts("  _____/ /___ _____ ___  ____/ / /_____  ____");
    puts(" / ___/ / __ `/ __ `__ \\/ __  / __/ __ \\/ __ \\");
    puts("/ /__/ / /_/ / / / / / / /_/ / /_/ /_/ / /_/ /");
    puts("\\___/_/\\__,_/_/ /_/ /_/\\__,_/\\__/\\____/ .___/");
    puts("                                     /_/");

    global.all_stats = calloc(global.num_clamd, sizeof(*global.all_stats));
    OOM_CHECK(global.all_stats);
    global.conn = calloc(global.num_clamd, sizeof(*global.conn));
    OOM_CHECK(global.conn);

    for (i=0;i < global.num_clamd;i++) {
        const char *soname = conn ? conn : opts->filename[i];
        global.conn[i].line = i+1;
        if (make_connection(soname, &global.conn[i]) < 0) {
            EXIT_PROGRAM(FAIL_INITIAL_CONN);
        }
    }

    optfree(opts);
    free(conn);
#ifndef _WIN32
    signal(SIGPIPE, SIG_IGN);
    signal(SIGINT, sigint);
#endif
}
コード例 #14
0
ファイル: tcp-server.c プロジェクト: calcu16/misc
/* driver function */
int main(int argc, char **argv)
{
  char hostaddr[MAXLINE], hostname[MAXLINE], *progname = argv[0], *portstring;
  int listenfd, connfd, error, pid, threaded = 0;
  size_t port, total = 0;
  FILE *logfile = NULL;
  sem_t count;
  struct options options;
  pthread_t cleaning;
  socklen_t clientlen;
  union
  {
    struct sockaddr_in client4;
    struct sockaddr_in6 client6;
  } clientaddr;

  if (sem_init(&count, 0, 0) == -1 || pthread_create(&cleaning, NULL, clean, &count) != 0) {
    perror(NULL);
    fprintf(stderr, "Warning : Unable to initialize thread mechanisms, child processes may not be cleaned up\n");
  } else {
    threaded = 1;
  }

  memset(&options, 0, sizeof(struct options));
  options.argc = argc - 1;
  options.argv = argv + 1;
  options.log_level = &log_level;

  error = optparse(&options);

  if (error || options.argc != 1) {
    fprintf(stderr, usage, progname);
    return error ? error - 1 : 0;
  }

  if (options.logfilename) {
    logfile = fopen(options.logfilename, "a");
  }

  portstring = options.argv[0];

  listenfd = open_socketfd(NULL, portstring, AI_PASSIVE, SOCK_STREAM, &bind);

  if(listenfd < 0) {
    fprintf(stderr, "Error : Cannot listen to socket %s with error %d\n", portstring, listenfd);
    return 1;
  }

  SETSOCKOPT(logfile, LOG_LEVEL_V, listenfd, SOL_SOCKET, SO_REUSEADDR, &option_true);
  SETSOCKOPT(logfile, LOG_LEVEL_L, listenfd, SOL_SOCKET, SO_PRIORITY, options.sopriority);
  SETSOCKOPT(logfile, LOG_LEVEL_L, listenfd, IPPROTO_TCP, TCP_NODELAY, options.tcpnodelay);
  SETSOCKOPT(logfile, LOG_LEVEL_L, listenfd, IPPROTO_TCP, TCP_QUICKACK, options.tcpquickack);

  if (listen(listenfd, LISTEN_MAX) == -1) {
    fprintf(stderr, "Error : Cannot listen on port\n");
    return 1;
  }
  LOG(logfile, LOG_LEVEL_L, "listening\n");

  while(1)
  {
    clientlen = sizeof(clientaddr);
    connfd = accept(listenfd, (void *)(&clientaddr), &clientlen);
    if (connfd == -1) {
      continue;
    }

    LOGSOCKOPT(logfile, LOG_LEVEL_L, connfd, SOL_SOCKET, SO_PRIORITY);
    LOGSOCKOPT(logfile, LOG_LEVEL_L, connfd, IPPROTO_TCP, TCP_NODELAY);
    LOGSOCKOPT(logfile, LOG_LEVEL_L, connfd, IPPROTO_TCP, TCP_QUICKACK);

    error = getnameinfo((struct sockaddr*)&clientaddr, clientlen, hostname, sizeof(hostname), NULL, 0, 0);
    if (error != 0) {
      close(connfd);
      continue;
    }
    error = getnameinfo((struct sockaddr*)&clientaddr, clientlen, hostaddr, sizeof(hostaddr), NULL, 0, NI_NUMERICHOST);

    port = ntohs(((struct sockaddr*)&clientaddr)->sa_family == AF_INET
         ? ((struct sockaddr_in*)&clientaddr)->sin_port
         : ((struct sockaddr_in6*)&clientaddr)->sin6_port);
    if (error) {
      LOGF(logfile, LOG_LEVEL_L, "connected to %s : %lu\n", hostname, port);
    } else {
      LOGF(logfile, LOG_LEVEL_L, "connected to %s (%s) : %lu\n", hostname, hostaddr, port);
    }

    if ((pid = fork()) == 0) {
      close(listenfd);
      respond(connfd, port, logfile, options.tcpquickack);
      LOGF(logfile, LOG_LEVEL_L, "server: closing connection to %s (%s) : %lu\n", hostname, hostaddr, port);
      if (logfile) {
        fclose(logfile);
      }
      close(connfd);
      exit(0);
    }
    ++total;
    close(connfd);
    if (pid > 0) {
      if (threaded && sem_post(&count) == -1) {
        fprintf(stderr, "Warning : Semaphore overflow, child processes may not be cleaned up\n");
      }
      LOGF(logfile, LOG_LEVEL_L, "server: forked to pid %d, connection accepted\n", pid);
    }
    if(pid == -1) {
      fprintf(stderr, "Error : Failed to fork, connection refused\n");
    }
  }
}
コード例 #15
0
ファイル: main.c プロジェクト: d3sre/edu_gol
int main(int argc, char *argv[]) {
  if(!optparse(argc, argv))
        abort();

  return 0;
}
コード例 #16
0
ファイル: optparse.cpp プロジェクト: chaosink/RGB-YUV
int optparse(struct optparse *options, const char *optstring)
{
    options->errmsg[0] = '\0';
    options->optopt = 0;
    options->optarg = 0;
    char *option = options->argv[options->optind];
    if (option == 0) {
        return -1;
    } else if (is_dashdash(option)) {
        options->optind++; /* consume "--" */
        return -1;
    } else if (!is_shortopt(option)) {
        if (options->permute) {
            int index = options->optind;
            options->optind++;
            int r = optparse(options, optstring);
            permute(options, index);
            options->optind--;
            return r;
        } else {
            return -1;
        }
    }
    option += options->subopt + 1;
    options->optopt = option[0];
    int type = argtype(optstring, option[0]);
    char *next = options->argv[options->optind + 1];
    switch (type) {
    case -1: {
        options->optind++;
        char str[2] = {option[0]};
        return opterror(options, MSG_INVALID, str);
    }
    case OPTPARSE_NONE:
        if (option[1]) {
            options->subopt++;
        } else {
            options->subopt = 0;
            options->optind++;
        }
        return option[0];
    case OPTPARSE_REQUIRED:
        options->subopt = 0;
        options->optind++;
        if (option[1]) {
            options->optarg = option + 1;
        } else if (next != 0) {
            options->optarg = next;
            options->optind++;
        } else {
            options->optarg = 0;
            char str[2] = {option[0]};
            return opterror(options, MSG_MISSING, str);
        }
        return option[0];
    case OPTPARSE_OPTIONAL:
        options->subopt = 0;
        options->optind++;
        if (option[1])
            options->optarg = option + 1;
        else
            options->optarg = 0;
        return option[0];
    }
    return 0;
}
コード例 #17
0
ファイル: main.c プロジェクト: samus250/random-c
int main(void)
{
	
	char first_range_string[128], second_range_string[128];
	char *endptr;

	welcome();
	
	for(;;){
	
	// first, lets clean up just in case
	memset(first_range_string,'\0',128);
	memset(second_range_string,'\0',128);
	first_range=second_range=prime_numbers=0;
	
	//! First Range
	
	printf("\n\nPlease enter the lowest range number: ");
	scanf("%s",&first_range_string);
	
	if(!strcasecmp("exit",first_range_string)) return 0;
	else if(first_range_string[0] == '-' && first_range_string[1] == '-')
	{
		optparse(&first_range_string[2]);
		continue;
	}
	
	if(first_range_string[0] == '-')
	{
		negative_input(); /*if the input is negative, show the error message*/
		continue; // you can see continue just like goto
	}
	
	first_range = strtoull(first_range_string,&endptr,0);
	
	if(*endptr == '.') /*if the user types a float number, show this message*/
		decimal_input(first_range, first_range_string);
	
	if((*endptr) && *endptr != '.')
	{
		only_numbers();
		continue;
	}

	//! Second Range
	
	printf("Please enter the highest range number: ");
	scanf("%s",&second_range_string);
	
	if(!strcasecmp("exit",second_range_string)) return(0);
	else if(first_range_string[0] == '-' && first_range_string[1] == '-')
	{
		optparse(&first_range_string[2]);
		continue;
	}
	
	if(second_range_string[0] == '-')
	{
		negative_input(); /*if the input is negative, show the error message*/
		continue;
	}
	
	second_range = strtoull(second_range_string,&endptr,0);
	
	if(*endptr == '.')
		decimal_input(second_range, second_range_string); /*if the user types a float number, show this message*/
	
	if((*endptr) && *endptr != '.')
	{
		only_numbers();
		continue;
	}
	
	//! Check Ranges
	
	if(first_range>=second_range) /*if the user types a bad range, show error message*/
	{	
		bad_ranges();
		continue;
	}
	
	//! End error check
	
	printf("\n");
	
	file_init();
	
	if(!options.progress)
		primegen();
	else
		primegen_prog();
	
	results();
	
	//! After Results Given
	
	printf("\nCheck the \"primes.txt\" file, Generated in the same Directory this Program is In.\n");
	
	} //! End for
	
	return 0;
}
コード例 #18
0
int main(int argc, char **argv)
{
	int ds, dms, ret, infected = 0, err = 0;
	struct timeval t1, t2;
	time_t starttime;
        struct optstruct *opts;
        const struct optstruct *opt;
#ifndef _WIN32
	struct sigaction sigact;
#endif

    if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMDSCAN, OPT_CLAMSCAN, NULL)) == NULL) {
	mprintf("!Can't parse command line options\n");
	return 2;
    }

    if((clamdopts = optparse(optget(opts, "config-file")->strarg, 0, NULL, 1, OPT_CLAMD, 0, NULL)) == NULL) {
	logg("!Can't parse clamd configuration file %s\n", optget(opts, "config-file")->strarg);
	return 2;
    }

    if(optget(opts, "verbose")->enabled) {
	mprintf_verbose = 1;
	logg_verbose = 1;
    }

    if(optget(opts, "quiet")->enabled)
	mprintf_quiet = 1;

    if(optget(opts, "stdout")->enabled)
	mprintf_stdout = 1;

    if(optget(opts, "version")->enabled) {
	print_server_version(opts);
	optfree(opts);
	optfree(clamdopts);
	exit(0);
    }

    if(optget(opts, "help")->enabled) {
	optfree(opts);
	optfree(clamdopts);
    	help();
    }

    if(optget(opts, "infected")->enabled)
	printinfected = 1;

    /* initialize logger */

    if((opt = optget(opts, "log"))->enabled) {
	logg_file = opt->strarg;
	if(logg("--------------------------------------\n")) {
	    mprintf("!Problem with internal logger.\n");
	    optfree(opts);
	    optfree(clamdopts);
	    exit(2);
	}
    } else 
	logg_file = NULL;


    if(optget(opts, "reload")->enabled) {
	ret = reload_clamd_database(opts);
	optfree(opts);
	optfree(clamdopts);
	logg_close();
	exit(ret);
    }

    if(actsetup(opts)) {
	optfree(opts);
	optfree(clamdopts);
	logg_close();
	exit(2);
    }

#ifndef _WIN32
    memset(&sigact, 0, sizeof(struct sigaction));
    sigact.sa_handler = SIG_IGN;
    sigemptyset(&sigact.sa_mask);
    sigaddset(&sigact.sa_mask, SIGPIPE);
    sigaction(SIGPIPE, &sigact, NULL);
#endif

    time(&starttime);
    /* ctime() does \n, but I need it once more */

    gettimeofday(&t1, NULL);

    ret = client(opts, &infected, &err);
    optfree(clamdopts);

    /* TODO: Implement STATUS in clamd */
    if(!optget(opts, "no-summary")->enabled) {
	gettimeofday(&t2, NULL);
	ds = t2.tv_sec - t1.tv_sec;
	dms = t2.tv_usec - t1.tv_usec;
	ds -= (dms < 0) ? (1):(0);
	dms += (dms < 0) ? (1000000):(0);
	logg("\n----------- SCAN SUMMARY -----------\n");
	logg("Infected files: %d\n", infected);
	if(err)
	    logg("Total errors: %d\n", err);
	if(notremoved) {
	    logg("Not removed: %d\n", notremoved);
	}
	if(notmoved) {
	    logg("Not moved: %d\n", notmoved);
	}
	logg("Time: %d.%3.3d sec (%d m %d s)\n", ds, dms/1000, ds/60, ds%60);
    }

    logg_close();
    optfree(opts);
    cl_cleanup_crypto();
    exit(ret);
}
コード例 #19
0
ファイル: viewssld.c プロジェクト: Jonnyliu/viewssld
int main(int argc, char *argv[], char *envp[])
{
	register int		i=0; // for counter
	int		rc = 0;
	char 	*logtitle;	// for syslog title
	pid_t	pid;

	// Initialization area
	config.loglevel = 0;
	config.daemon = 1;
	config.cmdl = 1;
	config.index = 0;

	strcpy(config.pidfilename, DEFAULT_PID_FILE);
	strcpy(config.imagefile, argv[0]);

	// Initialize buffers for errors
	*errbuf.common = '\0';
	*errbuf.libnet = '\0';
	capindex = 0;

	if ((rc = optparse(&config, argc, argv, envp)) != 0)
	switch (rc)
	{
		case -1:
			exit(EXIT_FAILURE);
		case 1:
			exit(EXIT_SUCCESS);
		default:
			exit(rc);
	}
	
	if (config.index == 0)
	{
		fprintf(stderr,"You must define all obligatory parameters in running arguments or in configuration file.\n");
		usage();
		exit(EXIT_FAILURE);
	}
	
	if (check_config(&config))
		exit (EXIT_FAILURE);
		
	if (config.loglevel > 0)
		print_config(&config);
		
	if (getuid() != 0)
	{
		fprintf(stderr, "%s, you must be root to run this program.\n", getlogin());
		exit (EXIT_FAILURE);
	}

	config.pidfile = fopen (config.pidfilename, "w");
	if (config.pidfile == NULL)
	{
		fprintf (stderr, "Error to create pid-file \"%s\".\n", config.pidfilename);
		fprintf (stderr, "Try %s -f <path>", config.imagefile);
		exit (EXIT_FAILURE);
	}

	if (config.daemon)
	{
		if (daemon(1,1) != 0)
		{
			fprintf(stderr,"Daemonize error, running in interactive mode.\n");
			config.daemon = 0;
		}
	}
	
	// Write PID to PID-file
	fprintf(config.pidfile, "%d\n", getpid());
	fclose(config.pidfile);

	atexit(before_exit);

	if (config.index > 1)
	{
		struct	sigaction sact;
		
		sact.sa_sigaction = SIGCHLD_act;
		sact.sa_flags = SA_RESTART | SA_NOMASK | SA_SIGINFO;
		sigaction(SIGCHLD, &sact, NULL);
	
		childs.index = 0;
		parent = 1;
		for (i=0; i<config.index; i++)
		{
			pid = fork();
			switch(pid)
			{
				case -1: // fork() error
					errorlog("ERROR: Can't exec fork().");
					break;

				case 0:	// in child
					logtitle = malloc((strlen(config.cap[i]->title)+24) * sizeof(char));
					parent = 0;
					capindex = i;
				
					sprintf(logtitle, "viewssl daemon child [%s]", config.cap[capindex]->title);

					openlog(logtitle, LOG_PID, LOG_DAEMON);
					syslog(LOG_NOTICE,"started at %s",gettime());
					break;

				default: // in parent
					childs.pid[childs.index] = pid;
					childs.title[childs.index] = malloc((strlen(config.cap[childs.index]->title)+1)*sizeof(char));
					strcpy(childs.title[childs.index],config.cap[childs.index]->title);
					childs.index++;
					break;
			} // switch(pid)

			if (!parent)
				break;
		} // for (i=0;i<config.index;i++)

		signal(SIGTERM, fsignal);
		signal(SIGINT, fsignal);
		signal(SIGQUIT, fsignal);


		if (parent)
		{ // in parent
			struct	sockaddr_un uds_addr;
			struct  sockaddr_un cl_addr;

			int		ss=0, r=0;	// master services socket

			// Master
			openlog("viewssl daemon master", LOG_PID, LOG_DAEMON);
			syslog(LOG_NOTICE, "started at %s", gettime());
			
			ss = socket(PF_UNIX, SOCK_STREAM, 0);
			if (ss < 0)
				errorlog("socket() error.");

			
			memset(&uds_addr, 0, sizeof(uds_addr));
			uds_addr.sun_family = AF_UNIX;
			strcpy(uds_addr.sun_path,SOCKPATH);
			
			unlink (SOCKPATH);
			
			r = bind(ss, (struct sockaddr *)&uds_addr, sizeof(uds_addr));
			if (r < 0)
				errorlog("bind() error.");
			
			r = listen(ss, 10);
			if (r < 0)
				errorlog("listen() error.");
			
			while(1)
			{
				int	cons=0;
				socklen_t cl_addr_len=0;

				memset (&cl_addr, 0, sizeof(cl_addr));
				cons = accept(ss, (struct sockaddr*) &cl_addr, &cl_addr_len);
				close(cons);
			}

			close(ss);
			unlink (SOCKPATH);
			exit(EXIT_SUCCESS);	// end master

		} else // child
		{
			signal(SIGCHLD, fsignal);
		}
		
	} // if (config.index > 1)
	else
	{ // one thread
		openlog("viewssl daemon", LOG_PID, LOG_DAEMON);
	}
	
	SSL_library_init();
	OpenSSL_add_all_ciphers();
	OpenSSL_add_all_digests();

	rc = proceed();

	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();

	if (rc != 0)
		exit(EXIT_FAILURE);
	else
		exit(EXIT_SUCCESS);	// end childs
}
コード例 #20
0
ファイル: bcrun.c プロジェクト: vrtadmin/clamav-devel
int main(int argc, char *argv[])
{
    FILE *f;
    struct cli_bc *bc;
    struct cli_bc_ctx *ctx;
    int rc, dbgargc, bc_stats=0;
    struct optstruct *opts;
    const struct optstruct *opt;
    unsigned funcid=0, i;
    struct cli_all_bc bcs;
    int fd = -1;
    unsigned tracelevel;

    if(check_flevel())
	exit(1);

    opts = optparse(NULL, argc, argv, 1, OPT_CLAMBC, 0, NULL);
    if (!opts) {
	fprintf(stderr, "ERROR: Can't parse command line options\n");
	exit(1);
    }
    if(optget(opts, "version")->enabled) {
	printf("Clam AntiVirus Bytecode Testing Tool %s\n", get_version());
	cl_init(CL_INIT_DEFAULT);
	cli_bytecode_printversion();
	optfree(opts);
	exit(0);
    }
    if(optget(opts, "help")->enabled || !opts->filename) {
	optfree(opts);
	help();
	exit(0);
    }
    f = fopen(opts->filename[0], "r");
    if (!f) {
	fprintf(stderr, "Unable to load %s\n", argv[1]);
	optfree(opts);
	exit(2);
    }

    bc = malloc(sizeof(*bc));
    if (!bc) {
	fprintf(stderr, "Out of memory\n");
	optfree(opts);
	exit(3);
    }

    if (optget(opts,"debug")->enabled) {
	cl_debug();
	debug_flag=1;
    }
    rc = cl_init(CL_INIT_DEFAULT);
    if (rc != CL_SUCCESS) {
	fprintf(stderr,"Unable to init libclamav: %s\n", cl_strerror(rc));
	optfree(opts);
	exit(4);
    }

    dbgargc=1;
    while (opts->filename[dbgargc]) dbgargc++;

    if (dbgargc > 1)
	cli_bytecode_debug(dbgargc, opts->filename);

    if (optget(opts, "force-interpreter")->enabled) {
	bcs.engine = NULL;
    } else {
	rc = cli_bytecode_init(&bcs);
	if (rc != CL_SUCCESS) {
	    fprintf(stderr,"Unable to init bytecode engine: %s\n", cl_strerror(rc));
	    optfree(opts);
	    exit(4);
	}
    }

    bcs.all_bcs = bc;
    bcs.count = 1;

    if((opt = optget(opts, "statistics"))->enabled) {
	while(opt) {
	    if (!strcasecmp(opt->strarg, "bytecode"))
		bc_stats=1;
	    opt = opt->nextarg;
        }
    }

    rc = cli_bytecode_load(bc, f, NULL, optget(opts, "trust-bytecode")->enabled, bc_stats);
    if (rc != CL_SUCCESS) {
	fprintf(stderr,"Unable to load bytecode: %s\n", cl_strerror(rc));
	optfree(opts);
	exit(4);
    }
    fclose(f);
    if (bc->state == bc_skip) {
	fprintf(stderr,"bytecode load skipped\n");
	exit(0);
    }
    if (debug_flag)
	printf("[clambc] Bytecode loaded\n");
    if (optget(opts, "info")->enabled) {
	cli_bytecode_describe(bc);
    } else if (optget(opts, "printsrc")->enabled) {
        print_src(opts->filename[0]);
    } else if (optget(opts, "printbcir")->enabled) {
        cli_bytetype_describe(bc);
        cli_bytevalue_describe(bc, 0);
        cli_bytefunc_describe(bc, 0);
    } else {
	cli_ctx cctx;
	struct cl_engine *engine = cl_engine_new();
	fmap_t *map = NULL;
	memset(&cctx, 0, sizeof(cctx));
	if (!engine) {
	    fprintf(stderr,"Unable to create engine\n");
	    optfree(opts);
	    exit(3);
	}
	rc = cl_engine_compile(engine);
	if (rc) {
	    fprintf(stderr,"Unable to compile engine: %s\n", cl_strerror(rc));
	    optfree(opts);
	    exit(4);
	}
	rc = cli_bytecode_prepare2(engine, &bcs, BYTECODE_ENGINE_MASK);
	if (rc != CL_SUCCESS) {
	    fprintf(stderr,"Unable to prepare bytecode: %s\n", cl_strerror(rc));
	    optfree(opts);
	    exit(4);
	}
	if (debug_flag)
	    printf("[clambc] Bytecode prepared\n");

	ctx = cli_bytecode_context_alloc();
	if (!ctx) {
	    fprintf(stderr,"Out of memory\n");
	    exit(3);
	}
	ctx->ctx = &cctx;
	cctx.engine = engine;
	cctx.fmap = cli_calloc(sizeof(fmap_t*), engine->maxreclevel+2);
	if (!cctx.fmap) {
	    fprintf(stderr,"Out of memory\n");
	    exit(3);
	}
	memset(&dbg_state, 0, sizeof(dbg_state));
	dbg_state.file = "<libclamav>";
	dbg_state.line = 0;
	dbg_state.col = 0;
	dbg_state.showline = !optget(opts, "no-trace-showsource")->enabled;
	tracelevel = optget(opts, "trace")->numarg;
	cli_bytecode_context_set_trace(ctx, tracelevel,
				       tracehook,
				       tracehook_op,
				       tracehook_val,
				       tracehook_ptr);

	if (opts->filename[1]) {
	    funcid = atoi(opts->filename[1]);
	}
	cli_bytecode_context_setfuncid(ctx, bc, funcid);
	if (debug_flag)
	    printf("[clambc] Running bytecode function :%u\n", funcid);

	if (opts->filename[1]) {
	    i=2;
	    while (opts->filename[i]) {
		rc = cli_bytecode_context_setparam_int(ctx, i-2, atoi(opts->filename[i]));
		if (rc != CL_SUCCESS) {
		    fprintf(stderr,"Unable to set param %u: %s\n", i-2, cl_strerror(rc));
		}
		i++;
	    }
	}

	if ((opt = optget(opts,"input"))->enabled) {
	    fd = open(opt->strarg, O_RDONLY);
	    if (fd == -1) {
		fprintf(stderr, "Unable to open input file %s: %s\n", opt->strarg, strerror(errno));
		optfree(opts);
		exit(5);
	    }
	    map = fmap(fd, 0, 0);
	    if (!map) {
		fprintf(stderr, "Unable to map input file %s\n", opt->strarg);
		exit(5);
	    }
	    rc = cli_bytecode_context_setfile(ctx, map);
	    if (rc != CL_SUCCESS) {
		fprintf(stderr, "Unable to set file %s: %s\n", opt->strarg, cl_strerror(rc));
		optfree(opts);
		exit(5);
	    }
	}
	/* for testing */
	ctx->hooks.match_counts = deadbeefcounts;
	ctx->hooks.match_offsets = deadbeefcounts;
	rc = cli_bytecode_run(&bcs, bc, ctx);
	if (rc != CL_SUCCESS) {
	    fprintf(stderr,"Unable to run bytecode: %s\n", cl_strerror(rc));
	} else {
	    uint64_t v;
	    if (debug_flag)
		printf("[clambc] Bytecode run finished\n");
	    v = cli_bytecode_context_getresult_int(ctx);
	    if (debug_flag)
		printf("[clambc] Bytecode returned: 0x%llx\n", (long long)v);
	}
	cli_bytecode_context_destroy(ctx);
	if (map)
	    funmap(map);
	cl_engine_free(engine);
	free(cctx.fmap);
    }
    cli_bytecode_destroy(bc);
    cli_bytecode_done(&bcs);
    free(bc);
    optfree(opts);
    if (fd != -1)
	close(fd);
    if (debug_flag)
	printf("[clambc] Exiting\n");
    cl_cleanup_crypto();
    return 0;
}
コード例 #21
0
ファイル: clamscan.c プロジェクト: OPSF/uClinux
int main(int argc, char **argv)
{
	int ds, dms, ret;
	double mb, rmb;
	struct timeval t1, t2;
#ifndef C_WINDOWS
	struct timezone tz;
	sigset_t sigset;
#endif
	struct optstruct *opts;
	const struct optstruct *opt;

#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
    if(!pthread_win32_process_attach_np()) {
	mprintf("!Can't start the win32 pthreads layer\n");
	return 72;
    }
#endif

#if !defined(C_WINDOWS) && !defined(C_BEOS)
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGXFSZ);
    sigprocmask(SIG_SETMASK, &sigset, NULL);
#endif


    if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMSCAN, 0, NULL)) == NULL) {
	mprintf("!Can't parse command line options\n");
	return 40;
    }

    if(optget(opts, "verbose")->enabled) {
	mprintf_verbose = 1;
	logg_verbose = 1;
    }

    if(optget(opts, "quiet")->enabled)
	mprintf_quiet = 1;

    if(optget(opts, "stdout")->enabled)
	mprintf_stdout = 1;


    if(optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
	    /* [email protected]: create a dump if needed */
	    struct rlimit rlim;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
	    perror("setrlimit");
#endif
	cl_debug(); /* enable debug messages */
    }

    if(optget(opts, "version")->enabled) {
	print_version(optget(opts, "database")->strarg);
	optfree(opts);
	return 0;
    }

    if(optget(opts, "help")->enabled) {
	optfree(opts);
    	help();
	return 0;
    }

    if(optget(opts, "recursive")->enabled)
	recursion = 1;

    if(optget(opts, "infected")->enabled)
	printinfected = 1;

    if(optget(opts, "bell")->enabled)
	bell = 1;

    /* initialize logger */
    if((opt = optget(opts, "log"))->enabled) {
	logg_file = opt->strarg;
	if(logg("#\n-------------------------------------------------------------------------------\n\n")) {
	    mprintf("!Problem with internal logger.\n");
	    optfree(opts);
	    return 62;
	}
    } else 
	logg_file = NULL;

    if(actsetup(opts)) {
	optfree(opts);
	logg_close();
	exit(2);
    }

    memset(&info, 0, sizeof(struct s_info));

#ifdef C_WINDOWS
    _set_fmode(_O_BINARY);
#ifdef CL_DEBUG
    {
	_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
	_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
    }
#endif	
    gettimeofday(&t1, NULL);
#else
    gettimeofday(&t1, &tz);
#endif

    ret = scanmanager(opts);

    if(!optget(opts, "no-summary")->enabled) {
#ifdef C_WINDOWS
	gettimeofday(&t2, NULL);
#else
	gettimeofday(&t2, &tz);
#endif
	ds = t2.tv_sec - t1.tv_sec;
	dms = t2.tv_usec - t1.tv_usec;
	ds -= (dms < 0) ? (1):(0);
	dms += (dms < 0) ? (1000000):(0);
	logg("\n----------- SCAN SUMMARY -----------\n");
	logg("Known viruses: %u\n", info.sigs);
	logg("Engine version: %s\n", get_version());
	logg("Scanned directories: %u\n", info.dirs);
	logg("Scanned files: %u\n", info.files);
	logg("Infected files: %u\n", info.ifiles);
	if(notremoved) {
	    logg("Not removed: %u\n", notremoved);
	}
	if(notmoved) {
	    logg("Not %s: %u\n", optget(opts, "copy")->enabled ? "moved" : "copied", notmoved);
	}
	mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
	logg("Data scanned: %2.2lf MB\n", mb);
	rmb = info.rblocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
	logg("Data read: %2.2lf MB (ratio %.2f:1)\n", rmb, info.rblocks ? (double)info.blocks/(double)info.rblocks : 0);
	logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms/1000, ds/60, ds%60);
    }

    optfree(opts);

#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
    if(!pthread_win32_process_detach_np()) {
	logg("!Can't stop the win32 pthreads layer\n");
	return 72;
    }
#endif

    return ret;
}
コード例 #22
0
int main(int argc, char **argv)
{
	int ds, dms, ret;
	double mb, rmb;
	struct timeval t1, t2;
#ifndef _WIN32
	sigset_t sigset;
#endif
	struct optstruct *opts;
	const struct optstruct *opt;

    if(check_flevel())
	exit(2);

#if !defined(_WIN32) && !defined(C_BEOS)
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGXFSZ);
    sigprocmask(SIG_SETMASK, &sigset, NULL);
#endif

    cl_initialize_crypto();


    if((opts = optparse(NULL, argc, argv, 1, OPT_CLAMSCAN, 0, NULL)) == NULL) {
	mprintf("!Can't parse command line options\n");
	return 2;
    }

    if(optget(opts, "verbose")->enabled) {
	mprintf_verbose = 1;
	logg_verbose = 1;
    }

    if(optget(opts, "quiet")->enabled)
	mprintf_quiet = 1;

    if(optget(opts, "stdout")->enabled)
	mprintf_stdout = 1;


    if(optget(opts, "debug")->enabled) {
#if defined(C_LINUX)
	    /* [email protected]: create a dump if needed */
	    struct rlimit rlim;

	rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
	if(setrlimit(RLIMIT_CORE, &rlim) < 0)
	    perror("setrlimit");
#endif
	cl_debug(); /* enable debug messages */
    }

    if (optget(opts, "gen-mdb")->enabled) {
        cl_always_gen_section_hash();
    }

    if(optget(opts, "version")->enabled) {
	print_version(optget(opts, "database")->strarg);
	optfree(opts);
	return 0;
    }

    if(optget(opts, "help")->enabled) {
	optfree(opts);
    	help();
	return 0;
    }

    if(optget(opts, "recursive")->enabled)
	recursion = 1;

    if(optget(opts, "infected")->enabled)
	printinfected = 1;

    if(optget(opts, "suppress-ok-results")->enabled)
	printclean = 0;

    if(optget(opts, "bell")->enabled)
	bell = 1;

    /* initialize logger */
    if((opt = optget(opts, "log"))->enabled) {
	logg_file = opt->strarg;
	if(logg("#\n-------------------------------------------------------------------------------\n\n")) {
	    mprintf("!Problem with internal logger.\n");
	    optfree(opts);
	    return 2;
	}
    } else 
	logg_file = NULL;

    if(actsetup(opts)) {
	optfree(opts);
	logg_close();
	exit(2);
    }

    memset(&info, 0, sizeof(struct s_info));

    gettimeofday(&t1, NULL);

    ret = scanmanager(opts);

    if(!optget(opts, "no-summary")->enabled) {
	gettimeofday(&t2, NULL);

    ds = t2.tv_sec - t1.tv_sec;
	dms = t2.tv_usec - t1.tv_usec;
	ds -= (dms < 0) ? (1):(0);
	dms += (dms < 0) ? (1000000):(0);
	logg("\n----------- SCAN SUMMARY -----------\n");
	logg("Known viruses: %u\n", info.sigs);
	logg("Engine version: %s\n", get_version());
	logg("Scanned directories: %u\n", info.dirs);
	logg("Scanned files: %u\n", info.files);
	logg("Infected files: %u\n", info.ifiles);
	if(info.errors)
	    logg("Total errors: %u\n", info.errors);
	if(notremoved) {
	    logg("Not removed: %u\n", notremoved);
	}
	if(notmoved) {
	    logg("Not %s: %u\n", optget(opts, "copy")->enabled ? "moved" : "copied", notmoved);
	}
	mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
	logg("Data scanned: %2.2lf MB\n", mb);
	rmb = info.rblocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
	logg("Data read: %2.2lf MB (ratio %.2f:1)\n", rmb, info.rblocks ? (double)info.blocks/(double)info.rblocks : 0);
	logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms/1000, ds/60, ds%60);
    }

    optfree(opts);

    cl_cleanup_crypto();

    return ret;
}
コード例 #23
0
ファイル: friidump.c プロジェクト: MauPlay/friidump
int main (int argc, char *argv[]) {
	disc *d;
	progstats stats;
	double duration;
	suseconds_t us;
	int out, ret;
	unscrambler *u;
	unscrambler_progress_func pfunc;
	u_int32_t current_sector;

	/* First of all... */
	drop_euid ();
	
	welcome ();

	d = NULL;
	out = false;
	if (optparse (argc, argv)) {
		if (options.device) {
			/* Dump DVD to file */
			fprintf (stderr, "Initializing DVD drive... ");

			if (!(d = disc_new (options.device, options.command))) {
				fprintf (stderr, "Failed\n");
#ifndef WIN32
				fprintf (stderr,
					"Probably you do not have access to the DVD device. Ask the administrator\n"
					"to add you to the proper group, or use 'sudo'.\n"
				);
#endif
			} else {
			fprintf (stderr, "OK\n");
			
				if(options.allmethods)
				{
					fprintf (stderr, "Trying all methods... This will take a LOOOONG time and generate an insanely long console output :p\n");
					for(options.command=0;options.command<=4;options.command++)
					{
						for(options.dump_method=0;options.dump_method<=9;options.dump_method++)
						{
							fprintf (stderr, "Trying with command %d, method %d\n", options.command, options.dump_method);
							out = dologic(d, stats);
							if(out==true)
							{
								break;
							}
						}
						if(out==true)
						{
							fprintf (stderr, "Command %d and method %d combination worked!\n", options.command, options.dump_method);
							break;
						}
					}
				} else {
					out = dologic(d, stats);
				}	
				
				d = disc_destroy (d);
			}
		} else if (options.raw_in) {
			/* Convert raw image to ISO format */
			u = unscrambler_new ();
			
			if (options.gui)
				pfunc = (unscrambler_progress_func) progress_for_guis;
			else
				pfunc = (unscrambler_progress_func) progress;

			if ((out = unscrambler_unscramble_file (u, options.raw_in, options.iso_out, pfunc, &stats, &current_sector)))
				fprintf (stderr, "Unscrambling completed successfully!\n");
			else
				fprintf (stderr, "\nUnscrambling failed at sectors: %u..%u\n", current_sector, current_sector+15);

			u = unscrambler_destroy (u);
		} else {
			MY_ASSERT (0);
		}

		if (out) {
			duration = stats.end_time.tv_sec - stats.start_time.tv_sec;
			if (stats.end_time.tv_usec >= stats.start_time.tv_usec) {
				us = stats.end_time.tv_usec - stats.start_time.tv_usec;
			} else {
				if (duration > 0)
					duration--;
				us = USECS_PER_SEC + stats.end_time.tv_usec - stats.start_time.tv_usec;
			}
			duration += ((double) us / (double) USECS_PER_SEC);
			if (duration < 0)
				duration = 0;
			fprintf (stderr, "Operation took %.2f seconds\n", duration);

			ret = EXIT_SUCCESS;
		} else {
			ret = EXIT_FAILURE;
		}
		
		my_free (options.device);
		my_free (options.iso_out);
		my_free (options.raw_out);
		my_free (options.raw_in);
	}

	return (out);
}