244 lines
5.7 KiB
C
244 lines
5.7 KiB
C
/****************************************************************************
|
|
|
|
mod_dav_pgsql (DASL) for apache 2.X
|
|
CopyRight(C) 2005 SolutionBox Inc. All Rights reserved.
|
|
CopyRight(C) 2006 Netomi Inc. All Rights reserved.
|
|
Author : elenoa lazyfake (elenoa@solutionbox.co.kr)
|
|
|
|
$Id: transfer.c,v 1.5 2007/02/22 08:22:13 elenoa Exp $
|
|
|
|
Redistribution and use in source and binary forms, with or with out
|
|
modification, are not permitted in outside of SolutionBox Inc.
|
|
|
|
****************************************************************************/
|
|
|
|
#include <httpd.h>
|
|
#include <http_config.h>
|
|
#include <http_protocol.h>
|
|
#include <http_log.h>
|
|
#include <http_core.h> /* for ap_construct_url */
|
|
#include <http_request.h>
|
|
|
|
#include <apr_strings.h>
|
|
#include <apr_signal.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/ipc.h>
|
|
#include <sys/msg.h>
|
|
#include <pwd.h>
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
|
|
#include "dav_repos.h"
|
|
#include "dbms.h"
|
|
#include "util.h"
|
|
#include "share_statistic.h"
|
|
#include "transfer.h"
|
|
|
|
struct msg_mgnt {
|
|
key_t key;
|
|
int handle;
|
|
};
|
|
|
|
/* transfer queue log definition */
|
|
|
|
static int dav_initialize_transfer_log_queue(server_rec *s, apr_pool_t *p)
|
|
{
|
|
#ifdef __USE_TRANSFER_LOG__
|
|
#endif // __USE_TRANSFER_LOG__
|
|
return OK;
|
|
}
|
|
|
|
static apr_status_t dav_cleanup_transfer_log_queue(void *data)
|
|
{
|
|
/* do nothing. want something? */
|
|
return 0;
|
|
}
|
|
|
|
int dav_transfer_log_generate(request_rec *r)
|
|
{
|
|
#ifdef __USE_TRANSFER_LOG__
|
|
#endif // __USE_TRANSFER_LOG__
|
|
|
|
return OK;
|
|
}
|
|
|
|
/* transfer progress queue definition */
|
|
#define MSG_PROGESS_KEY 642656000
|
|
|
|
struct Transfer_stat {
|
|
long mtype; // 고정으로 1
|
|
uint32_t timestamp;
|
|
|
|
short int nInOut; // Inbount : 0 Outbout: non zero
|
|
int nUserSeq;
|
|
int nServiceSeq;
|
|
uint64_t sizeTransfer; // opendav에서는 순수 컨텐츠 전송량을 세팅해서 전송 하면 됨.
|
|
// fimngd에서 rc_statd로 올려 줄때는 해당 변수에 1.1을 곱한 값도 별도로 전달 해줘야 함
|
|
// mrtg와 유사한 형태를 맞추기 위해서 1.1을 곱함
|
|
char filename_hash[128]; // 기존 message queue에서는 64byte 사용하고 있었지만, 추 후 변경 시 overflow를 방지하기 위해 일단 128byte로 결정 함
|
|
};
|
|
|
|
static struct msg_mgnt *progress_list = NULL;
|
|
|
|
static unsigned short cur_pos = 0;
|
|
static unsigned short max_progess = 0;
|
|
|
|
static int dav_initialize_transfer_progress_queue(server_rec *s, apr_pool_t *p)
|
|
{
|
|
/* get dav_repos_server_conf structure */
|
|
dav_repos_server_conf *dsc;
|
|
dsc = dav_repos_get_server_conf(s);
|
|
if (!dsc) {
|
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: dav_initialize_transfer_progress_queue: "
|
|
"fail to read config file");
|
|
return !OK;
|
|
}
|
|
|
|
if (dsc->max_progress <= 0) {
|
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: dav_initialize_transfer_progress_queue: "
|
|
"MaxProgess <= 0 (%d)", dsc->max_progress);
|
|
return !OK;
|
|
}
|
|
|
|
max_progess = dsc->max_progress;
|
|
progress_list = malloc(sizeof(struct msg_mgnt) * max_progess);
|
|
if (progress_list == NULL)
|
|
{
|
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: dav_initialize_transfer_progress_queue: "
|
|
"Memory allocation failure");
|
|
return !OK;
|
|
}
|
|
|
|
int i = 0;
|
|
for (i = 0; i < max_progess; i++)
|
|
{
|
|
/* create or attach queue */
|
|
progress_list[i].key = MSG_PROGESS_KEY + i;
|
|
if ((progress_list[i].handle = msgget(progress_list[i].key, 0644 | IPC_EXCL)) == -1)
|
|
{
|
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "OPENDAV: dav_initialize_transfer_progress_queue: cannot attach [%d][%s]", i, strerror(errno));
|
|
return !OK;
|
|
}
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
static apr_status_t dav_cleanup_transfer_progress_queue(void *data)
|
|
{
|
|
if (progress_list)
|
|
free(progress_list);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int dav_transfer_progess_set_value(struct Transfer_stat *ts)
|
|
{
|
|
if (progress_list == NULL)
|
|
{
|
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_transfer_progess_set_value: progress list is NULL. [%s]", ts->filename_hash);
|
|
return !OK;
|
|
}
|
|
|
|
if ((++cur_pos) >= max_progess)
|
|
cur_pos = 0;
|
|
|
|
int err = errno;
|
|
int i = 0;
|
|
|
|
for (i = cur_pos; i < max_progess; i++)
|
|
{
|
|
if (msgsnd(progress_list[i].handle, (const void *)ts, sizeof(struct Transfer_stat), IPC_NOWAIT) != -1)
|
|
return OK;
|
|
err = errno;
|
|
|
|
if (err == EINTR)
|
|
{
|
|
apr_sleep(10000);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < max_progess; i++)
|
|
{
|
|
if (msgsnd(progress_list[i].handle, (const void *)ts, sizeof(struct Transfer_stat), IPC_NOWAIT) != -1)
|
|
return OK;
|
|
err = errno;
|
|
|
|
if (err == EINTR)
|
|
{
|
|
apr_sleep(10000);
|
|
}
|
|
}
|
|
|
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_transfer_progess_set_value: fail. [%s] [%s(%d)]", ts->filename_hash, strerror(err), err);
|
|
return !OK;
|
|
}
|
|
|
|
int dav_transfer_progess_generate(request_rec *r, int bound, apr_size_t size, apr_size_t org_sent)
|
|
{
|
|
char *volume = r->user;
|
|
|
|
if (r == NULL) return OK;
|
|
|
|
if (size < 0) return OK;
|
|
|
|
if (!volume) return OK;
|
|
|
|
acct_info acctinfo;
|
|
memset(&acctinfo, 0x00, sizeof(acct_info));
|
|
|
|
if (at_split(r->user, &acctinfo) <= 0)
|
|
return OK;
|
|
|
|
struct Transfer_stat ts = { 0 };
|
|
|
|
ts.nServiceSeq = atoi(acctinfo.szVolumeID);
|
|
ts.nUserSeq = atoi(acctinfo.szUserID);
|
|
|
|
ts.timestamp = STAT_STAMP(time(0));
|
|
|
|
if (ts.nServiceSeq == 0 && ts.nUserSeq == 0)
|
|
return OK;
|
|
|
|
ts.mtype = 1;
|
|
ts.nInOut = bound;
|
|
ts.sizeTransfer = size;
|
|
|
|
strcpy(ts.filename_hash, r->canonical_filename);
|
|
|
|
if (dav_transfer_progess_set_value(&ts) == !OK)
|
|
{
|
|
//ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "dav_transfer_progess_set_value: fail. [%s]", r->uri);
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
|
|
/************************/
|
|
/* initialize functions */
|
|
|
|
int dav_initialize_transfer_queue(server_rec *s, apr_pool_t *p)
|
|
{
|
|
dav_initialize_transfer_log_queue(s, p);
|
|
if (dav_initialize_transfer_progress_queue(s, p) != OK)
|
|
return !OK;
|
|
|
|
return OK;
|
|
}
|
|
|
|
apr_status_t dav_cleanup_transfer_queue(void *data)
|
|
{
|
|
/* do nothing. want something? */
|
|
dav_cleanup_transfer_log_queue(data);
|
|
dav_cleanup_transfer_progress_queue(data);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|