示例#1
0
/**
 * @brief	Check to see if the specified command line option specified an optional parameter, and adjust the index accordingly.
 * @note	This function will automatically generate an error through display_usage() if the parameters are incorrect.
 * @param	xargv	a pointer to the main function's argv array.
 * @param	iptr	a pointer to the xargv option index to be checked and updated.
 * @param	xargc	the number of items in the xargv array.
 * @return	a pointer to the value of the current index's optional parameter if specified, or NULL if one wasn't.
 */
chr_t * check_next_opt(char *xargv[], int *iptr, int xargc) {

	chr_t *result;

	// If this is an optional parameter then there still must be a config file specified after it.
	if (*iptr == (xargc-1)) {
		check_display_usage(xargv[0]);
	}
	// If the next argument begins with '-' then our option has a null parameter.
	else if (!mm_cmp_cs_eq(xargv[*iptr+1], "-", 1)) {
		(*iptr)++;
		return NULL;
	}

	// If the following parameter is the last one, it must be the config file and this is a null option.
	if (*iptr+1 == (xargc-1)) {
		(*iptr)++;
		return NULL;
	}

	(*iptr) += 2;

	if (!(result = ns_dupe(xargv[*iptr-1]))) {
		log_unit("Memory allocation encountered while preparing checks. Exiting.\n");
	}

	return result;
}
示例#2
0
/**
 * @brief	Count the number of instances of a boundary string inside a MIME body.
 * @note	The search is terminated if "--" is found right after the boundary string.
 * @param	body		a placer containing the body text to be parsed.
 * @param	boundary	a pointer to a managed string containing the boundary string for the MIME content.
 * @return	0 on failure, or the number of times the boundary string was located in the MIME body on success.
 */
uint32_t mail_mime_count(placer_t body, stringer_t *boundary) {

	uint32_t result = 0;
	chr_t *stream, *bounddata;
	size_t increment = 0, length, boundlen;

	if (pl_empty(body) || st_empty(boundary)) {
		return 0;
	}

	// Figure out the lengths.
	if (!(length = st_length_get(&body))) {
		log_pedantic("Cannot count boundary marker in zero-length MIME body..");
		return 0;
	}
	else if (!(boundlen = st_length_get(boundary))) {
		log_pedantic("Cannot count zero-length MIME boundary.");
		return 0;
	}

	// Setup.
	stream = st_char_get(&body);
	bounddata = st_char_get(boundary);

	// Find the start of the first part.
	while (increment + boundlen <= length) {

		if (mm_cmp_cs_eq(stream, bounddata, boundlen) == 0) {
			stream += boundlen + 1;
			increment += boundlen + 1;

			// Two dashes indicate the end of this mime sections.
			if (increment + 1 <= length && mm_cmp_cs_eq(stream, "--", 2) == 0) {
				increment = length + 1;
			}
			else {
				result++;
			}
		}
		else {
			stream++;
			increment++;
		}
	}

	return result;
}
示例#3
0
/**
 * @brief	Get a specified chunk (mime part) of a multipart mime message.
 * @param	message		a managed string containing the mime message to be parsed.
 * @param	boundary	a managed string containing the boundary used to split the multipart mime message.
 * @param	chunk		the one-index based chunk to be retrieved from the multipart message
 * @return	NULL on failure or a placer containing the specified chunk on success.
 */
stringer_t * mail_get_chunk(stringer_t *message, stringer_t *boundary, int_t chunk) {

	int_t found = 0;
	stringer_t *result;
	size_t start = 0, length = 0, input = 0;

	while (chunk != 0) {

		// So on repeats we don't have to start all over again.
		if (length != 0) {
			start += length - 1;
		}

		found = 0;

		while (found == 0) {

			// Get the start of the MIME message part.
			if (!st_search_cs(PLACER(st_char_get(message) + start, st_length_get(message) - start), boundary, &input)) {
				log_pedantic("The boundary doesn't appear to be part of this message.");
				return NULL;
			}

			// Skip the boundary before searching again.
			start += input + st_length_get(boundary);

			// This will detect the section ending.
			if (st_length_get(message) - start >= 2 && mm_cmp_cs_eq(st_char_get(message) + start, "--", 2) == 1) {
				return NULL;
			}
			// Some broken implementations use similar boundaries. This should detect those.
			else if (st_length_get(message) - start > 0 && (*(st_char_get(message) + start) < '!' || *(st_char_get(message) + start) > '~')) {
				found = 1;
			}
		}

		found = 0;

		while (found == 0) {

			// Get the end.
			if (!st_search_cs(PLACER(st_char_get(message) + start, st_length_get(message) - start), boundary, &length)) {
				length = st_length_get(message) - start;
				found = 1;
			}
			else if (st_length_get(message) - start - length > 0 && (*(st_char_get(message) + start) < '!' || *(st_char_get(message) + start) > '~')) {
				found = 1;
			}

		}

		chunk--;
	}

	// Setup a placer with the chunk.
	result = PLACER(st_char_get(message) + start, length);

	return result;
}
示例#4
0
/**
 * @brief	Get the media type for a given file extension.
 * @note	If no direct match is found for the content, "application/octet-stream" will be returned.
 * @param	extension	a pointer to a null-terminated string containing the file extension to be looked up, starting with a period.
 * @return	a pointer to a media type object corresponding to the media type of the specified file extension.
 */
