Ejemplo n.º 1
0
/*
 *  send the damn thing
 */
char *
data(String *from, Biobuf *b)
{
	char *buf, *cp;
	int i, n, nbytes, bufsize, eof, r;
	String *fromline;
	char errmsg[Errlen];
	char id[40];

	/*
	 *  input the header.
	 */

	buf = malloc(1);
	if(buf == 0){
		s_append(s_restart(reply), "out of memory");
		return Retry;
	}
	n = 0;
	eof = 0;
	for(;;){
		cp = Brdline(b, '\n');
		if(cp == nil){
			eof = 1;
			break;
		}
		nbytes = Blinelen(b);
		buf = realloc(buf, n+nbytes+1);
		if(buf == 0){
			s_append(s_restart(reply), "out of memory");
			return Retry;
		}
		strncpy(buf+n, cp, nbytes);
		n += nbytes;
		if(nbytes == 1)		/* end of header */
			break;
	}
	buf[n] = 0;
	bufsize = n;

	/*
	 *  parse the header, turn all addresses into @ format
	 */
	yyinit(buf, n);
	yyparse();

	/*
	 *  print message observing '.' escapes and using \r\n for \n
	 */
	alarm(20*alarmscale);
	if(!filter){
		dBprint("DATA\r\n");
		switch(getreply()){
		case 3:
			break;
		case 5:
			free(buf);
			return Giveup;
		default:
			free(buf);
			return Retry;
		}
	}
	/*
	 *  send header.  add a message-id, a sender, and a date if there
	 *  isn't one
	 */
	nbytes = 0;
	fromline = convertheader(from);
	uneaten = buf;

	srand(truerand());
	if(messageid == 0){
		for(i=0; i<16; i++){
			r = rand()&0xFF;
			id[2*i] = hex[r&0xF];
			id[2*i+1] = hex[(r>>4)&0xF];
		}
		id[2*i] = '\0';
		nbytes += Bprint(&bout, "Message-ID: <%s@%s>\r\n", id, hostdomain);
		if(debug)
			Bprint(&berr, "Message-ID: <%s@%s>\r\n", id, hostdomain);
	}

	if(originator==0){
		nbytes += Bprint(&bout, "From: %s\r\n", s_to_c(fromline));
		if(debug)
			Bprint(&berr, "From: %s\r\n", s_to_c(fromline));
	}
	s_free(fromline);

	if(destination == 0 && toline)
		if(*s_to_c(toline) == '@'){	/* route addr */
			nbytes += Bprint(&bout, "To: <%s>\r\n", s_to_c(toline));
			if(debug)
				Bprint(&berr, "To: <%s>\r\n", s_to_c(toline));
		} else {
			nbytes += Bprint(&bout, "To: %s\r\n", s_to_c(toline));
			if(debug)
				Bprint(&berr, "To: %s\r\n", s_to_c(toline));
		}

	if(date==0 && udate)
		nbytes += printdate(udate);
	if (usys)
		uneaten = usys->end + 1;
	nbytes += printheader();
	if (*uneaten != '\n')
		putcrnl("\n", 1);

	/*
	 *  send body
	 */

	putcrnl(uneaten, buf+n - uneaten);
	nbytes += buf+n - uneaten;
	if(eof == 0){
		for(;;){
			n = Bread(b, buf, bufsize);
			if(n < 0){
				rerrstr(errmsg, sizeof(errmsg));
				s_append(s_restart(reply), errmsg);
				free(buf);
				return Retry;
			}
			if(n == 0)
				break;
			alarm(10*alarmscale);
			putcrnl(buf, n);
			nbytes += n;
		}
	}
	free(buf);
	if(!filter){
		if(last != '\n')
			dBprint("\r\n.\r\n");
		else
			dBprint(".\r\n");
		alarm(10*alarmscale);
		switch(getreply()){
		case 2:
			break;
		case 5:
			return Giveup;
		default:
			return Retry;
		}
		syslog(0, "smtp", "%s sent %d bytes to %s", s_to_c(from),
				nbytes, s_to_c(toline));/**/
	}
	return 0;
}
Ejemplo n.º 2
0
eastl::optional<csv_parser_status>
Options::read(eastl::shared_ptr<context> context, FILE* is, const Model& model)
{
    clear();

    eastl::vector<const attribute*> atts = get_basic_attribute(model);
    eastl::vector<int> convertheader(atts.size(), 0);
    eastl::vector<eastl::string> columns;
    eastl::string line;
    int id = -1;

    line_reader ls(is);

    {
        auto opt_line = ls.getline();
        if (!opt_line) {
            info(context, "Fail to read header\n");
            return eastl::make_optional<csv_parser_status>(
              csv_parser_status::tag::file_error, size_t(0), columns.size());
        }

        line = *opt_line;

        tokenize(line, columns, ";", false);

        if (columns.size() == atts.size() + 4)
            id = 3;
        else if (columns.size() == atts.size() + 5)
            id = 4;
        else
            return eastl::make_optional<csv_parser_status>(
              csv_parser_status::tag::column_number_incorrect,
              size_t(0),
              columns.size());
    }

    for (size_t i = 0, e = atts.size(); i != e; ++i)
        info(context, "column {} {}\n", i, columns[i].c_str());

    for (size_t i = id, e = id + atts.size(); i != e; ++i) {
        info(context,
             "try to get_basic_atribute_id {} : {}\n",
             i,
             columns[i].c_str());

        auto opt_att_id = get_basic_attribute_id(atts, columns[i]);
        if (!opt_att_id) {
            return eastl::make_optional<csv_parser_status>(
              csv_parser_status::tag::basic_attribute_unknown,
              size_t(0),
              columns.size());
        }

        convertheader[i - id] = *opt_att_id;
    }

    info(context, "Starts to read data (atts.size() = {}\n", atts.size());

    options.init(atts.size());
    options.push_line();
    int line_number = -1;

    while (true) {
        auto opt_line = ls.getline();
        if (!opt_line)
            break;

        line = *opt_line;
        line_number++;

        tokenize(line, columns, ";", false);
        if (columns.size() != atts.size() + id + 1) {
            error(context,
                  "Options: error in csv file line {}:"
                  " not correct number of column {}"
                  " (expected: {})\n",
                  line_number,
                  columns.size(),
                  atts.size() + id + 1);
            continue;
        }

        auto opt_obs =
          model.attributes[0].scale.find_scale_value(columns.back());

        if (not opt_obs) {
            return eastl::make_optional<csv_parser_status>(
              csv_parser_status::tag::scale_value_unknown,
              static_cast<size_t>(line_number),
              static_cast<size_t>(columns.size()));
        }

        int obs = *opt_obs;
        int department, year;

        {
            auto len1 = sscanf(columns[id - 1].c_str(), "%d", &year);
            auto len2 = sscanf(columns[id - 1].c_str(), "%d", &department);

            if (len1 != 1 or len2 != 1) {
                error(context,
                      "Options: error in csv file line {}."
                      " Malformed year or department\n",
                      line_number);
                continue;
            }
        }

        simulations.push_back(columns[0]);
        if (id == 4)
            places.push_back(columns[1]);

        departments.push_back(department);
        years.push_back(year);
        observed.push_back(obs);

        for (size_t i = id, e = id + atts.size(); i != e; ++i) {
            size_t attid = convertheader[i - id];

            auto opt_option = atts[attid]->scale.find_scale_value(columns[i]);
            if (!opt_option) {
                error(context,
                      "Options: error in csv file line {}: "
                      "unknown scale value `{}' for attribute `{}'",
                      line_number,
                      columns[i].c_str(),
                      atts[attid]->name.c_str());
                simulations.pop_back();
                if (id == 4)
                    places.pop_back();
                departments.pop_back();
                years.pop_back();
                observed.pop_back();

                options.pop_line();
            } else {
                options(options.rows() - 1, attid) = *opt_option;
            }
        }

        options.push_line();
    }

    options.pop_line();

    init_dataset();
    check();

    return {};
}