Exemplo n.º 1
0
void matomlserv_send_archived_changes(matomlserventry *eptr) {
    char buff[4096],logname[30],*ptr;
    uint8_t *data;
    uint64_t nextid;
    int i,len;
    for (i=0; i<50000 && eptr->logf; i++) {
        if (fgets(buff,4096,eptr->logf)!=NULL) {
            len=strlen(buff);
            if (len==0 || buff[len-1]!='\n') {
                syslog(LOG_WARNING,"meta logger broken changelog: len=%d", len);
                fclose(eptr->logf);
                eptr->logf=NULL;
                return;
            }
            nextid=strtoull(buff,&ptr,10);
            if (nextid<eptr->currentversion) continue;

            ptr += 2; // ": "
            len=strlen(ptr);
            ptr[len-1]='\0'; // drop \n
			data = matomlserv_createpacket(eptr,MATOML_METACHANGES_LOG,9+len);
			put8bit(&data,0xFF);
			put64bit(&data,nextid);
			memcpy(data,ptr,len);

            eptr->currentversion++;

            if (old_changes_head && eptr->currentversion==old_changes_head->minversion) {
                fclose(eptr->logf);
                eptr->logf=NULL;
            }
        } else {
            // end of file
            fclose(eptr->logf);
            eptr->logf=NULL;
            eptr->logindex--;

            if (eptr->logindex>=0) {
                data = matomlserv_createpacket(eptr,MATOML_METACHANGES_LOG,1);
                put8bit(&data,0x55);

                sprintf(logname,"changelog.%d.mfs",eptr->logindex);
                if ((eptr->logf=fopen(logname,"r"))==NULL) {
                    syslog(LOG_WARNING,"meta logger open %s failed", logname);
                }
            }
        }
    }
}
Exemplo n.º 2
0
void matomlserv_broadcast_logrotate() {
	matomlserventry *eptr;
	uint8_t *data;

	for (eptr = matomlservhead ; eptr ; eptr=eptr->next) {
		if (eptr->version>0 && eptr->logf==NULL) {
			data = matomlserv_createpacket(eptr,MATOML_METACHANGES_LOG,1);
			put8bit(&data,0x55);
		}
	}
}
Exemplo n.º 3
0
void matomlserv_broadcast_logstring(uint64_t version,uint8_t *logstr,uint32_t logstrsize) {
	matomlserventry *eptr;
	uint8_t *data;

	for (eptr = matomlservhead ; eptr ; eptr=eptr->next) {
		if (eptr->version>0) {
			data = matomlserv_createpacket(eptr,MATOML_METACHANGES_LOG,9+logstrsize);
			put8bit(&data,0xFF);
			put64bit(&data,version);
			memcpy(data,logstr,logstrsize);
		}
	}
}
Exemplo n.º 4
0
void matomlserv_download_data(matomlserventry *eptr,const uint8_t *data,uint32_t length) {
	uint8_t *ptr;
	uint64_t offset;
	uint32_t leng;
	uint32_t crc;
	ssize_t ret;

	if (length!=12) {
		syslog(LOG_NOTICE,"MLTOMA_DOWNLOAD_DATA - wrong size (%"PRIu32"/12)",length);
		eptr->mode=KILL;
		return;
	}
	if (eptr->metafd<0) {
		syslog(LOG_NOTICE,"MLTOMA_DOWNLOAD_DATA - file not opened");
		eptr->mode=KILL;
		return;
	}
	offset = get64bit(&data);
	leng = get32bit(&data);
	ptr = matomlserv_createpacket(eptr,MATOML_DOWNLOAD_DATA,16+leng);
	put64bit(&ptr,offset);
	put32bit(&ptr,leng);
#ifdef HAVE_PREAD
	ret = pread(eptr->metafd,ptr+4,leng,offset);
#else /* HAVE_PWRITE */
	lseek(eptr->metafd,offset,SEEK_SET);
	ret = read(eptr->metafd,ptr+4,leng);
#endif /* HAVE_PWRITE */
	if (ret!=(ssize_t)leng) {
		mfs_errlog_silent(LOG_NOTICE,"error reading metafile");
		eptr->mode=KILL;
		return;
	}
	crc = mycrc32(0,ptr+4,leng);
	put32bit(&ptr,crc);
}
Exemplo n.º 5
0
void matomlserv_serve(struct pollfd *pdesc) {
	uint32_t now=main_time();
	matomlserventry *eptr,**kptr;
	packetstruct *pptr,*paptr;
	int ns;
	static uint64_t lastaction = 0;
	uint64_t unow;
	uint32_t timeoutadd;

	if (lastaction==0) {
		lastaction = main_precise_utime();
	}

	if (lsockpdescpos>=0 && (pdesc[lsockpdescpos].revents & POLLIN)) {
		ns=tcpaccept(lsock);
		if (ns<0) {
			mfs_errlog_silent(LOG_NOTICE,"Master<->ML socket: accept error");
		} else {
			tcpnonblock(ns);
			tcpnodelay(ns);
			eptr = malloc(sizeof(matomlserventry));
			passert(eptr);
			eptr->next = matomlservhead;
			matomlservhead = eptr;
			eptr->sock = ns;
			eptr->pdescpos = -1;
			eptr->mode = HEADER;
			eptr->lastread = now;
			eptr->lastwrite = now;
			eptr->inputpacket.next = NULL;
			eptr->inputpacket.bytesleft = 8;
			eptr->inputpacket.startptr = eptr->hdrbuff;
			eptr->inputpacket.packet = NULL;
			eptr->outputhead = NULL;
			eptr->outputtail = &(eptr->outputhead);
			eptr->timeout = 10;

			tcpgetpeer(eptr->sock,&(eptr->servip),NULL);
			eptr->servstrip = matomlserv_makestrip(eptr->servip);
			eptr->version=0;
			eptr->metafd=-1;
			eptr->chain1fd=-1;
			eptr->chain2fd=-1;
            eptr->logindex=-1;
            eptr->logf=NULL;
            eptr->currentversion=0;
		}
	}

// read
	for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
		if (eptr->pdescpos>=0) {
			if (pdesc[eptr->pdescpos].revents & (POLLERR|POLLHUP)) {
				eptr->mode = KILL;
			}
			if ((pdesc[eptr->pdescpos].revents & POLLIN) && eptr->mode!=KILL) {
				eptr->lastread = now;
				matomlserv_read(eptr);
			}
		}
	}