media_type_t * mail_mime_get_media_type (chr_t *extension) {

	size_t cmplen = ns_length_get(extension) + 1;

	for (size_t i = 1; i < sizeof(media_types) / sizeof(media_type_t); i++) {

		if (!mm_cmp_cs_eq(media_types[i].extension, extension, cmplen)) {
			return (&(media_types[i]));
		}

	}

	return (&(media_types[0]));
}
示例#5
0
/* modeled closely after args_parse() */
void check_args_parse(int argc, char *argv[]) {

	int_t i = 1;

	while (i < argc) {

		if (!st_cmp_cs_eq(NULLER(argv[i]), PLACER("-v", 2))) {

			if (!(virus_check_data_path = check_next_opt(argv, &i, argc))) {
				do_virus_check = false;
			}

		}
		else if (!st_cmp_cs_eq(NULLER(argv[i]), PLACER("-t", 2))) {

			if (!(tank_check_data_path = check_next_opt(argv, &i, argc))) {
				do_tank_check = false;
			}

		}
		else if (!st_cmp_cs_eq(NULLER(argv[i]), PLACER("-d", 2))) {

			if (!(dspam_check_data_path = check_next_opt(argv, &i, argc))) {
				do_dspam_check = false;
			}

		}
		else if (!st_cmp_cs_eq(NULLER(argv[i]), PLACER("-s", 2))) {
			do_spf_check = false;
			i++;
		}
		// See if it's an illegal parameter beginning with "-"
		else if (!mm_cmp_cs_eq(argv[i], "-", 1)) {
			check_display_usage(argv[0]);
		}
		// Otherwise it's the config file
		else if (i == (argc-1)) {
			snprintf(magma.config.file, MAGMA_FILEPATH_MAX, "%s", argv[i]);
			i++;
		}
		else {
			check_display_usage(argv[0]);
		}

	}

	return;
}
示例#6
0
文件: mime.c 项目: lavabit/magma
/**
 * @brief	Get the media type for a given file extension.
 * @note	If no direct match is found for the content, "application/octet-stream" will be returned.
 * @param	extension	a pointer to a null-terminated string containing the file extension to be looked up, starting with a period.
 * @return	a pointer to a media type object corresponding to the media type of the specified file extension.
 */
media_type_t * mail_mime_get_media_type (chr_t *extension) {

	size_t cmplen = 0;

	// If extension is NULL, return application/octet-stream.
	if (ns_empty(extension)) return (&(media_types[0]));

	cmplen = ns_length_get(extension) + 1;

	for (size_t i = 1; i < sizeof(media_types) / sizeof(media_type_t); i++) {

		if (!mm_cmp_cs_eq(media_types[i].extension, extension, cmplen)) {
			return (&(media_types[i]));
		}

	}

	return (&(media_types[0]));
}
示例#7
0
/**
 * @brief	Get a placer pointing to the specified child inside a MIME body.
 * @param	body		a placer containing the body text to be parsed.
 * @param	boundary	a pointer to a managed string containing the boundary string to split the MIME content.
 * @param	child		the zero-based index of the MIME child to be located in the body text.
 * @return	pl_null() on failure, or a placer containing the specified MIME child on success.
 */
placer_t mail_mime_child(placer_t body, stringer_t *boundary, uint32_t child) {

	uint32_t result = 0;
	chr_t *start, *stream, *bounddata;
	size_t increment = 0, length, boundlen;

	if (pl_empty(body) || st_empty(boundary)) {
		return pl_null();
	}

	// Figure out the lengths.
	if (!(length = st_length_get(&body))) {
		log_pedantic("Cannot parse children from zero-length MIME body..");
		return pl_null();
	}
	else if (!(boundlen = st_length_get(boundary))) {
		log_pedantic("Cannot parse children from MIME body with zero-length boundary.");
		return pl_null();;
	}

	// Setup.
	stream = st_char_get(&body);
	bounddata = st_char_get(boundary);

	// Find the start of the first part.
	while (increment + boundlen <= length && result < child) {

		if (mm_cmp_cs_eq(stream, bounddata, boundlen) == 0 && (increment + boundlen == length || *(stream + boundlen) < '!' || *(stream + boundlen) > '~')) {
			stream += boundlen;
			increment += boundlen;

			// Two dashes indicate the end of this mime sections.
			if (increment < length && mm_cmp_cs_eq(stream, "--", 2) == 0) {
				increment = length + 1;
			}
			else {
				result++;
			}

		}
		else {
			stream++;
			increment++;
		}

	}

	// The requested child wasn't found.
	if (increment + boundlen >= length) {
		return pl_null();
	}

	// This will skip a line break after the boundary marker.
	if (length - increment > 0 && *stream == '\r') {
		stream++;
		increment++;
	}

	if (length - increment > 0 && *stream == '\n') {
		stream++;
		increment++;
	}

	// Store the start position.
	start = stream;

	// Find the end.
	while (increment < length) {

		if (increment + boundlen < length && mm_cmp_cs_eq(stream, bounddata, boundlen) == 0) {
			increment = length;
		}
		else {
			stream++;
			increment++;
		}
	}

	// Make sure we advanced.
	if (stream == start) {
		return pl_null();
	}

	return pl_init(start, stream - start);
}