int Init(void *_ctx) { int n; ctx = _ctx; moddebug("enter ts=%d\n",oesr_tstamp(ctx)); if (!mem_ok) { init_memory(); mem_ok = 1; } if (!log_ok) { mlog = NULL; if (USE_LOG) { if (init_log(ctx)) { return -1; } } log_ok = 1; } if (!check_ok) { if (check_configuration(ctx)) { return -1; } check_ok = 1; } if (init_variables(ctx)) { return -1; } if (init_counter(ctx)) { return -1; } moddebug("calling initialize, ts=%d\n",oesr_tstamp(ctx)); /* this is the module initialize function */ if (initialize()) { moddebug("error initializing module\n",oesr_tstamp(ctx)); return -1; } n = init_interfaces(ctx); if (n == -1) { return -1; } else if (n == 0) { return 0; } moddebug("exit ts=%d\n",oesr_tstamp(ctx)); return 1; }
int main(int argc, char** argv) { int ret = 0; parse_command_line(argc, argv); if (arg_check_config) { return check_configuration(arg_dump_config); } #ifndef WIN32 if (arg_fork) { ret = fork(); if (ret == -1) { LOG_FATAL("Unable to fork to background!"); return -1; } else if (ret == 0) { /* child process - detatch from TTY */ fclose(stdin); fclose(stdout); fclose(stderr); close(0); close(1); close(2); } else { /* parent process */ LOG_DEBUG("Forked to background\n"); return 0; } } if (pidfile_create() == -1) return -1; if (drop_privileges() == -1) return -1; #endif /* WIN32 */ ret = main_loop(); #ifndef WIN32 pidfile_destroy(); #endif return ret; }
/** Init the filesystem, retriving contents from Item Manager @param conn Unused */ static void* ifs_init (struct fuse_conn_info *conn) { check_configuration (); /* User parameters are directly embedded in the hierarchy tree (cfr. parse_reference_formula()), so we can destroy the table at the end of the configuration file parsing */ set_user_param (NULL, NULL); return NULL; }
int main( int argc, char *argv[] ) { signed char c; const char *progname = "wavefront"; debug_config(progname); progress_log_file = stdout; struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, {"debug", required_argument, 0, 'd'}, {"jobs", required_argument, 0, 'n'}, {"block-size", required_argument, 0, 'b'}, {"debug-file", required_argument, 0, 'o'}, {"log-file", required_argument, 0, 'l'}, {"bitmap", required_argument, 0, 'B'}, {"bitmap-interval", required_argument, 0, 'i'}, {"auto", no_argument, 0, 'A'}, {"local", no_argument, 0, 'L'}, {"batch-type", required_argument, 0, 'T'}, {"verify", no_argument, 0, 'V'}, {0,0,0,0} }; while((c=getopt_long(argc,argv,"n:b:d:o:l:B:i:qALDT:VX:Y:vh", long_options, NULL)) > -1) { switch(c) { case 'n': manual_max_jobs_running = atoi(optarg); break; case 'b': manual_block_size = atoi(optarg); break; case 'd': debug_flags_set(optarg); break; case 'o': debug_config_file(optarg); break; case 'B': progress_bitmap_file = optarg; break; case 'i': progress_bitmap_interval = atoi(optarg); break; case 'l': progress_log_file = fopen(optarg,"w"); if(!progress_log_file) { fprintf(stderr,"couldn't open %s: %s\n",optarg,strerror(errno)); return 1; } break; case 'A': wavefront_mode = WAVEFRONT_MODE_AUTO; break; case 'L': wavefront_mode = WAVEFRONT_MODE_MULTICORE; break; case 'T': wavefront_mode = WAVEFRONT_MODE_DISTRIBUTED; batch_system_type = batch_queue_type_from_string(optarg); if(batch_system_type==BATCH_QUEUE_TYPE_UNKNOWN) { fprintf(stderr,"unknown batch system type: %s\n",optarg); exit(1); } break; case 'V': verify_mode = 1; break; case 'X': xstart = atoi(optarg); break; case 'Y': ystart = atoi(optarg); break; case 'v': cctools_version_print(stdout, progname); exit(0); break; case 'h': show_help(progname); exit(0); break; } } cctools_version_debug(D_DEBUG, argv[0]); if( (argc-optind<3) ) { show_help(progname); exit(1); } function = argv[optind]; xsize=atoi(argv[optind+1]); ysize=atoi(argv[optind+2]); total_cells = xsize*ysize; if(!verify_mode && !check_configuration(function,xsize,ysize)) exit(1); int ncpus = load_average_get_cpus(); if(wavefront_mode!=WAVEFRONT_MODE_MULTICORE) { double task_time = measure_task_time(); printf("Each function takes %.02lfs to run.\n",task_time); block_size = find_best_block_size(xsize,1000,2,task_time,average_dispatch_time); double distributed_time = wavefront_distributed_model(xsize,1000,2,task_time,block_size,average_dispatch_time); double multicore_time = wavefront_multicore_model(xsize,ncpus,task_time); double ideal_multicore_time = wavefront_multicore_model(xsize,xsize,task_time); double sequential_time = wavefront_multicore_model(xsize,1,task_time); printf("---------------------------------\n"); printf("This workload would take:\n"); printf("%.02lfs sequentially\n",sequential_time); printf("%.02lfs on this %d-core machine\n",multicore_time,ncpus); printf("%.02lfs on a %d-core machine\n",ideal_multicore_time,xsize); printf("%.02lfs on a 1000-node distributed system with block size %d\n",distributed_time,block_size); printf("---------------------------------\n"); if(wavefront_mode==WAVEFRONT_MODE_AUTO) { if(multicore_time < distributed_time*2) { wavefront_mode = WAVEFRONT_MODE_MULTICORE; } else { wavefront_mode = WAVEFRONT_MODE_DISTRIBUTED; } } } if(wavefront_mode==WAVEFRONT_MODE_MULTICORE) { batch_system_type = BATCH_QUEUE_TYPE_LOCAL; max_jobs_running = ncpus; } else { max_jobs_running = 1000; } if(manual_block_size!=0) { block_size = manual_block_size; } if(manual_max_jobs_running!=0) { max_jobs_running = manual_max_jobs_running; } if(wavefront_mode==WAVEFRONT_MODE_MULTICORE) { printf("Running in multicore mode with %d CPUs.\n",max_jobs_running); } else { printf("Running in distributed mode with block size %d on up to %d CPUs\n",block_size,max_jobs_running); } batch_q = batch_queue_create(batch_system_type); if(verify_mode) exit(0); struct bitmap * b = bitmap_create(xsize+1,ysize+1); struct list *ready_list = list_create(); struct itable *running_table = itable_create(0); struct batch_job_info info; UINT64_T jobid; struct wavefront_task *task; wavefront_task_initialize(b,ready_list); printf("Starting workload...\n"); fprintf(progress_log_file,"# elapsed time : waiting jobs / running jobs / cells complete (percent complete)\n"); while(1) { if(abort_mode) { while((task=list_pop_tail(ready_list))) { wavefront_task_delete(task); } itable_firstkey(running_table); while(itable_nextkey(running_table,&jobid,(void**)&task)) { batch_job_remove(batch_q,jobid); } } if(list_size(ready_list)==0 && itable_size(running_table)==0) break; while(1) { if(itable_size(running_table)>=max_jobs_running) break; task = list_pop_tail(ready_list); if(!task) break; jobid = wavefront_task_submit(task); if(jobid>0) { itable_insert(running_table,jobid,task); wavefront_task_mark_range(task,b,WAVEFRONT_TASK_STATE_RUNNING); } else { abort(); sleep(1); list_push_head(ready_list,task); } } save_status(b,ready_list,running_table); jobid = batch_job_wait(batch_q,&info); if(jobid>0) { task = itable_remove(running_table,jobid); if(task) { if(info.exited_normally && info.exit_code==0) { total_dispatch_time += info.started-info.submitted; total_execute_time += MAX(info.finished-info.started,1); total_cells_complete+=task->width*task->height; total_jobs_complete++; average_dispatch_time = 1.0*total_dispatch_time / total_jobs_complete; average_task_time = 1.0*total_execute_time / total_cells_complete; wavefront_task_complete(b,ready_list,task); } else { printf("job %" PRIu64 " failed, aborting this workload\n",jobid); abort_mode = 1; } } } } save_status(b,ready_list,running_table); if(abort_mode) { printf("Workload was aborted.\n"); } else { printf("Workload complete.\n"); } return 0; }
int main(int argc, char *argv[]) { char *configuration = NULL; char *infile = NULL; char *outfile = NULL; char *verbose = NULL; int version_opt = 0; char *logdir = NULL; char *logfile = NULL; char *home = NULL; int help_opt = 0; int c; static struct option long_options[] = { {"configuration", required_argument, 0, 'c'}, {"silent", no_argument, 0, 1}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"logdir", required_argument, 0, 'l'}, {"logfile", required_argument, 0, 'L'}, {"home", required_argument, 0, 2}, {"infile", required_argument, 0, 'i'}, {"outfile", required_argument, 0, 'o'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; #ifdef XCP int is_bash_exist = system("command -v bash"); if ( is_bash_exist != 0 ) { fprintf(stderr, "Cannot find bash. Please ensure that bash is " "installed and available in the PATH\n"); exit(2); } #endif strcpy(progname, argv[0]); init_var_hash(); while(1) { int option_index = 0; c = getopt_long(argc, argv, "i:o:c:vVl:L:h", long_options, &option_index); if (c == -1) break; switch(c) { case 1: verbose = "n"; break; case 2: if (home) free (home); home = strdup(optarg); break; case 'i': if (infile) free(infile); infile = strdup(optarg); break; case 'o': if (outfile) free(outfile); outfile = strdup(optarg); break; case 'v': verbose = "y"; break; case 'V': version_opt = 1; break; case 'l': if (logdir) free(logdir); logdir = strdup(optarg); break; case 'L': if (logfile) free(logfile); logfile = strdup(optarg); break; case 'c': if (configuration) free(configuration); configuration = strdup(optarg); break; case 'h': help_opt = 1; break; default: fprintf(stderr, "Invalid optin value, received code 0%o\n", c); exit(1); } } if (version_opt || help_opt) { if (version_opt) print_version(); if (help_opt) print_help(); exit(0); } setup_my_env(); /* Read $HOME/.pgxc_ctl */ build_pgxc_ctl_home(home); if (infile) reset_var_val(VAR_configFile, infile); if (logdir) reset_var_val(VAR_logDir, logdir); if (logfile) reset_var_val(VAR_logFile, logfile); startLog(sval(VAR_logDir), sval(VAR_logFile)); prepare_pgxc_ctl_bash(pgxc_ctl_bash_path); build_configuration_path(configuration); read_configuration(); check_configuration(); /* * Setop output */ if (outfile) { elog(INFO, "Output file: %s\n", outfile); if ((outF = fopen(outfile, "w"))) dup2(fileno(outF),2); else elog(ERROR, "ERROR: Cannot open output file %s, %s\n", outfile, strerror(errno)); } else outF = stdout; /* * Startup Message */ elog(NOTICE, " ******** PGXC_CTL START ***************\n\n"); elog(NOTICE, "Current directory: %s\n", pgxc_ctl_home); /* * Setup input */ if (infile) { elog(INFO, "Input file: %s\n", infile); inF = fopen(infile, "r"); if(inF == NULL) { elog(ERROR, "ERROR: Cannot open input file %s, %s\n", infile, strerror(errno)); exit(1); } } else inF = stdin; /* * If we have remaing arguments, they will be treated as a command to do. Do this * first, then handle the input from input file specified by -i option. * If it is not found, then exit. */ #if 0 print_vars(); #endif if (optind < argc) { char orgBuf[MAXLINE + 1]; char wkBuf[MAXLINE + 1]; orgBuf[0] = 0; while (optind < argc) { strncat(orgBuf, argv[optind++], MAXLINE); strncat(orgBuf, " ", MAXLINE); } strncpy(wkBuf, orgBuf, MAXLINE); do_singleLine(orgBuf, wkBuf); if (infile) do_command(inF, outF); } else do_command(inF, outF); exit(0); }
int main ( int argc, char* argv[] ) { char *distroname = NULL; int valid_args , c; while (1) { int option_index = 0; c = getopt_long_only( argc , argv , "d:" , long_options , &option_index ); if (c == -1) break; switch (c) { case 'd': distroname = malloc( strlen(optarg) * sizeof(char) ); strcpy( distroname , optarg ); break; } } valid_args = argc - ( optind - 1 ); if ( valid_args < 2 ) { print_usage( argv[0] ); exit(1); } if ( strcmp( argv[optind] , "register" ) == 0 ) { if ( valid_args != 4 ) { printf( "Usage register\n" ); exit(1); } } if ( strcmp( argv[optind] , "login" ) == 0 ) { if ( valid_args != 2 ) { printf( "Usage login\n" ); exit(1); } } if ( strcmp( argv[optind] , "loginout" ) == 0 ) { if ( valid_args != 3 ) { printf( "Usage logout\n" ); exit(1); } } // TODO : Use a define instead of 256 AMEBA_SESSID_MAX_LENGTH char *sessid = malloc( 256 * sizeof(char) ); memset( sessid , '\0' , 256 ); if ( strncmp( argv[optind] , "login" , 5 ) == 0 ) { GKeyFile *config = get_configuration(); if ( ! check_configuration( config , 1 ) ) { printf("No valid configuration exists\n"); free_configuration( config ); exit(2); } login_node( get_configuration_value( config , "url" ) , get_configuration_value( config , "uuid" ) , sessid ); free_configuration( config ); } if ( strcmp( argv[optind] , "loginout" ) == 0 ) { GKeyFile *config = get_configuration(); if ( ! check_configuration( config , 1 ) ) { printf("No valid configuration exists\n"); free_configuration( config ); exit(2); } logout_node( get_configuration_value( config , "url" ) , sessid , argv[optind+1] ); free_configuration( config ); } if ( strcmp( argv[optind] , "register" ) == 0 ) { nodeinfo *nodedata = get_nodeinfo( argv[optind+2] , distroname ); if ( ! nodedata ) { exit(-255); } register_node( argv[optind+1] , nodedata ); free_nodeinfo( nodedata ); } free(sessid); exit(0); }
void *process_connection(void *ptr) { char *server_ident = _ds_read_attribute(agent_config, "ServerIdent"); THREAD_CTX *TTX = (THREAD_CTX *) ptr; AGENT_CTX *ATX = NULL; char *input, *cmdline = NULL, *token, *ptrptr; buffer *message = NULL; char *parms=NULL, *p=NULL; int i, locked = -1, invalid = 0; int server_mode = SSM_DSPAM; char *argv[64]; char buf[1024]; int tries = 0; int argc = 0; FILE *fd = 0; if (_ds_read_attribute(agent_config, "ServerMode") && !strcasecmp(_ds_read_attribute(agent_config, "ServerMode"), "standard")) { server_mode = SSM_STANDARD; } if (_ds_read_attribute(agent_config, "ServerMode") && !strcasecmp(_ds_read_attribute(agent_config, "ServerMode"), "auto")) { server_mode = SSM_AUTO; } /* Initialize a file descriptor hook for dspam to use as stdout */ fd = fdopen(TTX->sockfd, "w"); if (!fd) { close(TTX->sockfd); goto CLOSE; } setbuf(fd, NULL); TTX->packet_buffer = buffer_create(NULL); if (TTX->packet_buffer == NULL) goto CLOSE; /* * Send greeting banner * in auto mode, we want to look like a regular LMTP server so we don't * cause any compatibility problems. in dspam mode, we can change this. */ snprintf(buf, sizeof(buf), "%d DSPAM %sLMTP %s %s", LMTP_GREETING, (server_mode == SSM_DSPAM) ? "D" : "", VERSION, (server_mode == SSM_DSPAM) ? "Authentication Required" : "Ready"); if (send_socket(TTX, buf)<=0) goto CLOSE; TTX->authenticated = 0; /* LHLO */ input = daemon_expect(TTX, "LHLO"); if (input == NULL) goto CLOSE; if (server_mode == SSM_AUTO && input[4]) { char buff[128]; /* * Auto-detect the server mode based on whether or not the ident is * assigned a password in dspam.conf */ snprintf(buff, sizeof(buff), "ServerPass.%s", input + 5); chomp(buff); if (_ds_read_attribute(agent_config, buff)) server_mode = SSM_DSPAM; else server_mode = SSM_STANDARD; } free(input); /* Advertise extensions */ if (daemon_extension(TTX, (server_ident) ? server_ident : "localhost.localdomain")<=0) goto CLOSE; if (daemon_extension(TTX, "PIPELINING")<=0) goto CLOSE; if (daemon_extension(TTX, "ENHANCEDSTATUSCODES")<=0) goto CLOSE; if (server_mode == SSM_DSPAM) if (daemon_extension(TTX, "DSPAMPROCESSMODE")<=0) goto CLOSE; if (daemon_extension(TTX, "8BITMIME")<=0) goto CLOSE; if (daemon_reply(TTX, LMTP_OK, "", "SIZE")<=0) goto CLOSE; /* Main protocol loop */ while(1) { char processmode[256]; parms = NULL; /* Configure a new agent context for each pass */ ATX = calloc(1, sizeof(AGENT_CTX)); if (ATX == NULL) { LOG(LOG_CRIT, ERR_MEM_ALLOC); daemon_reply(TTX, LMTP_TEMP_FAIL, "4.3.0", ERR_MEM_ALLOC); goto CLOSE; } if (initialize_atx(ATX)) { LOG(LOG_ERR, ERR_AGENT_INIT_ATX); daemon_reply(TTX, LMTP_BAD_CMD, "5.3.0", ERR_AGENT_INIT_ATX); goto CLOSE; } /* MAIL FROM (and authentication, if SSM_DSPAM) */ processmode[0] = 0; while(!TTX->authenticated) { input = daemon_expect(TTX, "MAIL FROM"); if (RSET(input)) goto RSET; if (input == NULL) goto CLOSE; else { char *pass, *ident; chomp(input); if (server_mode == SSM_STANDARD) { TTX->authenticated = 1; ATX->mailfrom[0] = 0; _ds_extract_address(ATX->mailfrom, input, sizeof(ATX->mailfrom)); if (daemon_reply(TTX, LMTP_OK, "2.1.0", "OK")<=0) { free(input); goto CLOSE; } } else { char id[256]; pass = ident = NULL; id[0] = 0; if (!_ds_extract_address(id, input, sizeof(id))) { pass = strtok_r(id, "@", &ptrptr); ident = strtok_r(NULL, "@", &ptrptr); } if (pass && ident) { char *serverpass; char *ptr, *ptr2, *ptr3; snprintf(buf, sizeof(buf), "ServerPass.%s", ident); serverpass = _ds_read_attribute(agent_config, buf); snprintf(buf, sizeof(buf), "ServerPass.%s", ident); if (serverpass && !strcmp(pass, serverpass)) { TTX->authenticated = 1; /* Parse PROCESSMODE service tag */ ptr = strstr(input, "DSPAMPROCESSMODE=\""); if (ptr) { char *mode; int i; ptr2 = strchr(ptr, '"')+1; mode = ptr2; while((ptr3 = strstr(ptr2, "\\\""))) ptr2 = ptr3+2; ptr3 = strchr(ptr2+2, '"'); if (ptr3) ptr3[0] = 0; strlcpy(processmode, mode, sizeof(processmode)); ptr = processmode; for(i=0; ptr[i]; i++) { if (ptr[i] == '\\' && ptr[i+1] == '"') { strcpy(ptr+i, ptr+i+1); } } LOGDEBUG("process mode: '%s'", processmode); } if (daemon_reply(TTX, LMTP_OK, "2.1.0", "OK")<=0) { free(input); goto CLOSE; } } } } free(input); if (!TTX->authenticated) { LOGDEBUG("fd %d authentication failure.", TTX->sockfd); if (daemon_reply(TTX, LMTP_AUTH_ERROR, "5.1.0", "Authentication Required")<=0) { free(input); goto CLOSE; } tries++; if (tries>=3) { struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; select(0, NULL, NULL, NULL, &tv); goto CLOSE; } } } } /* MAIL FROM response */ snprintf(buf, sizeof(buf), "%d OK", LMTP_OK); argc = 1; argv[0] = "dspam"; argv[1] = 0; /* Load open-LMTP configuration parameters */ if (server_mode == SSM_STANDARD) { parms = _ds_read_attribute(agent_config, "ServerParameters"); if (parms) { p = strdup(parms); if (p) { token = strtok_r(p, " ", &ptrptr); while(token != NULL && argc<63) { argv[argc] = token; argc++; argv[argc] = 0; token = strtok_r(NULL, " ", &ptrptr); } } } } /* RCPT TO */ while(ATX->users->items == 0 || invalid) { free(cmdline); cmdline = daemon_getline(TTX, 300); while(cmdline && (!strncasecmp(cmdline, "RCPT TO:", 8) || !strncasecmp(cmdline, "RSET", 4))) { char username[256]; char *at = NULL; if (!strncasecmp(cmdline, "RSET", 4)) { snprintf(buf, sizeof(buf), "%d OK", LMTP_OK); if (send_socket(TTX, buf)<=0) goto CLOSE; goto RSET; } if (_ds_extract_address(username, cmdline, sizeof(username)) || username[0] == 0 || username[0] == '-' || username[0] == '@') { if ((server_mode == SSM_DSPAM) || (server_mode == SSM_STANDARD && _ds_validate_address(username) == 0)) { daemon_reply(TTX, LMTP_BAD_CMD, "5.1.2", ERR_LMTP_BAD_RCPT); goto GETCMD; } } if (_ds_match_attribute(agent_config, "Broken", "case")) lc(username, username); /* Chop of @.* from the recipient */ if (_ds_match_attribute(agent_config, "StripRcptDomain", "on")) { at = strchr(username, '@'); if (at != NULL) *at = '\0'; } if (server_mode == SSM_DSPAM) { nt_add(ATX->users, username); } else { if (!parms || !strstr(parms, "--user ")) nt_add(ATX->users, username); if (!ATX->recipients) { ATX->recipients = nt_create(NT_CHAR); if (ATX->recipients == NULL) { LOG(LOG_CRIT, ERR_MEM_ALLOC); goto CLOSE; } } if (at != NULL) *at = '@'; /* always add complete address (user@domain) to recipient list */ nt_add(ATX->recipients, username); } if (daemon_reply(TTX, LMTP_OK, "2.1.5", "OK")<=0) goto CLOSE; GETCMD: free(cmdline); cmdline = daemon_getline(TTX, 300); } if (cmdline == NULL) goto CLOSE; if (!strncasecmp(cmdline, "RSET", 4)) { snprintf(buf, sizeof(buf), "%d OK", LMTP_OK); if (send_socket(TTX, buf)<=0) goto CLOSE; goto RSET; } if (!strncasecmp(cmdline, "quit", 4)) { daemon_reply(TTX, LMTP_OK, "2.0.0", "OK"); goto CLOSE; } /* Parse DSPAMPROCESSMODE input and set up process arguments */ if (server_mode == SSM_DSPAM && processmode[0] != 0) { token = strtok_r(processmode, " ", &ptrptr); while(token != NULL && argc<63) { argv[argc] = token; argc++; argv[argc] = 0; token = strtok_r(NULL, " ", &ptrptr); } } invalid = 0; if (process_arguments(ATX, argc, argv) || apply_defaults(ATX)) { LOG(LOG_ERR, ERR_AGENT_INIT_ATX); daemon_reply(TTX, LMTP_NO_RCPT, "5.1.0", ERR_AGENT_INIT_ATX); invalid = 1; } else if (ATX->users->items == 0) { daemon_reply(TTX, LMTP_NO_RCPT, "5.1.1", ERR_AGENT_USER_UNDEFINED); } } ATX->sockfd = fd; ATX->sockfd_output = 0; /* Something's terribly misconfigured */ if (check_configuration(ATX)) { LOG(LOG_ERR, ERR_AGENT_MISCONFIGURED); daemon_reply(TTX, LMTP_BAD_CMD, "5.3.5", ERR_AGENT_MISCONFIGURED); goto CLOSE; } /* DATA */ if (cmdline != NULL) { if (strncasecmp(cmdline, "DATA", 4)) { if (daemon_reply(TTX, LMTP_BAD_CMD, "5.0.0", "Need DATA Here")<0) goto CLOSE; input = daemon_expect(TTX, "DATA"); if (input == NULL) goto CLOSE; if (RSET(input)) goto RSET; } } if (daemon_reply(TTX, LMTP_DATA, "", INFO_LMTP_DATA)<=0) goto CLOSE; /* * Read in the message from a DATA. I personally like to just hang up on * a client stupid enough to pass in a NULL message for DATA, but you're * welcome to do whatever you want. */ message = read_sock(TTX, ATX); if (message == NULL || message->data == NULL || message->used == 0) { daemon_reply(TTX, LMTP_FAILURE, "5.2.0", ERR_LMTP_MSG_NULL); goto CLOSE; } /* * Lock a database handle. We currently use the modulus of the socket * id against the number of database connections in the cache. This * seems to work rather well, as we would need to lock up the entire * cache to wrap back around. And if we do wrap back around, that means * we're busy enough to justify spinning on the current lock (vs. seeking * out a free handle, which there likely are none). */ i = (TTX->sockfd % TTX->DTX->connection_cache); LOGDEBUG("using database handle id %d", i); if (TTX->DTX->flags & DRF_RWLOCK) { if (ATX->operating_mode == DSM_CLASSIFY || ATX->training_mode == DST_NOTRAIN || (ATX->training_mode == DST_TOE && ATX->classification == DSR_NONE)) { pthread_rwlock_rdlock(&TTX->DTX->connections[i]->rwlock); } else { pthread_rwlock_wrlock(&TTX->DTX->connections[i]->rwlock); } } else { pthread_mutex_lock(&TTX->DTX->connections[i]->lock); } LOGDEBUG("handle locked"); ATX->dbh = TTX->DTX->connections[i]->dbh; locked = i; /* Process the message by tying back into the agent functions */ ATX->results = nt_create(NT_PTR); if (ATX->results == NULL) { LOG(LOG_CRIT, ERR_MEM_ALLOC); goto CLOSE; } process_users(ATX, message); /* * Unlock the database handle as soon as we're done. We also need to * refresh our handle index with a new handle if for some reason we * had to re-establish a dewedged connection. */ if (TTX->DTX->connections[locked]->dbh != ATX->dbh) TTX->DTX->connections[locked]->dbh = ATX->dbh; if (TTX->DTX->flags & DRF_RWLOCK) { pthread_rwlock_unlock(&TTX->DTX->connections[locked]->rwlock); } else { pthread_mutex_unlock(&TTX->DTX->connections[locked]->lock); } locked = -1; /* Send a terminating '.' if --stdout in 'dspam' mode */ if (ATX->sockfd_output) { if (send_socket(TTX, ".")<=0) goto CLOSE; /* Otherwise, produce standard delivery results */ } else { struct nt_node *node_nt, *node_res = NULL; struct nt_c c_nt; if (ATX->recipients) node_nt = c_nt_first(ATX->recipients, &c_nt); else node_nt = c_nt_first(ATX->users, &c_nt); if (ATX->results) node_res = ATX->results->first; while(node_res && node_nt != NULL) { agent_result_t result = (agent_result_t) node_res->ptr; if (result != NULL && result->exitcode == ERC_SUCCESS) { if (server_mode == SSM_DSPAM) { snprintf(buf, sizeof(buf), "%d 2.6.0 <%s> Message accepted for delivery: %s", LMTP_OK, (char *) node_nt->ptr, (result->classification == DSR_ISSPAM) ? "SPAM" : "INNOCENT"); } else { snprintf(buf, sizeof(buf), "%d 2.6.0 <%s> Message accepted for delivery", LMTP_OK, (char *) node_nt->ptr); } } else { if (result != NULL && result->exitcode == ERC_PERMANENT_DELIVERY) { snprintf(buf, sizeof(buf), "%d 5.3.0 <%s> %s", LMTP_FAILURE, (char *) node_nt->ptr, (result->text[0]) ? result->text : "Permanent error occured"); } else { if (result != NULL && result->text[0]) { snprintf(buf, sizeof(buf), "%d 4.3.0 <%s> %s", LMTP_TEMP_FAIL, (char *) node_nt->ptr, result->text); } else { snprintf(buf, sizeof(buf), "%d 4.3.0 <%s> Error occured during %s", LMTP_TEMP_FAIL, (char *) node_nt->ptr, (result != NULL && result->exitcode == ERC_DELIVERY) ? "delivery" : "processing"); } } } if (send_socket(TTX, buf)<=0) goto CLOSE; if (ATX->recipients) node_nt = c_nt_next(ATX->recipients, &c_nt); else node_nt = c_nt_next(ATX->users, &c_nt); if (node_res) node_res = node_res->next; } } /* Cleanup and get ready for another message */ RSET: fflush(fd); buffer_destroy(message); message = NULL; if (ATX != NULL) { nt_destroy(ATX->users); nt_destroy(ATX->recipients); nt_destroy(ATX->results); free(ATX); ATX = NULL; free(cmdline); cmdline = NULL; TTX->authenticated = 0; /* argc = 0; */ } free(p); p = NULL; } /* while(1) */ /* Close connection and return */ CLOSE: if (locked>=0) pthread_mutex_unlock(&TTX->DTX->connections[locked]->lock); if (fd) fclose(fd); buffer_destroy(TTX->packet_buffer); if (message) buffer_destroy(message); if (ATX != NULL) { nt_destroy(ATX->users); nt_destroy(ATX->recipients); nt_destroy(ATX->results); } free(ATX); free(cmdline); free(TTX); decrement_thread_count(); pthread_exit(0); return 0; }
int main (int argc, char *argv[]) { AGENT_CTX ATX; int exitcode = EXIT_SUCCESS; buffer *message = NULL; /* input Message */ int agent_init = 0; /* agent is initialized */ setbuf (stdout, NULL); /* unbuffered output */ #ifdef DEBUG DO_DEBUG = 0; #endif srand ((long) time << (long) getpid()); umask (006); #ifndef DAEMON LOG(LOG_ERR, ERR_DAEMON_NO_SUPPORT); exit(EXIT_FAILURE); #endif /* Read dspam.conf into global config structure (ds_config_t) */ agent_config = read_config(NULL); if (!agent_config) { LOG(LOG_ERR, ERR_AGENT_READ_CONFIG); exitcode = EXIT_FAILURE; goto BAIL; } if (!_ds_read_attribute(agent_config, "Home")) { LOG(LOG_ERR, ERR_AGENT_DSPAM_HOME); exitcode = EXIT_FAILURE; goto BAIL; } /* Set up agent context to define behavior of processor */ if (initialize_atx(&ATX)) { LOG(LOG_ERR, ERR_AGENT_INIT_ATX); exitcode = EXIT_FAILURE; goto BAIL; } else { agent_init = 1; } if (process_arguments(&ATX, argc, argv)) { LOG(LOG_ERR, ERR_AGENT_INIT_ATX); exitcode = EXIT_FAILURE; goto BAIL; } if (apply_defaults(&ATX)) { LOG(LOG_ERR, ERR_AGENT_INIT_ATX); exitcode = EXIT_FAILURE; goto BAIL; } if (check_configuration(&ATX)) { LOG(LOG_ERR, ERR_AGENT_MISCONFIGURED); exitcode = EXIT_FAILURE; goto BAIL; } /* Read the message in and apply ParseTo services */ message = read_stdin(&ATX); if (message == NULL) { exitcode = EXIT_FAILURE; goto BAIL; } if (ATX.users->items == 0) { LOG (LOG_ERR, ERR_AGENT_USER_UNDEFINED); fprintf (stderr, "%s\n", SYNTAX); exitcode = EXIT_FAILURE; goto BAIL; } /* Perform client-based processing */ #ifdef DAEMON if (_ds_read_attribute(agent_config, "ClientIdent") && (_ds_read_attribute(agent_config, "ClientHost") || _ds_read_attribute(agent_config, "ServerDomainSocketPath"))) { exitcode = client_process(&ATX, message); } else { LOG(LOG_ERR, ERR_CLIENT_INVALID_CONFIG); exitcode = EINVAL; } #endif BAIL: if (message) buffer_destroy(message); if (agent_init) nt_destroy(ATX.users); if (agent_config) _ds_destroy_config(agent_config); exit (exitcode); }