/**************************************************************************** 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 #include #include #include #include /* for ap_construct_url */ #include #include #include #include #include #include #include #include #include #include #include #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; }