86badd32 |
#include "makuosan.h"
|
634a23d7 |
static void mrecv_req(mdata *data, struct sockaddr_in *addr);
static void mrecv_ack(mdata *data, struct sockaddr_in *addr);
/******************************************************************
*
* Receive common functions (private)
*
*******************************************************************/ |
86badd32 |
static mfile *mrecv_mfdel(mfile *m)
{
mfile *r;
if(!m)
return(NULL);
r = m->next;
if(m->fd != -1){
close(m->fd);
m->fd = -1;
if(S_ISREG(m->fs.st_mode))
mremove(moption.base_dir, m->tn);
}
if(m->mark){
free(m->mark);
m->mark = NULL;
}
mfdel(m);
return(r);
}
|
634a23d7 |
static int mrecv_decrypt(mdata *data, struct sockaddr_in *addr)
{
int i;
MD5_CTX ctx;
uint8_t hash[16];
if(data->head.flags & MAKUO_FLAG_CRYPT){
if(!moption.cryptena){ |
8f9aeac1 |
lprintf(0, "%s: recv encrypt packet from %s. I have not key!", __func__, inet_ntoa(addr->sin_addr)); |
634a23d7 |
return(-1);
}
if(data->head.szdata){
for(i=0;i<data->head.szdata;i+=8){
BF_decrypt((BF_LONG *)(data->data + i), &EncKey);
}
MD5_Init(&ctx);
MD5_Update(&ctx, data->data, data->head.szdata);
MD5_Final(hash, &ctx);
if(memcmp(hash,data->head.hash,16)){ |
8f9aeac1 |
lprintf(0, "%s: protocol checksum error from %s\n", __func__, inet_ntoa(addr->sin_addr)); |
634a23d7 |
return(-1);
}
}
}
return(0);
}
static int mrecv_packet(int s, mdata *data, struct sockaddr_in *addr)
{
int recvsize;
socklen_t addr_len;
while(1){
addr_len = sizeof(struct sockaddr_in);
recvsize = recvfrom(s, data, sizeof(mdata), 0, (struct sockaddr *)addr, &addr_len);
if(recvsize != -1){
break;
}else{
if(errno == EAGAIN || errno == EINTR){
continue;
}else{ |
8f9aeac1 |
lprintf(0, "%s: recv error from %s\n", __func__, inet_ntoa(addr->sin_addr)); |
634a23d7 |
return(-1);
}
}
}
if(recvsize < sizeof(data->head)){ |
8f9aeac1 |
lprintf(0, "%s: recv head size error\n", __func__); |
634a23d7 |
return(-1);
}
data->head.szdata = ntohs(data->head.szdata);
data->head.flags = ntohs(data->head.flags);
data->head.reqid = ntohl(data->head.reqid);
data->head.seqno = ntohl(data->head.seqno);
if(data->head.vproto != PROTOCOL_VERSION){ |
8f9aeac1 |
lprintf(0, "%s: protocol version error(%d != %d) from %s\n", __func__, |
634a23d7 |
data->head.vproto, PROTOCOL_VERSION, inet_ntoa(addr->sin_addr));
return(-1);
}
return(mrecv_decrypt(data, addr));
}
/******************************************************************
*
* Receive common functions (public)
*
*******************************************************************/
void mrecv(int s)
{
mdata data;
struct sockaddr_in addr;
if(mrecv_packet(s, &data, &addr) == -1){
return;
}
if(data.head.flags & MAKUO_FLAG_ACK){
mrecv_ack(&data, &addr);
}else{
mrecv_req(&data, &addr);
}
}
void mrecv_gc()
{
mhost *t = members;
mfile *m = mftop[1];
/* file timeout */
while(m){
if(mtimeout(&(m->lastrecv), MAKUO_RECV_GCWAIT)){ |
8f9aeac1 |
lprintf(0,"%s: mfile object GC state=%d %s\n", __func__, m->mdata.head.nstate, m->fn); |
634a23d7 |
m = mrecv_mfdel(m);
continue;
}
m = m->next;
}
/* pong timeout */
while(t){
if(!mtimeout(&(t->lastrecv), MAKUO_PONG_TIMEOUT)){
t = t->next;
}else{ |
8f9aeac1 |
lprintf(0,"%s: pong timeout %s\n", __func__, t->hostname); |
634a23d7 |
if(t->next){
t = t->next;
member_del(t->prev);
}else{
member_del(t);
t = NULL;
}
}
}
}
/******************************************************************
* |
8f9aeac1 |
* ack receive functions (for source node tasks) |
634a23d7 |
*
*******************************************************************/ |
8f9aeac1 |
static int mrecv_ack_search(mhost **lpt, mfile **lpm, mdata *data, struct sockaddr_in *addr) |
634a23d7 |
{
mhost *t;
mfile *m;
*lpt = NULL;
*lpm = NULL;
t = member_add(&addr->sin_addr, NULL);
if(!t){ |
8f9aeac1 |
lprintf(0, "%s: member not found %s\n", __func__, inet_ntoa(addr->sin_addr));
return(-1); |
634a23d7 |
}
for(m=mftop[0];m;m=m->next)
if(m->mdata.head.reqid == data->head.reqid)
break;
if(!m){ |
8f9aeac1 |
lprintf(4, "%s: mfile not found rid=%06d state=%02d %s(%s)\n", __func__, |
634a23d7 |
data->head.reqid, data->head.nstate, inet_ntoa(addr->sin_addr), t->hostname); |
8f9aeac1 |
return(-1); |
634a23d7 |
}
*lpt = t;
*lpm = m; |
8f9aeac1 |
return(0); |
634a23d7 |
}
static void mrecv_ack_report(mfile *m, mhost *h, mdata *data)
{
if(data->head.nstate == MAKUO_RECVSTATE_OPENERROR){
cprintf(0, m->comm, "%s: file open error %s\n", h->hostname, m->fn); |
8f9aeac1 |
lprintf(0, "%s: file open error rid=%06d state=%02d %s(%s) %s\n", __func__, |
634a23d7 |
data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
}
if(data->head.nstate == MAKUO_RECVSTATE_WRITEERROR){
cprintf(0, m->comm, "%s: file write error %s\n", h->hostname, m->fn); |
8f9aeac1 |
lprintf(0, "%s: file write error rid=%06d state=%02d %s(%s) %s\n", __func__, |
634a23d7 |
data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
}
if(data->head.nstate == MAKUO_RECVSTATE_CLOSEERROR){
cprintf(0, m->comm, "%s: file close error %s\n", h->hostname, m->fn); |
8f9aeac1 |
lprintf(0, "%s: file close error rid=%06d state=%02d %s(%s) %s\n", __func__, |
634a23d7 |
data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
}
}
static void mrecv_ack_ping(mdata *data, struct sockaddr_in *addr)
{
member_add(&addr->sin_addr, data);
}
static void mrecv_ack_file(mdata *data, struct sockaddr_in *addr)
{
mhost *t;
mfile *m;
|
8f9aeac1 |
if(mrecv_ack_search(&t, &m, data, addr)){
return;
} |
634a23d7 |
mtimeget(&m->lastrecv);
if(data->head.nstate == MAKUO_RECVSTATE_IGNORE){
cprintf(4, m->comm, "%s: file update ignore %s\n", t->hostname, m->fn); |
8f9aeac1 |
lprintf(0, "%s: file update ignore rid=%06d state=%02d %s(%s) %s\n", __func__, |
634a23d7 |
data->head.reqid, data->head.nstate, inet_ntoa(t->ad), t->hostname, m->fn);
}
if(data->head.nstate == MAKUO_RECVSTATE_OPEN){
uint32_t *d = (uint32_t *)(data->data);
while(d < (uint32_t *)&data->data[data->head.szdata]){
seq_addmark(m, *d, (*d) + 1);
d++;
}
}
t->state = data->head.nstate;
mrecv_ack_report(m, t, data);
}
static void mrecv_ack_md5(mdata *data, struct sockaddr_in *addr)
{
mhost *t;
mfile *m;
mrecv_ack_search(&t, &m, data, addr);
if(!t || !m){
return;
}
mtimeget(&m->lastrecv);
if(t->state != data->head.nstate){
if(data->head.nstate == MAKUO_RECVSTATE_MD5OK){
cprintf(1, m->comm, "%s: OK %s\r\n", t->hostname, m->fn); |
8f9aeac1 |
lprintf(1, "%s: OK %s\n", __func__, m->fn); |
634a23d7 |
}
if(data->head.nstate == MAKUO_RECVSTATE_MD5NG){
cprintf(0, m->comm, "%s: NG %s\r\n", t->hostname, m->fn); |
8f9aeac1 |
lprintf(0, "%s: NG %s\n", __func__, m->fn); |
634a23d7 |
}
}
t->state = data->head.nstate;
mrecv_ack_report(m, t, data);
}
static void mrecv_ack(mdata *data, struct sockaddr_in *addr)
{
switch(data->head.opcode){
case MAKUO_OP_PING:
mrecv_ack_ping(data, addr);
break; |
8f9aeac1 |
case MAKUO_OP_SEND: |
634a23d7 |
mrecv_ack_file(data, addr);
break;
case MAKUO_OP_MD5:
mrecv_ack_md5(data, addr);
break; |
8f9aeac1 |
/* 機能追加はここへ */ |
634a23d7 |
}
}
/******************************************************************
* |
8f9aeac1 |
* Request receive functions (for destination node tasks) |
634a23d7 |
*
*******************************************************************/
static void mrecv_req_ping(mdata *data, struct sockaddr_in *addr) |
86badd32 |
{
mping *p;
mfile *m; |
634a23d7 |
char buff[MAKUO_HOSTNAME_MAX + 1]; |
86badd32 |
member_add(&addr->sin_addr, data);
m = mfadd(0);
if(!m){ |
8f9aeac1 |
lprintf(0,"%s: out of memory\n", __func__); |
86badd32 |
return;
} |
634a23d7 |
m->mdata.head.opcode = MAKUO_OP_PING;
m->mdata.head.flags |= MAKUO_FLAG_ACK;
m->mdata.head.reqid = data->head.reqid;
m->mdata.head.seqno = 0;
m->mdata.head.szdata = 0; |
86badd32 |
memcpy(&(m->addr), addr, sizeof(m->addr));
if(gethostname(buff, sizeof(buff)) == -1){
buff[0] = 0;
}
p = (mping *)(m->mdata.data);
p->hostnamelen = strlen(buff);
p->versionlen = strlen(MAKUOSAN_VERSION);
m->mdata.head.szdata = sizeof(mping) + p->hostnamelen + p->versionlen;
m->mdata.p = p->data;
memcpy(m->mdata.p, buff, p->hostnamelen);
m->mdata.p += p->hostnamelen;
memcpy(m->mdata.p, MAKUOSAN_VERSION, p->versionlen);
m->mdata.p += p->versionlen;
p->hostnamelen = htons(p->hostnamelen);
p->versionlen = htons(p->versionlen);
}
|
634a23d7 |
static void mrecv_req_exit(mdata *data, struct sockaddr_in *addr) |
86badd32 |
{ |
8f9aeac1 |
mhost *t;
for(t=members;t;t=t->next)
if(!memcmp(&(t->ad), &(addr->sin_addr), sizeof(t->ad))) |
86badd32 |
break; |
8f9aeac1 |
member_del(t); |
86badd32 |
}
|
91adf830 |
static void mrecv_req_file_data(mfile *m, mdata *r) |
86badd32 |
{
if(m->mdata.head.nstate != MAKUO_RECVSTATE_OPEN) |
91adf830 |
return; |
86badd32 |
if(m->lickflag){
if(!seq_delmark(m, r->head.seqno)){ |
91adf830 |
return; |
86badd32 |
}
}else{
if(r->head.seqno < m->mdata.head.seqno){
seq_delmark(m, r->head.seqno);
}else{
m->mdata.head.seqno++;
if(m->mdata.head.seqno < r->head.seqno){
seq_addmark(m, m->mdata.head.seqno, r->head.seqno);
m->mdata.head.seqno = r->head.seqno;
}
}
}
if(lseek(m->fd, (r->head.seqno - 1) * MAKUO_BUFFER_SIZE, SEEK_SET) == -1){ |
8f9aeac1 |
lprintf(0, "%s: seek error seq=%d size=%d fd=%d err=%d\n", __func__, (int)r->head.seqno, r->head.szdata, m->fd, errno); |
86badd32 |
m->mdata.head.nstate = MAKUO_RECVSTATE_WRITEERROR;
}else{
if(write(m->fd, r->data, r->head.szdata) != -1){
m->recvcount++;
}else{ |
8f9aeac1 |
lprintf(0, "%s: write error seqno=%d size=%d fd=%d err=%d\n", __func__, (int)r->head.seqno, r->head.szdata, m->fd, errno); |
86badd32 |
m->mdata.head.nstate = MAKUO_RECVSTATE_WRITEERROR;
}
}
}
|
91adf830 |
static void mrecv_req_file_break(mfile *m, mdata *r) |
86badd32 |
{
mrecv_mfdel(m);
}
|
91adf830 |
static void mrecv_req_file_open(mfile *m, mdata *r) |
86badd32 |
{
char fpath[PATH_MAX];
char tpath[PATH_MAX];
if(m->mdata.head.nstate != MAKUO_RECVSTATE_UPDATE) |
91adf830 |
return; |
86badd32 |
sprintf(fpath, "%s/%s", moption.base_dir, m->fn);
sprintf(tpath, "%s/%s", moption.base_dir, m->tn);
mfile *a = mfins(0); |
634a23d7 |
a->mdata.head.flags |= MAKUO_FLAG_ACK;
a->mdata.head.opcode = r->head.opcode;
a->mdata.head.reqid = r->head.reqid;
a->mdata.head.seqno = r->head.seqno; |
86badd32 |
a->mdata.head.ostate = m->mdata.head.nstate;
a->mdata.head.nstate = MAKUO_RECVSTATE_OPEN;
m->mdata.head.nstate = MAKUO_RECVSTATE_OPEN;
memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
if(S_ISLNK(m->fs.st_mode)){
mtempname(moption.base_dir, m->fn, m->tn);
sprintf(tpath, "%s/%s", moption.base_dir, m->tn);
if(symlink(m->ln, m->tn) != -1){ |
8f9aeac1 |
lprintf(2, "%s: open %s -> %s\n", __func__, m->ln, m->fn); |
86badd32 |
}else{ |
8f9aeac1 |
lprintf(0, "%s: symlink error %s\n", __func__, m->fn); |
86badd32 |
m->mdata.head.nstate = MAKUO_RECVSTATE_OPENERROR;
a->mdata.head.nstate = m->mdata.head.nstate;
}
}else{
if(S_ISDIR(m->fs.st_mode)){
if(!is_dir(fpath)){
mcreatedir(moption.base_dir, m->fn, m->fs.st_mode & 0xFFF);
mkdir(fpath, m->fs.st_mode & 0xFFF);
}else{
chmod(fpath, m->fs.st_mode & 0xFFF);
}
if(!is_dir(fpath)){ |
8f9aeac1 |
lprintf(0,"%s: mkdir error %s\n", __func__, m->fn); |
86badd32 |
m->mdata.head.nstate = MAKUO_RECVSTATE_OPENERROR;
a->mdata.head.nstate = m->mdata.head.nstate;
}
}
if(S_ISREG(m->fs.st_mode)){
mtempname(moption.base_dir, m->fn, m->tn);
sprintf(tpath, "%s/%s", moption.base_dir, m->tn);
m->fd = mcreate(moption.base_dir, m->tn, m->fs.st_mode);
if(m->fd == -1){ |
8f9aeac1 |
lprintf(0, "%s: open error %s\n", __func__, m->fn); |
86badd32 |
m->mdata.head.nstate = MAKUO_RECVSTATE_OPENERROR;
a->mdata.head.nstate = m->mdata.head.nstate;
}
}
}
}
|
91adf830 |
static void mrecv_req_file_last(mfile *m, mdata *r)
{
mrecv_mfdel(m);
}
static void mrecv_req_file_close(mfile *m, mdata *r) |
86badd32 |
{
struct utimbuf mftime;
char fpath[PATH_MAX];
char tpath[PATH_MAX];
sprintf(fpath, "%s/%s", moption.base_dir, m->fn);
sprintf(tpath, "%s/%s", moption.base_dir, m->tn);
|
91adf830 |
switch(m->mdata.head.nstate){
case MAKUO_RECVSTATE_OPEN:
case MAKUO_RECVSTATE_UPDATE:
case MAKUO_RECVSTATE_CLOSE:
case MAKUO_RECVSTATE_CLOSEERROR:
break;
default:
return;
}
mfile *a = mfins(0);
a->mdata.head.flags |= MAKUO_FLAG_ACK;
a->mdata.head.opcode = r->head.opcode;
a->mdata.head.reqid = r->head.reqid;
a->mdata.head.seqno = r->head.seqno;
a->mdata.head.ostate = m->mdata.head.nstate;
a->mdata.head.nstate = MAKUO_RECVSTATE_CLOSE;
memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
switch(m->mdata.head.nstate){
case MAKUO_RECVSTATE_OPEN:
break;
case MAKUO_RECVSTATE_UPDATE:
case MAKUO_RECVSTATE_CLOSE:
return;
case MAKUO_RECVSTATE_CLOSEERROR:
a->mdata.head.nstate = MAKUO_RECVSTATE_CLOSEERROR;
return;
}
if(m->fd != -1){
fstat(m->fd, &(a->fs));
close(m->fd);
}
m->fd = -1;
mftime.actime = m->fs.st_ctime;
mftime.modtime = m->fs.st_mtime;
if(S_ISLNK(m->fs.st_mode)){
if(!mrename(moption.base_dir, m->tn, m->fn)){
lprintf(2, "%s: close %s -> %s\n", __func__, m->ln, m->fn);
}else{
a->mdata.head.nstate = MAKUO_RECVSTATE_CLOSEERROR;
mremove(moption.base_dir, m->tn);
lprintf(0, "%s: close error %s -> %s\n", __func__, m->ln, m->fn);
}
return;
}
if(S_ISDIR(m->fs.st_mode)){
utime(fpath, &mftime);
}else{
utime(tpath, &mftime);
if(a->fs.st_size != m->fs.st_size){
a->mdata.head.nstate = MAKUO_RECVSTATE_CLOSEERROR;
mremove(moption.base_dir, m->tn);
lprintf(0, "%s: close error %s (file size mismatch %d != %d)\n", __func__, m->fn, (int)(a->fs.st_size), (int)(m->fs.st_size));
lprintf(0, "%s: seq=%d max=%d markcnt=%d\n", __func__, m->mdata.head.seqno, m->seqnomax, m->markcount);
}else{
if(!mrename(moption.base_dir, m->tn, m->fn)){
lprintf(2, "%s: close %s recv=%d mark=%d\n", __func__, m->fn , m->recvcount, m->markcount); |
86badd32 |
}else{ |
91adf830 |
a->mdata.head.nstate = MAKUO_RECVSTATE_CLOSEERROR;
mremove(moption.base_dir, m->tn);
lprintf(0, "%s: close error %s\n", __func__, m->fn); |
86badd32 |
}
}
} |
91adf830 |
if(!geteuid()){
chown(fpath, m->fs.st_uid, m->fs.st_gid);
} |
86badd32 |
}
|
91adf830 |
static void mrecv_req_file_mark(mfile *m, mdata *r) |
86badd32 |
{
if(m->mdata.head.nstate != MAKUO_RECVSTATE_OPEN) |
91adf830 |
return; |
86badd32 |
mfile *a = mfins(0); |
634a23d7 |
a->mdata.head.flags |= MAKUO_FLAG_ACK;
a->mdata.head.opcode = r->head.opcode;
a->mdata.head.reqid = r->head.reqid;
a->mdata.head.seqno = r->head.seqno; |
86badd32 |
a->mdata.head.nstate = m->mdata.head.nstate; |
634a23d7 |
a->mdata.head.szdata = 0; |
86badd32 |
memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
m->lickflag = 1;
a->lickflag = 1;
if(m->mdata.head.seqno < m->seqnomax){
seq_addmark(m, m->mdata.head.seqno, m->seqnomax + 1);
m->mdata.head.seqno = m->seqnomax;
}
if(m->markcount){
if(MAKUO_BUFFER_SIZE < m->markcount * sizeof(uint32_t)){
a->marksize = MAKUO_BUFFER_SIZE / sizeof(uint32_t);
}else{
a->marksize = m->markcount;
}
a->markcount = a->marksize;
a->mark = malloc(a->marksize * sizeof(uint32_t));
memcpy(a->mark, m->mark, a->marksize * sizeof(uint32_t)); |
8f9aeac1 |
lprintf(3, "%s: retry %s recv=%d mark=%d reqest=%d\n", __func__, m->fn , m->recvcount, m->markcount, a->markcount); |
86badd32 |
}
}
|
91adf830 |
static void mrecv_req_file_stat(mfile *m, mdata *r) |
86badd32 |
{ |
91adf830 |
mstat fs;
mfile *a;
struct utimbuf mftime;
a = mfins(0);
a->mdata.head.flags |= MAKUO_FLAG_ACK;
a->mdata.head.opcode = m->mdata.head.opcode;
a->mdata.head.reqid = m->mdata.head.reqid;
a->mdata.head.szdata = 0;
a->mdata.head.seqno = m->mdata.head.seqno;
memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
if(moption.dontrecv){
m->mdata.head.nstate = MAKUO_RECVSTATE_READONLY;
}else{
if(S_ISLNK(m->fs.st_mode)){
m->mdata.head.nstate = linkcmp(m);
}else{
if(lstat(m->fn, &(a->fs)) == -1){
m->mdata.head.nstate = MAKUO_RECVSTATE_UPDATE;
}else{
m->mdata.head.nstate = statcmp(&(m->fs), &(a->fs));
}
} |
86badd32 |
} |
91adf830 |
a->mdata.head.nstate = m->mdata.head.nstate;
}
static void mrecv_req_file_next(mfile *m, mdata *r)
{ |
86badd32 |
switch(r->head.nstate){ |
91adf830 |
case MAKUO_SENDSTATE_STAT:
lprintf(9,"%s: MAKUO_SENDSTATE_STAT: state=%d %s\n", __func__, m->mdata.head.nstate, m->fn);
mrecv_req_file_stat(m, r);
break;
|
86badd32 |
case MAKUO_SENDSTATE_OPEN: |
8f9aeac1 |
lprintf(9,"%s: MAKUO_SENDSTATE_OPEN : state=%d %s\n", __func__, m->mdata.head.nstate, m->fn); |
91adf830 |
mrecv_req_file_open(m, r);
break;
case MAKUO_SENDSTATE_DATA:
mrecv_req_file_data(m, r);
break;
|
86badd32 |
case MAKUO_SENDSTATE_MARK: |
8f9aeac1 |
lprintf(9,"%s: MAKUO_SENDSTATE_MARK : state=%d seqno=%d max=%d cnt=%d %s\n", __func__, |
86badd32 |
m->mdata.head.nstate, m->mdata.head.seqno, m->seqnomax, m->markcount, m->fn); |
91adf830 |
mrecv_req_file_mark(m, r);
break;
|
86badd32 |
case MAKUO_SENDSTATE_CLOSE: |
8f9aeac1 |
lprintf(9,"%s: MAKUO_SENDSTATE_CLOSE: state=%d %s\n", __func__, m->mdata.head.nstate, m->fn); |
91adf830 |
mrecv_req_file_close(m, r);
break;
case MAKUO_SENDSTATE_LAST:
lprintf(9,"%s: MAKUO_SENDSTATE_LAST : state=%d %s\n", __func__, m->mdata.head.nstate, m->fn);
mrecv_req_file_last(m, r);
break;
case MAKUO_SENDSTATE_BREAK:
lprintf(9,"%s: MAKUO_SENDSTATE_BREAK: state=%d %s\n", __func__, m->mdata.head.nstate, m->fn);
mrecv_req_file_break(m, r);
break; |
86badd32 |
}
}
|
91adf830 |
static void mrecv_req_send(mdata *data, struct sockaddr_in *addr) |
86badd32 |
{
mstat fs; |
91adf830 |
mfile *m;
uint16_t fnlen;
uint16_t lnlen; |
86badd32 |
|
91adf830 |
for(m=mftop[1];m;m=m->next){
if(!memcmp(&m->addr, addr, sizeof(m->addr)) && m->mdata.head.reqid == data->head.reqid){
break;
}
} |
86badd32 |
|
91adf830 |
if(!m){
/* create object */ |
86badd32 |
m = mfadd(1); |
91adf830 |
if(!m){
lprintf(0, "%s: out of memory\n", __func__);
return;
}
/* copy header */ |
86badd32 |
memcpy(&(m->addr), addr, sizeof(m->addr));
memcpy(&(m->mdata.head), &(data->head), sizeof(m->mdata.head)); |
91adf830 |
data->p = data->data; |
86badd32 |
/* read mstat */
memcpy(&fs, data->p, sizeof(fs));
data->p += sizeof(fs);
/* stat = mstat */
m->fs.st_mode = ntohl(fs.mode);
m->fs.st_uid = ntohs(fs.uid);
m->fs.st_gid = ntohs(fs.gid);
m->fs.st_size = ((off_t)ntohl(fs.sizeh) << 32) + (off_t)ntohl(fs.sizel);
m->fs.st_mtime = ntohl(fs.mtime);
m->fs.st_ctime = ntohl(fs.ctime);
fnlen = ntohs(fs.fnlen);
lnlen = ntohs(fs.lnlen);
/* read filename */
memcpy(m->fn, data->p, fnlen);
m->fn[fnlen] = 0;
data->p += fnlen;
/* read linkname */
memcpy(m->ln, data->p, lnlen);
m->ln[lnlen] = 0;
data->p += lnlen;
|
91adf830 |
/* Number of blocks */ |
86badd32 |
m->seqnomax = m->fs.st_size / MAKUO_BUFFER_SIZE;
if(m->fs.st_size % MAKUO_BUFFER_SIZE){
m->seqnomax++;
}
} |
91adf830 |
mtimeget(&(m->lastrecv));
mrecv_req_file_next(m, data); |
86badd32 |
}
|
634a23d7 |
static void mrecv_req_md5_open(mfile *m, mdata *data, struct sockaddr_in *addr) |
86badd32 |
{
int r;
int l;
mfile *a;
mhash *h;
if(!m){
m = mfadd(1);
memcpy(&(m->addr), addr, sizeof(m->addr));
memcpy(&(m->mdata.head), &(data->head), sizeof(m->mdata.head));
h = (mhash *)(data->data);
l = ntohs(h->fnlen);
memcpy(m->fn, h->filename, l);
m->fn[l] = 0;
m->fd = open(m->fn, O_RDONLY);
if(m->fd == -1){
m->mdata.head.nstate = MAKUO_RECVSTATE_OPENERROR;
}else{
r = md5sum(m->fd, m->mdata.data);
close(m->fd);
m->fd = -1;
if(r == -1){ |
8f9aeac1 |
lprintf(0, "%s: file read error %s\n", __func__, m->fn); |
86badd32 |
m->mdata.head.nstate = MAKUO_RECVSTATE_READERROR;
}else{
if(!memcmp(m->mdata.data, data->data, 16)){
m->mdata.head.nstate = MAKUO_RECVSTATE_MD5OK;
}else{
m->mdata.head.nstate = MAKUO_RECVSTATE_MD5NG;
}
}
}
}
a=mfadd(0); |
634a23d7 |
a->mdata.head.flags |= MAKUO_FLAG_ACK;
a->mdata.head.opcode = m->mdata.head.opcode;
a->mdata.head.reqid = m->mdata.head.reqid;
a->mdata.head.seqno = 0;
a->mdata.head.szdata = 0; |
86badd32 |
a->mdata.head.nstate = m->mdata.head.nstate;
memcpy(&(a->addr), addr, sizeof(a->addr));
mtimeget(&(m->lastrecv));
}
|
634a23d7 |
static void mrecv_req_md5_close(mfile *m, mdata *data, struct sockaddr_in *addr) |
86badd32 |
{
mfile *a = mfadd(0); |
634a23d7 |
a->mdata.head.flags |= MAKUO_FLAG_ACK;
a->mdata.head.opcode = data->head.opcode;
a->mdata.head.reqid = data->head.reqid;
a->mdata.head.szdata = 0;
a->mdata.head.seqno = 0; |
86badd32 |
a->mdata.head.nstate = MAKUO_RECVSTATE_CLOSE;
memcpy(&(a->addr), addr, sizeof(a->addr));
mrecv_mfdel(m);
}
/* |
3434d319 |
* md5チェック要求を受け取ったときの処理
* mfileオブジェクトを生成して
* 対象ファイルのmd5を取得する |
86badd32 |
*/ |
634a23d7 |
static void mrecv_req_md5(mdata *data, struct sockaddr_in *addr) |
86badd32 |
{
mfile *m = mftop[1];
while(m){
if(!memcmp(&m->addr, addr, sizeof(m->addr)) && m->mdata.head.reqid == data->head.reqid){
mtimeget(&m->lastrecv);
break;
}
m = m->next;
}
switch(data->head.nstate){
case MAKUO_SENDSTATE_OPEN: |
634a23d7 |
mrecv_req_md5_open(m, data, addr); |
86badd32 |
break;
case MAKUO_SENDSTATE_CLOSE: |
634a23d7 |
mrecv_req_md5_close(m, data, addr); |
86badd32 |
break;
}
}
|
634a23d7 |
static void mrecv_req(mdata *data, struct sockaddr_in *addr) |
86badd32 |
{ |
634a23d7 |
switch(data->head.opcode){ |
86badd32 |
case MAKUO_OP_PING: |
634a23d7 |
mrecv_req_ping(data, addr); |
86badd32 |
break;
case MAKUO_OP_EXIT: |
634a23d7 |
mrecv_req_exit(data, addr); |
86badd32 |
break; |
8f9aeac1 |
case MAKUO_OP_SEND: |
91adf830 |
mrecv_req_send(data, addr); |
86badd32 |
break;
case MAKUO_OP_MD5: |
634a23d7 |
mrecv_req_md5(data, addr); |
86badd32 |
break; |
8f9aeac1 |
/* 機能追加はここへ */ |
86badd32 |
}
}
|