Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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");
}
Example #4
0
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");
}
Example #5
0
File: server.c Project: rtoy/cmucl
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);
}
Example #6
0
File: server.c Project: rtoy/cmucl
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;
}
Example #8
0
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;
}
Example #9
0
/*
 * 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;
        }
    }
}
Example #10
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;
}