// timeout fix
	unow = main_precise_utime();
	timeoutadd = (unow-lastaction)/1000000;
	if (timeoutadd) {
		for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
			eptr->lastread += timeoutadd;
		}
	}
	lastaction = unow;

// write
	for (eptr=matomlservhead ; eptr ; eptr=eptr->next) {
		if ((uint32_t)(eptr->lastwrite+(eptr->timeout/3))<(uint32_t)now && eptr->outputhead==NULL) {
			matomlserv_createpacket(eptr,ANTOAN_NOP,0);
		}
		if (eptr->pdescpos>=0) {
			if ((((pdesc[eptr->pdescpos].events & POLLOUT)==0 && (eptr->outputhead)) || (pdesc[eptr->pdescpos].revents & POLLOUT)) && eptr->mode!=KILL) {
				eptr->lastwrite = now;
				matomlserv_write(eptr);
			}
            if (eptr->mode!=KILL && eptr->logf && eptr->outputhead==NULL) {
                matomlserv_send_old_changes(eptr, eptr->currentversion);
            }
		}
		if ((uint32_t)(eptr->lastread+eptr->timeout)<(uint32_t)now) {
			eptr->mode = KILL;
		}
	}

// close
	kptr = &matomlservhead;
	while ((eptr=*kptr)) {
		if (eptr->mode == KILL) {
			matomlserv_beforeclose(eptr);
			tcpclose(eptr->sock);
			if (eptr->inputpacket.packet) {
				free(eptr->inputpacket.packet);
			}
			pptr = eptr->outputhead;
			while (pptr) {
				if (pptr->packet) {
					free(pptr->packet);
				}
				paptr = pptr;
				pptr = pptr->next;
				free(paptr);
			}
			if (eptr->servstrip) {
				free(eptr->servstrip);
			}
			*kptr = eptr->next;
			free(eptr);
		} else {
			kptr = &(eptr->next);
		}
	}
}
Exemplo n.º 6
0
void matomlserv_download_start(matomlserventry *eptr,const uint8_t *data,uint32_t length) {
	uint8_t filenum;
	uint64_t size;
	uint8_t *ptr;
	if (length!=1) {
		syslog(LOG_NOTICE,"MLTOMA_DOWNLOAD_START - wrong size (%"PRIu32"/1)",length);
		eptr->mode=KILL;
		return;
	}
	filenum = get8bit(&data);
	if (filenum==1 || filenum==2) {
		if (eptr->metafd>=0) {
			close(eptr->metafd);
			eptr->metafd=-1;
		}
		if (eptr->chain1fd>=0) {
			close(eptr->chain1fd);
			eptr->chain1fd=-1;
		}
		if (eptr->chain2fd>=0) {
			close(eptr->chain2fd);
			eptr->chain2fd=-1;
		}
	}
	if (filenum==1) {
		eptr->metafd = open("metadata.mfs.back",O_RDONLY);
		eptr->chain1fd = open("changelog.0.mfs",O_RDONLY);
		eptr->chain2fd = open("changelog.1.mfs",O_RDONLY);
	} else if (filenum==2) {
		eptr->metafd = open("sessions.mfs",O_RDONLY);
	} else if (filenum==11) {
		if (eptr->metafd>=0) {
			close(eptr->metafd);
		}
		eptr->metafd = eptr->chain1fd;
		eptr->chain1fd = -1;
	} else if (filenum==12) {
		if (eptr->metafd>=0) {
			close(eptr->metafd);
		}
		eptr->metafd = eptr->chain2fd;
		eptr->chain2fd = -1;
	} else {
		eptr->mode=KILL;
		return;
	}
	if (eptr->metafd<0) {
		if (filenum==11 || filenum==12) {
			ptr = matomlserv_createpacket(eptr,MATOML_DOWNLOAD_START,8);
			put64bit(&ptr,0);
			return;
		} else {
			ptr = matomlserv_createpacket(eptr,MATOML_DOWNLOAD_START,1);
			put8bit(&ptr,0xff);	// error
			return;
		}
	}
	size = lseek(eptr->metafd,0,SEEK_END);
	ptr = matomlserv_createpacket(eptr,MATOML_DOWNLOAD_START,8);
	put64bit(&ptr,size);	// ok
}
Exemplo n.º 7
0
void matomlserv_send_old_changes(matomlserventry *eptr,uint64_t version) {
	old_changes_block *oc;
	old_changes_entry *oce;
	uint8_t *data;
	uint8_t start=0;
	uint32_t i;
    char logname[255];
    uint64_t firstlv;

    if (eptr->logf) {
        matomlserv_send_archived_changes(eptr);
        if (eptr->logf) {
            return;
        }
        version=eptr->currentversion;
    } else if (old_changes_head==NULL || old_changes_head->minversion>version) {
        for (i=0; i<20; i++) {
            sprintf(logname, "changelog.%d.mfs",i);
            firstlv=findfirstlogversion(logname);
            if (firstlv>version || firstlv==0) {
                continue;
            }
            if ((eptr->logf=fopen(logname,"r"))!=NULL) {
                eptr->logindex = i;
                eptr->currentversion=version;
                matomlserv_send_archived_changes(eptr);
                if (eptr->logf) {
                    return;
                }
                version=eptr->currentversion;
            } else {
                syslog(LOG_WARNING, "matomlserv open %s failed", logname);
            }
            break;
        }
	}

	if (old_changes_head==NULL) {
		// syslog(LOG_WARNING,"meta logger wants old changes, but storage is disabled");
		return;
	}
	if (old_changes_head->minversion>version) {
		syslog(LOG_WARNING,"meta logger wants changes since version: %"PRIu64", but minimal version in storage is: %"PRIu64,version,old_changes_head->minversion);
	}
	for (oc=old_changes_head ; oc ; oc=oc->next) {
		if (oc->minversion<=version && (oc->next==NULL || oc->next->minversion>version)) {
			start=1;
		}
		if (start) {
			for (i=0 ; i<oc->entries ; i++) {
				oce = oc->old_changes_block + i;
				if (version<=oce->version) {
					data = matomlserv_createpacket(eptr,MATOML_METACHANGES_LOG,9+oce->length);
					put8bit(&data,0xFF);
					put64bit(&data,oce->version);
					memcpy(data,oce->data,oce->length);
				}
			}
		}
	}
}