int call_spamc(FILE *tmp_msg, char *user, int maxsize) { struct message msg; FILE *tmp_sa_msg; int tmp_msg_fd; int err,flags,is_spam; struct sockaddr addr; tmp_msg_fd=fileno(tmp_msg); flags = SPAMC_RAW_MODE | SPAMC_SAFE_FALLBACK; #if WITH_DEBUG == 1 fprintf(stderr, "SpamAssassin Check\n"); #endif msg.max_len=maxsize; msg.type=MESSAGE_NONE; msg.raw=(char *)malloc(msg.max_len); err=lookup_host(SPAMD_HOST, SPAMD_PORT, &addr); if(err!=EX_OK) { fprintf(stderr, "BARF on lookup_host (%d)\n",err); return; } rewind(tmp_msg); err=message_read(tmp_msg_fd,SPAMC_RAW_MODE, &msg); if(err != EX_OK) { fprintf(stderr, "BARF on message_read (%d)\n",err); return; } err=message_filter(&addr, user, flags|SPAMC_CHECK_ONLY, &msg); if(err != EX_OK) { fprintf(stderr, "BARF on message_filter (%d)\n",err); return; } is_spam=msg.is_spam; /* * We currently run the message through the filter twice. Becuase * libspamc doesn't fill in all the msg structures w/o CHECK_ONLY * Until this is fixed or a better workaround comes up this is how * it is handled (one 'check only' and one real check) */ rewind(tmp_msg); err=message_filter(&addr, user, flags, &msg); if(err != EX_OK) { fprintf(stderr, "BARF on message_filter (%d)\n",err); return; } rewind(tmp_msg); if(err=message_write(tmp_msg_fd, &msg)<0) { fprintf(stderr, "BARF on message_write (%d)\n",err); return; } /* Restore from the original is_spam check */ msg.is_spam = is_spam; if(msg.is_spam == EX_TOOBIG) msg.is_spam=0; /* Ignore Too Big errs */ return msg.is_spam; }
static MsgStatus msg_is_spam(FILE *fp) { struct transport trans; struct message m; gboolean is_spam = FALSE; if (!config.enable) return MSG_IS_HAM; transport_init(&trans); switch (config.transport) { case SPAMASSASSIN_TRANSPORT_LOCALHOST: trans.type = TRANSPORT_LOCALHOST; trans.port = config.port; break; case SPAMASSASSIN_TRANSPORT_TCP: trans.type = TRANSPORT_TCP; trans.hostname = config.hostname; trans.port = config.port; break; case SPAMASSASSIN_TRANSPORT_UNIX: trans.type = TRANSPORT_UNIX; trans.socketpath = config.socket; break; default: return MSG_IS_HAM; } if (transport_setup(&trans, flags) != EX_OK) { log_error(LOG_PROTOCOL, _("SpamAssassin plugin couldn't connect to spamd.\n")); debug_print("failed to setup transport\n"); return MSG_FILTERING_ERROR; } m.type = MESSAGE_NONE; m.max_len = config.max_size * 1024; m.timeout = config.timeout; if (message_read(fileno(fp), flags, &m) != EX_OK) { debug_print("failed to read message\n"); message_cleanup(&m); return MSG_FILTERING_ERROR; } if (message_filter(&trans, config.username, flags, &m) != EX_OK) { log_error(LOG_PROTOCOL, _("SpamAssassin plugin filtering failed.\n")); debug_print("filtering the message failed\n"); message_cleanup(&m); return MSG_FILTERING_ERROR; } if (m.is_spam == EX_ISSPAM) is_spam = TRUE; message_cleanup(&m); return is_spam ? MSG_IS_SPAM:MSG_IS_HAM; }
END_TEST START_TEST(test_message_read) { message * msg; int * sock = GC_malloc(sizeof(int) * 2); socketpair(AF_UNIX, SOCK_STREAM, 0, sock); uint32_t size = HEADER_SIZE + sizeof("\x93\x00\x01\xa3hey"); char * src_buf = GC_malloc(size); memcpy(src_buf, "\x00\x00\x00\x07\xfb\x65\x78\xa3", HEADER_SIZE); memcpy(src_buf + HEADER_SIZE, "\x93\x00\x01\xa3hey", sizeof("\x93\x00\x01\xa3hey")); ck_assert_int_eq(message_read(sock[0], &msg), RET_MESSAGE_HEADER_ERROR); send(sock[1], src_buf, HEADER_SIZE, MSG_DONTWAIT); ck_assert_int_eq(message_read(sock[0], &msg), RET_MESSAGE_RECEIVE_ERROR); send(sock[1], src_buf, size, MSG_DONTWAIT); ck_assert_int_eq(message_read(sock[0], &msg), RET_OK); ck_assert(msg != NULL); ck_assert_str_eq(msg->data.echo, "hey"); }
END_TEST START_TEST(test_message_send_read) { message * msg, * msg2; int * sock = GC_malloc(sizeof(int) * 2); socketpair(AF_UNIX, SOCK_STREAM, 0, sock); msg = message_create_echo(MESSAGE_TYPE_REQUEST, "hey"); message_send(sock[0], msg); ck_assert_int_eq(message_read(sock[1], &msg2), RET_OK); ck_assert(msg2 != NULL); ck_assert_str_eq(msg2->data.echo, "hey"); }
void greet_client(int socket) { short byte; int result; char *dpy_name,*app_class,*app_name; message_t first; /* Read byte-swap thing */ result = read(socket,&byte,2); if( !result ) fatal_error("greet_client: Unable to read initial data."); else if( result == 1 ) { result = read(socket, ((char *) &byte)+1,1); fatal_error("greet_client: Unable to read initial data."); } swap_bytes = (byte!=1); if( global_will_trace ) { printf("swap_bytes is: %d (from %d)\n",swap_bytes,byte); fflush(stdout); } /* Read initial packet */ first = message_read(socket); if( !first ) fatal_error("greet_client: No greeting packet sent."); toolkit_read_value(first,&dpy_name,XtRString); toolkit_read_value(first,&app_name,XtRString); toolkit_read_value(first,&app_class,XtRString); global_app_class = XtNewString(app_class); global_app_name = XtNewString(app_name); if( global_will_trace ) { printf("Opening display on '%s' for app '%s' class '%s'\n",dpy_name, app_name,app_class); fflush(stdout); }; display = XtOpenDisplay(app_context, dpy_name, app_name, app_class, NULL, 0, &global_argc, global_argv); if( !display ) fatal_error("greet_client: Unable to open display."); message_free(first); }
void get_input(caddr_t closure, int *socket, XtInputId *id) { message_t message; if( global_will_trace ) { printf("get_input: Receiving incoming packet.\n"); fflush(stdout); } message = message_read(*socket); process_request(message,*socket); if( global_will_trace ) { printf("get_input: Successfully digested packet. Now freeing.\n"); fflush(stdout); } message_free(message); }
int gestic_message_receive(gestic_t *gestic, int *timeout) { int result = GESTIC_NO_ERROR; int msg_size; void *msg; for(;;) { msg = message_read(gestic, &msg_size); if(msg) { gestic_message_handle(gestic, msg, msg_size); break; } if(!timeout || (*timeout <= 0)) { result = GESTIC_NO_DATA; break; } sleep(10); *timeout -= 10; } return result; }
static int proc(struct proc_config_t * config) { int rc; int fd_max; fd_set rfds; struct message_t msg; uint32_t cnt_error = 0; struct message_log_data_t * data; struct signalfd_siginfo signal_info; if (!config) return EXIT_FAILURE; data = (struct message_log_data_t *)config->data; if (!data) return EXIT_FAILURE; while (1) { fd_max = -1; FD_ZERO(&rfds); FD_SET(config->rfd, &rfds); if (config->rfd > fd_max) fd_max = config->rfd; FD_SET(config->signal_fd, &rfds); if (config->signal_fd > fd_max) fd_max = config->signal_fd; rc = select(fd_max + 1, &rfds, NULL, NULL, NULL); if (rc < 0 && errno != EINTR) { syslog(LOG_ERR, "error in 'select': %s", strerror(errno)); return EXIT_FAILURE; } else if (rc < 0 && errno == EINTR) { break; } else if (rc == 0) { continue; } if (FD_ISSET(config->signal_fd, &rfds)) { rc = read(config->signal_fd, &signal_info, sizeof(signal_info)); if (rc < 0 || rc != sizeof(signal_info)) { syslog(LOG_ERR, "cannot read singal info"); return EXIT_FAILURE; } if (signal_info.ssi_signo == SIGTERM) break; } if (FD_ISSET(config->rfd, &rfds)) { if (message_read(config->rfd, &msg) != EXIT_SUCCESS) return EXIT_FAILURE; switch (msg.type) { case MSG_SYSTEM: switch (msg.data.attr.system) { case SYSTEM_TERMINATE: return EXIT_SUCCESS; default: break; } break; case MSG_NMEA: #if defined(NEEDS_NMEA) if (data->enable) { rc = log_nmea_message(&msg, data); if (rc < 0) { ++cnt_error; if (cnt_error >= data->max_errors) { syslog(LOG_ERR, "max_errors (%u) reached, disable logging", data->max_errors); data->enable = 0; } } } #endif break; case MSG_SEATALK: #if defined(NEEDS_SEATALK) /* TODO: message log to support seatalk messages */ syslog(LOG_WARNING, "seatalk messages not handled yet: %08x\n", msg.type); #endif break; default: syslog(LOG_WARNING, "unknown msg type: %08x\n", msg.type); break; } continue; } } return EXIT_SUCCESS; }
/* * Data is ready to be read. */ static void data_ready(void) { static char buf[1024]; static int buf_full; char *ptr; int x; /* Determine number of bytes to read */ if (buf_full < 8) { /* Read 8 bytes for header */ x = 8; } else { /* Skip to message size portion of header */ ptr = buf + 4; x = get_integer(&ptr); } /* Check for overly long message */ if (x > 1024) { /* Error */ printf("Received too long message!\n"); exit(1); } /* Try to read enough bytes */ x = read(0, buf + buf_full, x - buf_full); /* Check for error */ if (x <= 0) { /* Check for try again error */ if (x < 0 && errno == EAGAIN) return; /* Check for server disconnect */ if (x == 0) exit(0); /* Print error */ perror("read"); exit(1); } /* Add to amount read */ buf_full += x; /* Check for complete message header */ if (buf_full >= 8) { /* Skip to length portion of header */ ptr = buf + 4; x = get_integer(&ptr); /* Check for too-small message */ if (x < 8) { /* Print error */ printf("Got too small message!\n"); exit(1); } /* Check for complete message */ if (buf_full == x) { /* Handle message at next opportunity */ message_read(buf); /* Clear buffer */ buf_full = 0; } } }
int main(int argc, char **argv) { if (argc < 3) err_quit("wrong number of parameters"); GraphData *data; Pipe *red_pipe, **blue_pipe; int st, fail, i, j, r, b, **vmatrix, mark, red_balance, msg_balance; int sem[2], monster_pipe[2]; pid_t *blue_pids; pid_t *red_pids; pid_t monster_pid, pid, rpid; const int mark_new_msg = 1; const int mark_dead_msg = -1; const int mark_dead_red = 0; data = data_read(); b = data->b; r = data->r; vmatrix = data->vmatrix; red_pipe = pipes_create(r); blue_pipe = blue_pipe_create(data); blue_pids = (pid_t*) malloc(sizeof(pid_t) * b); //sync pipes if (pipe(sem)) err_sys("sync pipe failed"); //blue processes for (i = 0; i < b; i++) { if ((pid = fork()) == 0) { Message *msg; Message **r_msg, **w_msg; Pipe *read_pipe; int *redp, redp_num, *isdead; int lock, l, k, s; int r_num; lock = 0; redp = (int*) malloc(sizeof(int) * r); isdead = (int*) malloc(sizeof(int) * r); //closing red pipes for (k = 0, j = 0; j < r; j++) { if (data->red[j].node == i) { isdead[k] = 0; redp[k++] = red_pipe[j].fd[0]; close(red_pipe[j].fd[1]); continue; } close(red_pipe[j].fd[0]); close(red_pipe[j].fd[1]); } redp_num = k; //copy pipes from which we read for faster access //and close them for writing, also close other pipes which we don't use in this process read_pipe = (Pipe*) malloc(sizeof(Pipe) * data->read_num[i]); for (k = 0, j = 0; j < b; j++) { if (j == i) continue; if (vmatrix[j][i] == 1) { for (lock = -1, l = 0; l < data->write_num[j]; l++) if (blue_pipe[j][l].to == i) { read_pipe[k++] = blue_pipe[j][l]; lock = l; break; } } for (l = 0; l < data->write_num[j]; l++) { if (l == lock) { close(blue_pipe[j][l].fd[1]); continue; } close(blue_pipe[j][l].fd[0]); close(blue_pipe[j][l].fd[1]); } } r_msg = (Message**) calloc(data->read_num[i], sizeof(Message*)); w_msg = (Message**) calloc(data->write_num[i], sizeof(Message*)); //don't read from pipes in which we write for (j = 0; j < data->write_num[i]; j++) close(blue_pipe[i][j].fd[0]); //main loop while (1) { r_num = -1; msg = NULL; //try to read from red pipes for (s = 0, j = 0; j < redp_num; j++) if (!isdead[j] && (msg = message_read(redp[j], &s, NULL)) != NULL) { //if we've received something from red pipe //we have a new packet in network st = write(sem[1], &mark_new_msg, sizeof(int)); break; } else if (s == -1) { //eof in pipe, so red is dead, and we will not receive smth from this one st = write(sem[1], &mark_dead_red, sizeof(int)); isdead[j] = 1; s = 0; } //try to read from blue pipes if nothing was read from red ones if (msg == NULL) { for (j = 0; j < data->read_num[i]; j++) if ((msg = message_read(read_pipe[j].fd[0], NULL, r_msg[j])) != NULL) { if (msg->len > msg->sv_r) { r_msg[j] = msg; r_num = j; msg = NULL; } else { r_msg[j] = NULL; debug("full - %d | id: %d", msg->len, msg->id); } break; } } //try again if (msg == NULL) { for (j = 0; msg == NULL && j < data->write_num[i]; j++) if (w_msg[j] != NULL) msg = w_msg[j]; if (msg == NULL) { usleep(100); continue; } } //check the message if (!msg->ch) { st = message_check(data, i, msg); fflush(stdout); if (st == MSG_ERROR || st == MSG_END) { //message is dead now st = write(sem[1], &mark_dead_msg, sizeof(int)); message_destroy(msg); continue; } //st == MSG_OK //send message for (j = 0; j < data->write_num[i]; j++) { if (blue_pipe[i][j].to == msg->node[0] - 1) { msg->num_w = j; msg->fd[1] = blue_pipe[i][j].fd[1]; break; } } j = msg->num_w; if (w_msg[j] != NULL) { Message *cur = w_msg[j]; while(cur->next != NULL) cur = cur->next; cur->next = msg; msg = w_msg[j]; } else { w_msg[j] = msg; } } st = message_send(msg->fd[1], msg); if (st == 0) { w_msg[msg->num_w] = w_msg[msg->num_w]->next; message_destroy(msg); } } exit(EXIT_SUCCESS); } else if (pid == -1) { err_sys("failed on %d's blue fork", i); } blue_pids[i] = pid; } //close all blue pipes for (i = 0; i < b; i++) pipes_close(blue_pipe[i], data->write_num[i]); //create red processes red_pids = (pid_t*) malloc(sizeof(pid_t) * r); for (i = 0; i < r; i++) { if ((pid = fork()) == 0) { char *filename = data->red[i].filename; char *name = argv[1]; char num_buf[10]; int pfd = red_pipe[i].fd[1]; dup2(pfd, 1); pipes_close(red_pipe, r); close_pipe(sem); sprintf(num_buf, "%d", i + 1); for (j = strlen(name); j > 0 && name[j] != '/'; j--) ; execlp(name, name + j + 1, num_buf, filename, NULL); err_sys("%d red process exec failed", i); } else if (pid == -1) { err_sys("%d red process fork failed", i); } red_pids[i] = pid; } //close all red pipes pipes_close(red_pipe, r); //create monster pipe and monster process if (pipe(monster_pipe) < 0) err_sys("monster pipe failed"); if ((monster_pid = fork()) == 0) { int *pfd = monster_pipe; char *name = argv[2]; dup2(pfd[0], 0); close_pipe(sem); close_pipe(pfd); for (i = strlen(name); i > 0 && name[i] != '/'; i--) ; execlp(name, name + i + 1, NULL); err_sys("monster process exec failed"); } else if (monster_pid == -1) { err_sys("monster process forking failed"); } close(monster_pipe[0]); //wait red processes for (i = 0; i < r; i++) { rpid = wait(&st); //check if dead process was red //do we need this check or not? for (fail = 1, j = 0; j < r; j++) if (rpid == red_pids[j]) fail = 0; if (fail) { err_quit("an error in blue process has occured, terminating..."); } } //wait all packets to reach their destination //and all red pipes to be read red_balance = r; msg_balance = 0; while (red_balance || msg_balance) { st = read(sem[0], &mark, sizeof(int)); if (st == 0) break; if (st == sizeof(int)) { if (mark == 0) red_balance--; else if (mark == 1) msg_balance++; else if (mark == -1) msg_balance--; continue; } err_sys("error in sync pipe"); } //tell monster to kill our children st = write(monster_pipe[1], &b, sizeof(int)); for (i = 0; i < b; i++) { st = write(monster_pipe[1], &blue_pids[i], sizeof(int)); } close(monster_pipe[1]); //wait him to do his dirty work, ignoring our children deaths while (wait(&st) != monster_pid); //will close everything that was opened and free everything that was allocated return 0; }