Files
interactive/fhs/sh-opendav/transfer.c
2026-08-07 17:38:18 +09:00

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;
}