コード例 #1
0
ファイル: rawx.c プロジェクト: korween/oio-sds
static gboolean
_rawx_update_chunk_attrs(chunk_id_t *cid, GSList *attrs, GError **err)
{
	ne_session *s = NULL;
	ne_request *r = NULL;
	int ne_rc;
	gboolean result = FALSE;

	gchar dst[128];
	guint16 port = 0;
	GString *req_str = NULL;
	char idstr[65];

	if (!addr_info_get_addr(&(cid->addr), dst, sizeof(dst), &port))
		return result;

	s = ne_session_create("http", dst, port);
	if (!s) {
		GSETERROR(err, "Failed to create session to rawx %s:%d", dst, port);
		return result;
	}

	ne_set_connect_timeout(s, 10);
	ne_set_read_timeout(s, 30);

	req_str =g_string_new("/rawx/chunk/set/");
	oio_str_bin2hex (&(cid->id), sizeof(cid->id), idstr, sizeof(idstr));
	req_str = g_string_append(req_str, idstr);
	GRID_TRACE("Calling %s", req_str->str);

	r = ne_request_create (s, "GET", req_str->str);
	if (!r) {
		goto end_attr;
	}

	for (; attrs != NULL; attrs = attrs->next) {
		struct chunk_attr_s *attr = attrs->data;
		ne_add_request_header(r, attr->key, attr->val);
	}

	switch (ne_rc = ne_request_dispatch(r)) {
		case NE_OK:
			result = TRUE;
			break;
		case NE_ERROR:
			GSETCODE(err, CODE_INTERNAL_ERROR, "Request NE_ERROR");
			break;
		case NE_TIMEOUT:
			GSETCODE(err, CODE_INTERNAL_ERROR, "Request Timeout");
			break;
		case NE_CONNECT:
			GSETCODE(err, CODE_INTERNAL_ERROR, "Request Connection timeout");
			break;
		default:
			GSETCODE(err, CODE_INTERNAL_ERROR, "Request failed");
			break;
	}

end_attr:
	if (NULL != req_str)
		g_string_free(req_str, TRUE);
	if (NULL != r)
		ne_request_destroy (r);
	if (NULL != s)
		ne_session_destroy (s);

	return result;
}
コード例 #2
0
ファイル: idx_management.c プロジェクト: amogrid/redcurrant
int get_idx_of_service(const char *service_type, struct grid_service_data *service, GError **error) {
	char file_name[strlen(IDX_STORE_PATH) + strlen(service_type) +1];
	struct stat file_stat;
	int rc;
	GArray *known_services = NULL;
	struct grid_service_data *known_service = NULL;
	gboolean idx_found = FALSE;
	int last_idx = 0;

	memset(file_name, '\0', strlen(IDX_STORE_PATH) + strlen(service_type) +1);
	memset(&file_stat, 0, sizeof(struct stat));

	sprintf(file_name, "%s%s_snmp_idx.dat", IDX_STORE_PATH, service_type);

	rc = stat(file_name, &file_stat);
	if (rc < 0 && errno != ENOENT && errno != ENOTDIR) {
		GSETERROR(error, "Failed to stat file [%s] : %s", file_name, strerror(errno));
		return(0);
	}

	known_services = g_array_new(TRUE, TRUE, sizeof(struct grid_service_data));

	if (rc < 0) {

		service->idx = 0;
		g_array_append_val(known_services, *service);

		if (!save_known_service_to_file(known_services, file_name, error)) {
			GSETERROR(error, "Failed to save known services to file [%s]", file_name);
			g_array_free(known_services, TRUE);
			return(0);
		}
	} else {
		guint i;

		read_known_service_from_file(known_services, file_name, error);

		for (i = 0; i < known_services->len; i++) {
			known_service = &g_array_index(known_services, struct grid_service_data, i);

			if (0 == g_ascii_strcasecmp(service->desc, known_service->desc)) {
				service->idx = known_service->idx;
				idx_found = TRUE;
				break;
			} else if (known_service->idx > last_idx)
				last_idx = known_service->idx;
		}

		if (!idx_found) {	
			service->idx = last_idx+1;
			g_array_append_val(known_services, *service);

			if (!save_known_service_to_file(known_services, file_name, error)) {
				GSETERROR(error, "Failed to save known sevices to file [%s]", file_name);
				g_array_free(known_services, TRUE);
				return(0);
			}
		}
	}

	g_array_free(known_services, TRUE);

	return(1); 
}
コード例 #3
0
int
compress_chunk(const gchar* path, const gchar* algo, const gint64 blocksize, gboolean preserve, GError ** error)
{
	GError *local_error = NULL;
	int status = 0;
	gchar *tmp_path = NULL;
	gulong tmp_len;
	guint32 compressed_size = 0;
	struct compression_ctx_s* comp_ctx = NULL;

	guint8* buf = NULL;
	gsize nb_read;
	gsize nb_write;
	GByteArray *gba = NULL;

	gulong checksum = 0;

	FILE *src = NULL;
	FILE *dst = NULL;

	/* Sanity check */
	if(!path || ! algo) {
		GSETERROR(error, "Invalid parameter %p\n", path);
		return status;
	}

	if (!check_uncompressed_chunk(path, &local_error)) {
		if(local_error) {
			GSETERROR(error, "Chunk check failed :\n%s", local_error->message);
			g_clear_error(&local_error);
		} else
			GSETERROR(error, "Chunk check failed : no error\n");
		return status;
	}

	tmp_len = strlen(path) +sizeof(".pending");
	tmp_path = g_malloc0(tmp_len);
	g_snprintf(tmp_path, tmp_len, "%s.pending", path);

	comp_ctx = g_malloc0(sizeof(struct compression_ctx_s));

	if(!init_compression_ctx(comp_ctx, algo)) {
		GSETERROR(error, "Failed to init compression context\n");
		goto end;
	}

	if(!comp_ctx->checksum_initiator(&checksum)) {
		GSETERROR(error, "Failed to init compression checksum\n");
		goto end;
	}

	do {
		int fd;
		if ((fd = open(tmp_path, O_WRONLY|O_CREAT|O_EXCL, 0644)) == -1) {
			GSETERROR(error, "Failed to create pending chunk file (%s)\n", strerror(errno));
			goto end;
		}
		metautils_pclose(&fd);
	} while (0);

	if (!copy_fattr(path, tmp_path, &local_error)) {
		if(local_error) {
			GSETERROR(error, "Failed to copy extended attributes to destination file:\n%s",local_error->message);
			g_clear_error(&local_error);
		}
		else
			GSETERROR(error, "Failed to copy extended attributes to destination file\n");
		goto end;
	}
	DEBUG("Extended attributes copied from src to dst\n");

	if(!set_compress_attr(tmp_path, algo, blocksize, &local_error)) {
		if(local_error) {
			GSETERROR(error, "Error while adding compression attibutes :\n %s", local_error->message);
			g_clear_error(&local_error);
		}
		goto end;
	}

	DEBUG("Compression extended attributes successfully added\n");

	src = fopen(path, "r");
	dst = fopen(tmp_path, "w");

	guint32 bsize32 = blocksize;
	if(comp_ctx->header_writer(dst, bsize32, &checksum, &compressed_size) != 0) {
		GSETERROR(error, "Failed to compress source file\n");
		goto end;
	}

	int src_fd = fileno(src);

	gsize bsize = blocksize;
	buf = g_malloc0(blocksize);

	while(1) {
		nb_read = 0;
		nb_read = read(src_fd, buf, bsize);
		if(nb_read != bsize) {
			/* check if we hit eof */
			if(!feof(src) && ferror(src)) {
				GSETERROR(error, "An error occured while reading data from source file\n");
				goto end;
			} else {
				if(nb_read > 0) {
					gba = g_byte_array_new();
					/* process data */
					if(0 != comp_ctx->data_compressor(buf, nb_read, gba, &checksum)) {
						GSETERROR(error, "Error while compressing data\n");
						goto end;
					}
					/* write compressed data */
					nb_write = 0;
					if ((nb_write = fwrite(gba->data, gba->len, 1, dst)) != 1) {
						GSETERROR(error, "An error occured while writing data in destination file\n");
						goto end;
					}

					compressed_size+=gba->len;
					if(gba) {
						g_byte_array_free(gba, TRUE);
						gba = NULL;
					}
				}
				break;
			}
		} else {
			gba = g_byte_array_new();
			/* process data */
			if(0 != comp_ctx->data_compressor(buf, nb_read, gba, &checksum)) {
				GSETERROR(error, "Error while compressing data\n");
				goto end;
			}

			/* write compressed data */
			nb_write = 0;
			if ((nb_write = fwrite(gba->data, gba->len, 1, dst)) != 1) {
				GSETERROR(error, "An error occured while writing data in destination file\n");
				goto end;
			}

			compressed_size+=gba->len;
			if(gba) {
				g_byte_array_free(gba, TRUE);
				gba = NULL;
			}
		}

	}

	DEBUG("Chunk compressed");

	if(comp_ctx->eof_writer(dst, checksum, &compressed_size) != 0) {
		GSETERROR(error, "Failed to write compressed file EOF marker and checksum\n");
		goto end;
	}

	if(!set_chunk_compressed_size_in_attr(tmp_path, error, compressed_size)) {
		GSETERROR(error, "Failed to set compression information in extended attributes\n");
		goto end;
	}

	DEBUG("Compression footers successfully wrote");

	status = 1;

end:
	if(src) {
		if(fclose(src) != 0)
			WARN("Failed to fclose source file");
		src = NULL;
	}
	if(dst) {
		if(fclose(dst) != 0)
			WARN("Failed to fclose destination file");
		dst = NULL;
	}

	if(status == 1) {
		/* TODO: stat old file, rename, paste stat*/
		if(preserve) {
			/* Need to set old file info in new file */
			TRACE("Renaming and setting good informations to new file...");
			struct stat stat_buf = {0};
			if(stat(path, &stat_buf) == -1) {
				GSETERROR (error, "Failed to stat old file, cannot keep old file information, abort\n");
				/* remove tmp file */
				DEBUG("Removing failed file");
				if(remove(tmp_path) != 0)
					WARN("Failed to remove tmp file [%s]", tmp_path);
				status = 0;
			} else {
				TRACE("Updating Access / Modify / Change informations");
				struct utimbuf ut = {0};
				ut.actime = stat_buf.st_atime;
				ut.modtime = stat_buf.st_mtime;
				if (0 > chown(tmp_path, stat_buf.st_uid, stat_buf.st_gid)) {
					GSETERROR(error, "chown error: (%d) %s", errno, strerror(errno));
					status = 0;
				}
				if (utime(tmp_path, &ut) != 0) {
					GSETERROR(error, "Failed to set correct access time to new file");
					status = 0;
				}
				if(status == 1) {
					if(rename(tmp_path, path) != 0) {
						GSETERROR(error, "Failed to rename tmp file");
						status = 0;
					}
				} else {
					/* remove tmp file */
					DEBUG("Removing failed file");
					if(remove(tmp_path) != 0)
						WARN("Failed to remove tmp file [%s]", tmp_path);
				}
			}
		} else {
			TRACE("Renaming pending file...");
			if(rename(tmp_path, path) != 0) {
				GSETERROR(error, "Failed to rename tmp file");
				status = 0;
			}
			TRACE("Renaming done");
		}
	} else {
		/* remove tmp file */
		DEBUG("Removing failed file");
		if(remove(tmp_path) != 0)
			WARN("Failed to remove tmp file [%s]", tmp_path);
	}

	if(buf)
		g_free(buf);
	if(gba)
		g_byte_array_free(gba, TRUE);

	if(tmp_path)
		g_free(tmp_path);

	return status;

}
コード例 #4
0
int
uncompress_chunk2(const gchar* path, gboolean preserve, gboolean keep_pending,
		GError ** error)
{
	GError *local_error = NULL;
	int status = 0;
	TRACE("Uncompressing [%s]", path);
	gchar *tmp_path = NULL;
	gulong tmp_len;
	gint64 total_read;
	guint8* data = NULL;
	gint64 bufsize, nb_read;
	gint64 current_read;
	struct compressed_chunk_s *cp_chunk = NULL;
	struct compression_ctx_s *comp_ctx = NULL;
	GHashTable *compress_opt = NULL;
	FILE *dst = NULL;

	/* Check chunk exists */

	DEBUG("Checking chunk exists");

	struct stat buf = {0};
	if(stat(path, &buf) == -1) {
		GSETERROR (error, "stat() failed, chunk not found\n");
		goto end;
	}
	DEBUG("File [%s] found", path);

	compress_opt = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, g_free);

	if (!get_compression_info_in_attr(path, error, compress_opt)) {
		GSETERROR(error, "Failed to get compression info in attr, chunk may be not compressed");
		goto end;
	}

	gchar * compression = NULL;
	compression = (gchar*) g_hash_table_lookup(compress_opt, NS_COMPRESSION_OPTION);

	if (compression != NULL && g_ascii_strncasecmp(compression, NS_COMPRESSION_ON, strlen(compression)) != 0) {
		GSETERROR(error, "Chunk not compressed, cannot nothing to do");
		goto end;
	}

	/* init compression method according to algo choice */
	comp_ctx = g_malloc0(sizeof(struct compression_ctx_s));
	init_compression_ctx(comp_ctx, g_hash_table_lookup(compress_opt, NS_COMPRESS_ALGO_OPTION));
	cp_chunk = g_malloc0(sizeof(struct compressed_chunk_s));

	if (comp_ctx->chunk_initiator(cp_chunk, path) != 0) {
		GSETERROR(error, "Failed to init compressed chunk context");
		goto end;
	}

	DEBUG("Chunk check done");

	tmp_len = strlen(path) +sizeof(".pending");
	tmp_path = g_malloc0(tmp_len);
	g_snprintf(tmp_path, tmp_len, "%s.pending", path);

	DEBUG("Checking chunk not busy");

	if(stat(tmp_path, &buf) != -1) {
		DEBUG("Stats failed");
		GSETERROR (error, "stat() success on pending file, cannot process : busy chunk\n");
		goto end;
	}

	do {
	int fd;

	if((fd = open(tmp_path, O_WRONLY|O_CREAT|O_EXCL, 0644)) == -1) {
		GSETERROR(error, "Failed to create pending chunk file (%s)\n", strerror(errno));
		goto end;
	}

	metautils_pclose(&fd);
	} while (0);

	if(!copy_fattr(path, tmp_path, error)) {
		GSETERROR(error, "Failed to copy extended attributes to destination file\n");
		goto end;
	}

	TRACE("xattr copied from src to dst");

	dst = fopen(tmp_path, "w");

	TRACE("Destination file opened");

	gint64 chunk_size;
	chunk_size = g_ascii_strtoll(cp_chunk->uncompressed_size, NULL, 10);

	total_read = 0;

	DEBUG("Starting, total_read = %"G_GINT64_FORMAT", chunk_size = %"G_GINT64_FORMAT, total_read, chunk_size);

	while(total_read < chunk_size) {
		bufsize = MIN(DECOMPRESSION_MAX_BUFSIZE, (chunk_size - total_read));
		data = g_malloc0(bufsize);
		DEBUG("New buffer allocated sized %"G_GINT64_FORMAT" bytes", bufsize);
		nb_read = 0;
		current_read = 0;
		while(nb_read < bufsize) {
			current_read = comp_ctx->data_uncompressor(cp_chunk, 0, data + nb_read, bufsize - nb_read, &local_error);
			DEBUG("Currently read %"G_GINT64_FORMAT" bytes", current_read);
			if(current_read < 0) {
				if(local_error) {
					GSETERROR(error, "An error occured while decompressing chunk : %s", local_error->message);
					g_clear_error(&local_error);
				} else
					GSETERROR(error, "An error occured while decompressing chunk\n");
				goto end;
			} else if (current_read == 0) {
				/* Premature end of file, will still write to pending */
				WARN("Read 0 bytes, original chunk may have been truncated");
				break;
			}
			nb_read += current_read;
		}
		TRACE("buffer filled");
		errno = 0;
		/* write buf to dst file */
		if(nb_read > 0 && fwrite(data, nb_read, 1, dst) != 1) {
			GSETERROR(error, "An error occured while writing data in destination file: %s",
					strerror(errno));
			goto end;
		}
		if (data) {
			g_free(data);
			data = NULL;
		}
		if (nb_read > 0)
			total_read += nb_read;
		else
			break;
	}

	if(!comp_ctx->integrity_checker(cp_chunk)) {
		GSETERROR(error, "Seems there is an error in decompression, invalid checksum\n");
		goto end;
	}

	status = 1;

