86badd32 |
#include "makuosan.h"
mopt moption;
mfile *mftop[2] = {NULL,NULL};
mhost *members = NULL;
int loop_flag = 1;
struct timeval curtime;
BF_KEY EncKey;
int md5sum(int fd, unsigned char *digest)
{
int rd;
char buff[1024];
MD5_CTX ctx;
MD5_Init(&ctx);
while(rd = read(fd, buff, sizeof(buff))){
if(rd == -1){
return(-1);
}
MD5_Update(&ctx, buff, rd);
}
MD5_Final(digest, &ctx);
return(0);
}
/* |
3434d319 |
* タイムアウト時間が経過しているかどうかを判断する
* - 現在時刻がtfからmsec[ms]経過していれば1を返す
* - それ以外は0を返す |
86badd32 |
*/
int mtimeout(struct timeval *tf, uint32_t msec)
{
struct timeval tv;
struct timeval tr;
tv.tv_sec = msec / 1000;
tv.tv_usec = (msec % 1000) * 1000;
timeradd(tf, &tv, &tr);
return(timercmp(&tr, &curtime, <));
}
/* |
3434d319 |
* 現在時刻を取得する |
e396e004 |
* (といってもcurtimeをコピーするだけだけど) |
86badd32 |
*/
int mtimeget(struct timeval *tv)
{
memcpy(tv, &curtime, sizeof(curtime));
return(0);
}
/* |
3434d319 |
* ファイル名がexcludeリストにマッチするかどうかを調べる
* - マッチした場合はそのexcludeitem構造体のポインタを返す
* - マッチしない場合はNULLを返す |
86badd32 |
*/
excludeitem *mfnmatch(char *str, excludeitem *exclude)
{
char *p;
excludeitem *e;
for(e=exclude;e;e=e->next){
p=str;
while(*p){
if(strlen(p) < strlen(e->pattern)){
break;
}
if(!fnmatch(e->pattern, p, FNM_PATHNAME)){
return(e);
}
while(*p){
if(*(p++) == '/'){
break;
}
}
}
}
return(NULL);
}
void fdprintf(int s, char *fmt, ...)
{
char m[2048];
va_list arg;
if(s != -1){
va_start(arg, fmt);
vsprintf(m, fmt, arg);
va_end(arg);
write(s, m, strlen(m));
}
}
void lprintf(int l, char *fmt, ...)
{
va_list arg;
char msg[512];
if(moption.loglevel >= l){
va_start(arg, fmt);
vsprintf(msg, fmt, arg);
va_end(arg);
if(moption.dontfork){
fprintf(stderr, msg);
}
syslog(LOG_ERR, "%s: %s", moption.user_name, msg);
}
}
void cprintf(int l, mcomm *c, char *fmt, ...)
{
char m[2048];
va_list arg;
if(!c)
return;
if(c->fd[0] == -1)
return;
if(c->loglevel >= l){
va_start(arg, fmt);
vsprintf(m, fmt, arg);
va_end(arg);
write(c->fd[0], m, strlen(m));
fsync(c->fd[0]);
}
}
int getrid()
{
static int rid=0;
return(rid++);
}
int workend(mcomm *c)
{
if(c){
if(c->working && !c->cpid){
c->working = 0;
if(moption.commpass && !c->authchk){
cprintf(0, c, "Password: \x1b]E");
}else{
cprintf(0,c,"> ");
}
}
}
return(0);
}
void mfdel(mfile *m)
{
mfile *p;
mfile *n;
if(m){
if(p = (mfile *)m->prev)
p->next = m->next;
if(n = (mfile *)m->next)
n->prev = m->prev;
if(mftop[0] == m)
mftop[0] = n;
if(mftop[1] == m)
mftop[1] = n;
free(m);
}
}
mfile *mfnew()
{
mfile *m;
if(m = (mfile *)malloc(sizeof(mfile))){
memset(m, 0, sizeof(mfile));
m->mdata.head.vproto = PROTOCOL_VERSION;
m->fd = -1;
m->retrycnt = MAKUO_SEND_RETRYCNT;
memcpy(&(m->addr), &(moption.maddr), sizeof(m->addr));
}
return(m);
}
mfile *mfadd(int n)
{
mfile *m;
if(m = mfnew()){
if(!mftop[n]){
mftop[n] =m;
}else{
mfile *l;
for(l=mftop[n];l->next;l=l->next);
l->next = (void *)m;
m->prev = (void *)l;
m->next = NULL;
}
}
return(m);
}
mfile *mfins(int n)
{
mfile *m;
if(m = mfnew()){
if(mftop[n]){
mftop[n]->prev = m;
m->next = mftop[n];
}
mftop[n] =m;
}
return(m);
}
mhost *member_add(struct in_addr *addr, mdata *data)
{
int f = 1;
int l = 0;
mhost *t = NULL;
mping *p = NULL;
for(t=members;t;t=t->next)
if(!(f=memcmp(&t->ad, addr, sizeof(t->ad))))
break;
if(!t){
t = malloc(sizeof(mhost));
if(!t){ |
8f9aeac1 |
lprintf(0,"%s: out of memory\n", __func__); |
86badd32 |
return(NULL);
}
memcpy(&t->ad, addr, sizeof(t->ad));
t->state = 0;
t->prev = NULL;
t->next = NULL;
if(members){
members->prev = t;
t->next = members;
}
members = t;
t->hostname[0] = 0;
}
if(data){ |
634a23d7 |
if(data->head.opcode == MAKUO_OP_PING){ |
86badd32 |
p = (mping *)data->data;
l = ntohs(p->hostnamelen);
data->p = p->data;
memcpy(t->hostname, data->p, l);
t->hostname[l] = 0;
data->p += l;
l = ntohs(p->versionlen);
memcpy(t->version, data->p, l);
t->version[l] = 0;
}
}
if(f){ |
8f9aeac1 |
lprintf(0,"%s: %s (%s)\n", __func__, inet_ntoa(t->ad), t->hostname); |
86badd32 |
}
mtimeget(&(t->lastrecv));
return(t);
}
void member_del(mhost *t)
{
mfile *m;
mhost *p;
mhost *n;
if(!t)
return; |
8f9aeac1 |
lprintf(0,"%s: %s (%s)\n", __func__, inet_ntoa(t->ad), t->hostname); |
86badd32 |
if(p = (mhost *)t->prev)
p->next = t->next;
if(n = (mhost *)t->next)
n->prev = t->prev;
if(members == t)
members = n;
do{
for(m=mftop[1];m;m=m->next){
if(!memcmp(&(m->addr.sin_addr), &(t->ad), sizeof(m->addr.sin_addr))){
if(m->mdata.head.nstate == MAKUO_RECVSTATE_OPEN){
if(m->fd != -1){
close(m->fd);
}
m->fd = -1;
if(S_ISREG(m->fs.st_mode)){
mremove(moption.base_dir,m->tn);
}
} |
8f9aeac1 |
lprintf(0,"%s: mfile break %s\n", __func__, m->fn); |
86badd32 |
mfdel(m);
break;
}
}
}while(m);
free(t);
}
int seq_addmark(mfile *m, uint32_t lseq, uint32_t useq)
{
int i,j;
int size;
void *n;
if(!m->mark){
m->markcount = 0;
m->marksize = 512;
m->mark = malloc(sizeof(uint32_t) * m->marksize);
}
size = m->marksize;
while(size < m->markcount + useq - lseq)
size += 512;
if(size != m->marksize){
n = malloc(sizeof(uint32_t) * size);
memcpy(n, m->mark, sizeof(uint32_t) * m->marksize);
free(m->mark);
m->mark = n;
m->marksize = size;
}
for(i=lseq;i<useq;i++){
for(j=0;j<m->markcount;j++)
if(i == m->mark[j])
break;
if(j == m->markcount){
m->mark[m->markcount++] = i;
}
}
return(0);
}
int seq_delmark(mfile *m, uint32_t seq)
{
int i;
int r = 0;
for(i=0;i<m->markcount;i++){
if(m->mark[i] == seq){
r = 1;
m->markcount--;
m->mark[i] = m->mark[m->markcount];
}
}
return(r);
}
int seq_popmark(mfile *m, int n)
{
char *s;
char *d;
int size = m->markcount - n;
if(size > 0){
s = (char *)(m->mark + n);
d = (char *)(m->mark + 0);
memmove(d, s, size * sizeof(uint32_t));
m->markcount = size;
}else{
m->markcount = 0;
}
}
int ack_clear(mfile *m, int state)
{
mhost *h;
for(h=members;h;h=h->next){
if(!m->sendto){
if(state == -1 || h->state == state)
h->state = MAKUO_RECVSTATE_NONE;
}else{
if(!memcmp(&(m->addr.sin_addr), &(h->ad), sizeof(m->addr.sin_addr))){
if(state == -1 || h->state == state){
h->state = MAKUO_RECVSTATE_NONE;
return(1);
}else{
return(0);
}
}
}
}
if(m->sendto)
return(-1);
return(0);
}
|
3434d319 |
/* 指定したステータスを持つ応答メッセージがあるかをチェックする
* 引数 :
* m: 送信対象のファイルオブジェクト
* state: 検索するステータス |
86badd32 |
* |
3434d319 |
* 戻り値:
* 0: 見つからなかった
* 1: 見つかった
* -1: ホスト指定転送なのにホストオブジェクトが見つからない |
86badd32 |
*/
int ack_check(mfile *m, int state)
{
mhost *h;
for(h=members;h;h=h->next){
if(!m->sendto){
if(h->state == state){
return(1);
}
}else{
if(!memcmp(&(m->addr.sin_addr), &(h->ad), sizeof(m->addr.sin_addr))){
if(h->state == state){
return(1);
}else{
return(0);
}
}
}
}
if(m->sendto)
return(-1);
return(0);
}
int linkcmp(mfile *m)
{
ssize_t size;
char ln[PATH_MAX];
if(m){
size = readlink(m->fn, ln, PATH_MAX);
if(size != -1 && size < PATH_MAX){
ln[size] = 0;
if(!strcmp(m->ln, ln)){
return(MAKUO_RECVSTATE_SKIP);
}
}
}
return(MAKUO_RECVSTATE_UPDATE);
}
int statcmp(struct stat *s1, struct stat *s2)
{
mode_t s1mode;
mode_t s2mode;
if((S_ISDIR(s1->st_mode)) && (S_ISDIR(s2->st_mode))){
s1mode = s1->st_mode & 0xFFF;
s2mode = s2->st_mode & 0xFFF;
if(s1mode != s2mode)
return(MAKUO_RECVSTATE_UPDATE);
if(s1->st_mtime != s2->st_mtime)
return(MAKUO_RECVSTATE_UPDATE);
return(MAKUO_RECVSTATE_SKIP);
}
if((S_ISREG(s1->st_mode)) && (S_ISREG(s2->st_mode))){
if(s1->st_size != s2->st_size)
return(MAKUO_RECVSTATE_UPDATE);
if(s1->st_mtime != s2->st_mtime)
return(MAKUO_RECVSTATE_UPDATE);
return(MAKUO_RECVSTATE_SKIP);
}
return(MAKUO_RECVSTATE_UPDATE);
}
int is_dir(char *path)
{
struct stat mstat;
if(!lstat(path,&mstat))
return(S_ISDIR(mstat.st_mode));
return(0);
}
int is_reg(char *path)
{
struct stat mstat;
if(!lstat(path,&mstat))
return(S_ISREG(mstat.st_mode));
return(0);
}
void mtempname(char *base, char *fn, char *tn)
{
struct stat st;
struct timeb tb;
char path[PATH_MAX];
do{
ftime(&tb);
sprintf(tn, "%s.makuo%03u%03u", fn, getrid() % 1000, (int)tb.millitm);
sprintf(path, "%s/%s", base, tn);
}while(lstat(tn, &st) != -1);
}
int mremove(char *base, char *name)
{
DIR *d;
struct dirent *dent;
char path[PATH_MAX];
if(!base){
strcpy(path,name);
}else{
sprintf(path,"%s/%s", base, name); |
8f9aeac1 |
lprintf(0,"%s: %s\n", __func__, path); |
86badd32 |
}
if(is_dir(path)){
if(d = opendir(path)){
while(dent=readdir(d)){
if(!strcmp(dent->d_name, "."))
continue;
if(!strcmp(dent->d_name, ".."))
continue;
mremove(path, dent->d_name);
}
closedir(d);
}
}
return(remove(path));
}
int mrename(char *base, char *oldname, char *newname)
{
char oldpath[PATH_MAX];
char newpath[PATH_MAX];
char tmppath[PATH_MAX];
sprintf(oldpath,"%s/%s", base, oldname);
sprintf(newpath,"%s/%s", base, newname);
mtempname(base, newname, tmppath);
rename(newpath,tmppath);
if(rename(oldpath,newpath) == -1){
rename(tmppath, newpath);
return(-1);
}
mremove(NULL,tmppath);
return(0);
}
int mcreatedir(char *base, char *name, mode_t mode)
{
char *p;
char buff[PATH_MAX];
char path[PATH_MAX];
strcpy(buff, name);
strcpy(path, base);
p = strtok(buff, "/");
while(p){
strcat(path, "/");
strcat(path, p);
if(p = strtok(NULL,"/")){
if(!is_dir(path)){
remove(path);
if(mkdir(path,mode) == -1){
return(-1);
}
}
}
}
return(0);
}
int mcreate(char *base, char *name, mode_t mode)
{
int fd = -1;
char path[PATH_MAX];
if(!mcreatedir(base,name,0755)){
sprintf(path,"%s/%s",base,name);
fd = open(path, O_RDWR | O_CREAT | O_TRUNC, mode & 0xFFF);
}
return(fd);
}
int space_escape(char *str)
{
int r = 0;
char buff[PATH_MAX];
char *s = str;
char *d = buff;
while(*s){
if(*s == ' '){
r++;
*(d++) = '\\';
}
*(d++) = *(s++);
}
*d = 0;
strcpy(str, buff);
return(r);
}
|