end:
	if(dst) {
		if(fclose(dst) != 0)
			WARN("Failed to fclose destination file");
		dst = NULL;
	}

	if(status == 1) {
		if(preserve) {
			/* Need to set old file info in new file */
			TRACE("Updating Access / Modify / Change informations");
			struct utimbuf ut = {0};
			ut.actime = buf.st_atime;
			ut.modtime = buf.st_mtime;
			if (0 > chown(tmp_path, buf.st_uid, buf.st_gid)) {
				GSETERROR(error, "chown error: (%d) %s", errno, strerror(errno));
				status = 0;
			}
			if(utime(tmp_path, &ut) != 0) {
				GSETERROR(error, "Failed to set correct access time to new file");
				status = 0;
			}
			if(status == 1) {
				if(rename(tmp_path, path) != 0) {
					GSETERROR(error, "Failed to rename tmp file");
					status = 0;
				}
			} else if (keep_pending) {
				INFO("Temporary file kept: %s", tmp_path);
			} else {
				/* remove tmp file */
				DEBUG("Removing failed file");
				if(remove(tmp_path) != 0)
					WARN("Failed to remove tmp file [%s]", tmp_path);
			}
		} else {
			DEBUG("Renaming pending file\n");
			if(rename(tmp_path, path) != 0) {
				GSETERROR(error, "Failed to rename tmp file");
				status = 0;
			}
		}
	} else if (keep_pending) {
		INFO("Temporary file kept: %s", tmp_path);
	} else {
		/* remove tmp file */
		DEBUG("Removing pending file\n");
		if(remove(tmp_path) != 0)
			WARN("Failed to remove tmp file [%s]", tmp_path);
	}

	if(compress_opt)
		g_hash_table_destroy(compress_opt);

	if(data)
		g_free(data);

	if(tmp_path)
		g_free(tmp_path);

	return status;
}
コード例 #5
0
int read_content_length(worker_t *worker, GError **error) {
        ssize_t rl;
        worker_data_t *data = NULL;
        http_session_t *http_session = NULL;
        unsigned int content_length;
        char *header_end = NULL;
        char *content_length_line = NULL;
        char *buffer = NULL;

        TRACE("Executing read_content_length worker");

        data = &(worker->data);
        http_session = (http_session_t*)data->session;
        header_end = strstr(data->buffer, "\r\n\r\n");
        content_length_line = strstr(data->buffer, "Content-Length");

        if (content_length_line && header_end) {

                if (sscanf(content_length_line, CONTENT_LENGTH_PATTERN, &content_length) == 1) {
                        DEBUG("Found a Content-Length header with value %u", content_length);

                        /* Prepare the buffer */
                        buffer = g_strdup(header_end + 4);
                        CLEAR_WORKER_DATA(data);

                        data->buffer_size = content_length;
                        data->buffer = g_try_malloc0(data->buffer_size+1);
                        if (data->buffer == NULL) {
                                GSETERROR(error, "Memory allocation failure");
                                g_free(buffer);
                                goto error_alloc_buffer;
                        }

                        strcpy(data->buffer, buffer);
                        data->done = strlen(buffer);

                        g_free(buffer);

                        worker->func = read_response_body;

                        return(1);
                }

        } else if (header_end) {
                GSETERROR(error, "Header Content-Length was not found in headers");
                goto error_content_length_not_found;
        }

        if (data->done >= data->buffer_size) {
                data->buffer_size += DEFAULT_BUFFER_SIZE;
                data->buffer = g_try_realloc(data->buffer, data->buffer_size+1); /* Allocate 1 byte for \0 */
                if (data->buffer == NULL) {
                        GSETERROR(error, "Memory allocation failure");
                        goto error_alloc_buffer;
                } else {
                        /* Init newly alloced memory */
                        memset(data->buffer + (data->buffer_size - DEFAULT_BUFFER_SIZE), 0, DEFAULT_BUFFER_SIZE + 1);
                }
        }

        rl = read(data->fd, data->buffer + data->done, data->buffer_size - data->done);
        if (rl < 0) {
                GSETERROR(error, "Read on socket failed with error : %s", strerror(errno));
                goto error_read;
        }

        if (rl == 0 && data->done < data->buffer_size) {
                GSETERROR(error, "Connection closed while reading Content-Length");
                goto error_read;
        }

        data->done += rl;

        return(1);

error_content_length_not_found:
error_read:
        g_free(data->buffer);
error_alloc_buffer:

        return(http_session->error_handler(worker, error));
}
コード例 #6
0
int write_request(worker_t *worker, GError **error) {
	ssize_t wl;
	worker_data_t *data = NULL;
	http_session_t *http_session;
	char request[HTTP_REQ_MAX_SIZE];

	TRACE("Executing write_request worker");

        data = &(worker->data);
	http_session = (http_session_t*)data->session;
	memset(request, '\0', HTTP_REQ_MAX_SIZE);

        if (data->buffer == NULL) {
		switch (http_session->method) {
			case E_GET :
				snprintf(request, HTTP_REQ_MAX_SIZE, "GET %s HTTP/1.0%s%s", http_session->url, EOL, EOL);
				break;
			case E_POST :
				break;
			default :
				break;
		}

		DEBUG("Sending HTTP request [%s]", request);

                data->buffer_size = strlen(request);

                data->buffer = g_try_malloc0(data->buffer_size);
                if (data->buffer == NULL) {
                        GSETERROR(error, "Memory allocation failure");
                        goto error_alloc_buffer;
                }

		memcpy(data->buffer, request, data->buffer_size);
	}

        wl = write(data->fd, data->buffer + data->done, data->buffer_size - data->done);
        if (wl < 0) {
                GSETERROR(error, "Write on socket failed with error : %s", strerror(errno));
                goto error_write;
        }

        data->done += wl;

        if (data->done >= data->buffer_size) {

                g_free(data->buffer);
                data->buffer = NULL;
                data->buffer_size = 0;
                data->done = 0;

                /* Schedule next worker */
                worker->func = read_http_status;

                if (!change_fd_events_in_io_scheduler(worker, EPOLLIN, error)) {
                        GSETERROR(error, "Failed to change polling event on fd %d", data->fd);
                        goto error_sched;
                }
        }

        return(1);

error_sched:
error_write:
        g_free(data->buffer);
error_alloc_buffer:

        return(http_session->error_handler(worker, error));
}
コード例 #7
0
int read_http_status(worker_t *worker, GError **error) {
        ssize_t rl;
        worker_data_t *data = NULL;
	http_session_t *http_session = NULL;
        unsigned int http_status;

        TRACE("Executing read_http_status worker");

        data = &(worker->data);
	http_session = (http_session_t*)data->session;

        if (data->buffer == NULL) {
                data->buffer_size = DEFAULT_BUFFER_SIZE;
                data->buffer = g_try_malloc0(data->buffer_size+1);      /* Allocate 1 byte for \0 */
                if (data->buffer == NULL) {
                        GSETERROR(error, "Memory allocation failure");
                        goto error_alloc_buffer;
                }
        } else if (data->done >= data->buffer_size) {
                data->buffer_size += DEFAULT_BUFFER_SIZE;
                data->buffer = g_try_realloc(data->buffer, data->buffer_size+1); /* Allocate 1 byte for \0 */
                if (data->buffer == NULL) {
                        GSETERROR(error, "Memory allocation failure");
                        goto error_alloc_buffer;
                } else {
                        /* Init newly alloced memory */
                        memset(data->buffer + (data->buffer_size - DEFAULT_BUFFER_SIZE), 0, DEFAULT_BUFFER_SIZE + 1);
                }
        }

        rl = read(data->fd, data->buffer + data->done, data->buffer_size - data->done);
        if (rl < 0) {
                GSETERROR(error, "Read on socket failed with error : %s", strerror(errno));
                goto error_read;
        }

        data->done += rl;

        /* Make sure we read the first line completely */
        if (strstr((char*)data->buffer, EOL)) {
                if (sscanf((char*)data->buffer, HTTP_STATUS_PATTERN, &http_status) == 1) {
                        DEBUG("Found HTTP status %u", http_status);

                        if (http_status == HTTP_STATUS_OK) {
                                worker->func = read_content_length;

                        } else {
                                GSETERROR(error, "HTTP request failed with status %d", http_status);
				goto error_status;
                        }

                } else {
                        GSETERROR(error, "Failed to read HTTP status");
			goto error_status;
                }
        } else if (rl == 0) {
                GSETERROR(error, "Connection closed while reading HTTP status");
                goto error_read;
        }

        return(1);

error_read:
error_status:
        g_free(data->buffer);
error_alloc_buffer:

        return(http_session->error_handler(worker, error));
}
コード例 #8
0
ファイル: sock.c プロジェクト: InGenious-Justice/oio-sds
gint
accept_add_local (ACCEPT_POOL ap, const gchar *l, GError **err)
{
	struct working_parameter_s wrkParam;
	struct sockaddr_un sun;
	int srv = -1;
	
	if (!l || !(*l))
	{
		GSETERROR(err,"invalid parameter");
		goto errorLabel;
	}

	/*parse the URL*/
	init_socket_options_defaults( l, &wrkParam );
	parse_socket_options( &wrkParam );

	/*try to stat the file*/
	if (-1 == check_socket_is_absent( &wrkParam, err )) {
		GSETERROR(err,"A socket seems already present at [%s]", wrkParam.path.ptr);
	}

	/*open and bind the socket*/

	if (-1==(srv=socket(PF_UNIX, SOCK_STREAM, 0)))
	{
		GSETERROR(err,"Cannot open a new socket PF_UNIX : %s", strerror(errno));
		goto errorLabel;
	}
	
	if (!sock_set_reuseaddr(srv, TRUE)) {
		GSETERROR(err,"Cannot set SO_REUSEADDR on %d [%s] (%s)", srv, l, strerror(errno));
		goto errorLabel;
	}

	fcntl(srv, F_SETFL, O_NONBLOCK|fcntl(srv, F_GETFL));

	sun.sun_family = PF_LOCAL;
	strncpy(sun.sun_path, wrkParam.path.ptr, sizeof(sun.sun_path));

	if (-1==bind (srv, (struct sockaddr*) &sun, sizeof(struct sockaddr_un)))
	{
		GSETERROR(err,"cannot bind srv=%d to %s (%s)", srv, l, strerror(errno));
		goto errorLabel;
	}
	
	if (-1==listen (srv,AP_BACKLOG))
	{
		GSETERROR(err,"cannot listen to inbound connections : %s",  strerror(errno));
		goto errorLabel;
	}
	
	if (!accept_add_any(ap,srv,err))
	{
		GSETERROR(err,"Cannot monitor the local server");
		goto errorLabel;
	}

	/*change socket rights*/
	if (0 != chmod(wrkParam.path.ptr,wrkParam.mode)) {
		int errsav = errno;
		ERROR("Failed to set mode [%o] on UNIX socket [%s] : %s", wrkParam.mode, wrkParam.path.ptr, strerror(errsav));
		SRV_SEND_WARNING("server","UNIX socket might be not accessible : failed to set mode [%o] on UNIX socket [%s] (%s)",
			wrkParam.mode, wrkParam.path.ptr, strerror(errsav));
	}
	
	INFO("socket srv=%d %s now monitored", srv, _get_family_name(FAMILY(&sun)));

	return 1;
errorLabel:
	if (srv>=0)
		metautils_pclose(&srv);
	return 0;
}
コード例 #9
0
ファイル: message.c プロジェクト: dibaggioj/oio-sds
int
send_request(request_t *req, response_t *resp, GError **error)
{
    int fd;
    size_t size_to_send, u_size_sent, u_size_read;
    gint size_sent, size_read;
    message_t message;
    void *buff = NULL;

    memset(&message, 0, sizeof(message_t));

    if (!build_message_from_request(&message, req, error)) {
        GSETERROR(error, "Failed to build message");
        return(0);
    }

    if (0 > (fd = gridagent_connect(error))) {
        GSETERROR(error, "Connection to agent failed");
        goto error_connect;
    }

    size_to_send = message.length + sizeof(message.length);
    buff = g_malloc0(size_to_send);
    memcpy(buff, &(message.length), sizeof(message.length));
    memcpy(buff + sizeof(message.length), message.data, message.length);

    size_sent = sock_to_write(fd, CONNECT_TIMEOUT, buff, size_to_send, error);
    if (size_sent<0) {
        GSETERROR(error, "Failed to send all data to agent");
        goto error_write;
    }
    if ((u_size_sent=size_sent) < size_to_send) {
        GSETERROR(error, "Failed to send all data to agent");
        goto error_write;
    }

    /* Clean message to reuse it */
    message_clean( &message);
    size_read = sock_to_read_size(fd, SOCKET_TIMEOUT, &(message.length), sizeof(message.length), error);
    if ((u_size_read=size_read) < sizeof(message.length)) {
        GSETERROR(error, "Failed to read message size");
        goto error_read_size;
    }

    message.data = g_malloc0(message.length);
    size_read = sock_to_read_size(fd, SOCKET_TIMEOUT, message.data, message.length, error);
    if ((u_size_read=size_read) < message.length) {
        GSETERROR(error, "Failed to read all data from agent");
        goto error_read;
    }

    if (!read_response_from_message(resp, &message, error)) {
        GSETERROR(error, "Failed to extract response from message");
        goto error_read_resp;
    }

    metautils_pclose(&fd);

    g_free(buff);

    message_clean( &message);
    return(1);

error_read_resp:
error_read:
error_read_size:
error_write:
    if (buff)
        g_free(buff);
    metautils_pclose(&fd);
error_connect:
    message_clean( &message);
    return(0);
}
コード例 #10
0
gint
sock_to_read(int fd, gint ms, void *buf, gsize bufSize, GError ** err)
{
	if (VTABLE.to_read)
		return VTABLE.to_read(fd, ms, buf, bufSize, err);

#define READ() do { \
		rc = metautils_syscall_read(fd, buf, bufSize); \
		if (rc > 0) \
			return rc; \
		if (rc == 0) { \
			GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d closed", fd); \
			return 0; \
		} \
		if (errno != EAGAIN && errno != EINTR) { \
			GSETCODE(err, errno_to_errcode(errno), "Read error (%s)", strerror(errno)); \
			return -1; \
		} \
	} while (0)

	gint rc;

	if (fd < 0 || !buf || bufSize <= 0) {
		GSETERROR(err, "invalid parameter");
		return -1;
	}

	/* on tente un premier READ, qui s'il reussit, nous epargne un appel a POLL */
	READ();

	/* pas de data en attente, donc attente protegee par le poll */
	for (;;) {
		struct pollfd p;

		p.fd = fd;
		p.events = POLLIN;
		p.revents = 0;

		/*wait for something to happen */
		rc = metautils_syscall_poll(&p, 1, ms);
		if (rc == 0) {	/*timeout */
			GSETCODE(err, ERRCODE_CONN_TIMEOUT, "Socket timeout");
			return -1;
		}

		if (rc < 0 && errno != EINTR) {	/*error */
			GSETCODE(err, errno_to_errcode(errno), "Socket error (%s)", strerror(errno));
			return -1;
		}
		if (rc == 1) {
			if (p.revents & POLLHUP && !(p.revents & POLLIN)) {
				GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d closed", fd);
				return 0;
			}
			if (p.revents & POLLERR) {
				int sock_err = socket_get_errcode(fd);
				GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d error : (%d) %s", fd, sock_err, strerror(sock_err));
				return 0;
			}
			READ();
		}
	}
}
コード例 #11
0
gint
sock_to_write(int fd, gint ms, void *buf, gsize bufSize, GError ** err)
{
	if (VTABLE.to_write)
		return VTABLE.to_write(fd, ms, buf, bufSize, err);

#define WRITE() do { \
		written = metautils_syscall_write(fd, ((guint8 *)buf) + nbSent, bufSize - nbSent); \
		if (written > 0) { \
			ui_written = written; \
			nbSent += ui_written; \
		} \
		if (written < 0) { \
			if (errno != EAGAIN && errno != EINTR) { \
				GSETERROR(err, "Write error (%s)", strerror(errno)); \
				return -1; \
			} \
		} \
} while (0)

	gsize ui_written;
	ssize_t written;
	gsize nbSent = 0;

	if (fd < 0 || !buf || bufSize <= 0) {
		GSETERROR(err, "invalid parameter");
		return -1;
	}

	WRITE();

	while (nbSent < bufSize) {
		int rc_poll;
		struct pollfd p;

		p.fd = fd;
		p.events = POLLOUT | POLLERR | POLLHUP | POLLNVAL;
		p.revents = 0;

		errno = 0;
		rc_poll = metautils_syscall_poll(&p, 1, ms);

		if (rc_poll == 0) {	/*timeout */
			GSETCODE(err, ERRCODE_CONN_TIMEOUT, "Socket timeout");
			return (-1);
		}

		if (rc_poll == -1) {	/*poll error */
			if (errno != EINTR) {
				GSETERROR(err, "Socket error (%s) after %"G_GSIZE_FORMAT" bytes written", strerror(errno), nbSent);
				return (-1);
			}
			else {
				TRACE("poll interrupted (%s)", strerror(errno));
				continue;
			}
		}

		/*poll success */
		if (p.revents & POLLNVAL) {
			GSETERROR(err, "Socket (%d) is invalid after %"G_GSIZE_FORMAT" bytes sent", fd, nbSent);
			return -1;
		}
		if (p.revents & POLLERR) {
			int sock_err = socket_get_errcode(fd);
			GSETERROR(err, "Socket (%d) error after %"G_GSIZE_FORMAT" bytes written : (%d) %s", fd, nbSent, sock_err, strerror(sock_err));
			return -1;
		}
		if ((p.revents & POLLHUP)) {
			GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket (%d) closed after %"G_GSIZE_FORMAT" bytes written", fd, nbSent);
			return -1;
		}

		WRITE();
	}

	return nbSent;
}