void CGrannyListView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	
	UINT iData = GetSelectedItemData();
	CGrannyViewerDoc *pDoc = GetDocument();
	if (!pDoc) return;

	if (ISSET(iData))
	{
		if (ISANIM(iData)) 
		{
			pDoc->SetCurAnimId(GETDATA(iData));
		} 
		else if (ISCHAR(iData)) 
		{
			UINT id = GETDATA(iData);
		/*	if (GETASSIGN(id)) 
				pDoc->SetCurEquipId(id);
			else */
			
			pDoc->SetCurModelId(id);
		}
	}
	//else
	//{
	//	pDoc->SetCurModelId(INVALID_GRN_ID);
	//}

	*pResult = 0;
}
예제 #2
0
파일: volume.cpp 프로젝트: Xylaant/Projects
struct Shade GetC(double x,double y,double z) /* x,y,z in voxel space*/
{
	struct Shade c;

	int x1,y1,z1;

	x1=(int)x;
	y1=(int)y;
	z1=(int)z;

	if ((x-x1)>=0.5) x1++;
	if ((y-y1)>=0.5) y1++;
	if ((z-z1)>=0.5) z1++;

	if (x1 >= x_size || x1<0 ||
			y1 >= vol_data.size_y() || y1<0 ||
			z1 >= z_size || z1<0)
	{
		c.red=0;
		c.green=0;
		c.blue=0;
		c.alpha=0;
		return c;
	}

	c=GetColor(GETDATA(x1,y1,z1));

	return c;
}
예제 #3
0
파일: ircd.c 프로젝트: prurigro/meshchat
static void
do_accept(uv_stream_t* server, int status) {
    CHECK(status);
    GETDATA(ircd_t, ircd, server);

    struct irc_session *new_session = (struct irc_session *)malloc(sizeof(struct irc_session));
    uv_tcp_init(uv_default_loop(),&new_session->handle);
    new_session->handle.data = new_session;

    new_session->buffer = NULL;
    new_session->ircd = ircd;
    new_session->mode = INITIALIZING;

    if (uv_accept((uv_stream_t*)&ircd->handle, (uv_stream_t*)&new_session->handle) < 0) {
        free(new_session);
        perror("accept");
    } else {
        struct sockaddr_storage addr;
        int addrlen = sizeof(addr);
        uv_tcp_getpeername(&new_session->handle,(struct sockaddr*)&addr,&addrlen);

        printf("accepted connection from %s\n", sprint_addrport((struct sockaddr *)&addr));

        new_session->inbuf_used = 0;
        new_session->next = ircd->session_list;
        if (!inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr, new_session->ip, INET6_ADDRSTRLEN)) {
            perror("inet_ntop");
        }
        ircd->session_list = new_session;

        uv_read_start((uv_stream_t*)&new_session->handle,alloc_buffer,on_read);
    }
}
예제 #4
0
파일: ircd.c 프로젝트: prurigro/meshchat
static void on_welcomed(uv_write_t* req, int status) {
    CHECK(status);

    GETDATA(ircd_t, ircd, req);
    GETDATA(struct irc_session, session, req->handle);

    struct irc_prefix prefix = {
        .nick = ircd->nick,
        .host = ircd->host
    };

    // send joins for the rooms we are in
    struct irc_channel *chan;
    for (chan = ircd->channel_list; chan; chan = chan->next) {
        if (chan->in) {
            irc_session_join(session, &prefix, chan);
            irc_session_names(session, &prefix, chan);
        }
    }

    session->mode = INITIALIZED;
}

void
irc_session_welcome(ircd_t *ircd, struct irc_session *session) {
    ircd_send(session, NULL, noAction, "001 %s :Welcome to this MeshChat Relay (I'm not really an IRC server!)", ircd->nick);
    ircd_send(session, NULL, noAction, "002 %s :IRC MeshChat v1", ircd->nick);
    ircd_send(session, NULL, noAction, "003 %s :Created 0", ircd->nick);
    ircd_send(session, NULL, on_welcomed, "004 %s %s ircd-meshchat-0.0.1 DOQRSZaghilopswz CFILMPQSbcefgijklmnopqrstvz bkloveqjfI", ircd->nick, ircd->host);
}
void CGrannyListView::OnModelRegistermodel()
{
	CGrannyViewerDoc *pDoc = GetDocument();
	UINT iData = GetSelectedItemData();
	if (!pDoc || !ISCHAR(iData)) return;

	UINT id = GETDATA(iData);
	pDoc->RegisterModel(id);
}
예제 #6
0
//²úÉú hash±í
int multi_hash(hash_paramiter *para)
{
int conflict,i,hashnum;
int *lp;
multi_hash_node *hash,*top,*hp,stack[para->key_count];

	if(!para) return -1;
	para->index=hash=(multi_hash_node *)malloc(para->key_count * sizeof(multi_hash_node));
	if(!hash) {
		return MEMERR;
	}

	top=stack;
	for(i=0;i<para->key_count;i++) {
		hash[i].rowno=-1;
		hash[i].link=-1;
		hash[i].count=0;
	}
//ShowLog(5,"multi_hash:data_count=%d,key_count=%d",para->data_count,para->key_count);
	for(i=0;i<para->data_count;i++) {
	    hashnum=para->do_hash(GETDATA(i),para->key_count);
	    hp=&hash[hashnum];
	    if(hp->rowno==-1) {	//ûÓÐÉ¢ÁгåÍ» 
		hp->rowno=i;
		hp->count=1;
	    } else if(!COMPARE(i,hp->rowno)) {	//¼ì²éÖØÂ룬¹¹½¨ÖØÂëÁ´
		hp->count++;
		continue;
	    } else {				//ÓÐÉ¢ÁгåÍ»£¬´æ´¢³åÍ»Á´
		if(top>stack&&!COMPARE(i,top[-1].rowno)) {
			top[-1].count++;
			continue;
		}
		top->rowno=i;
		top->link=hashnum;
		top->count=1;
		top++;
	    }
	}
	conflict=top-stack;
	if(top > stack) { //ÓÐÉ¢ÁгåÍ»£¬¹¹½¨³åÍ»Á´ 
		hp=hash;
		for(i=0;top>stack&&i<para->key_count;i++,hp++) {
			if(hp->rowno > -1) continue;
			top--;
//ÕÒµ½Ë÷Òý±íÀïµÄ¿ÕÏî 
			hp->rowno=top->rowno;
			hp->count=top->count;
			hp->link=-1;
			for(lp=&top->link;*lp != -1;lp=&hash[*lp].link)
				;
			*lp=i;
		}
	}
	return conflict;
}
void CGrannyListView::OnModelUnregistermodel()
{
	UINT iData = GetSelectedItemData();
	CGrannyViewerDoc *pDoc = GetDocument();
	if (!pDoc) return;

	if (ISCHAR(iData))
	{	
		UINT id = GETDATA(iData);
		pDoc->UnregisterModel(id);
	}
}
예제 #8
0
int multi_hash_find(void *key,hash_paramiter *para,int *a_count)
{
multi_hash_node *hp;

        if(a_count) *a_count=0;
        if(!para||!para->index) return -1;
        for(hp=((multi_hash_node *)para->index)+para->do_hash(key,para->key_count);
                hp->rowno>-1&&para->key_cmp(GETDATA(hp->rowno),key);
                hp=((multi_hash_node *)para->index)+hp->link) if(hp->link<0) return -1;
	if(hp->rowno<0) return -1;
        if(a_count) *a_count=hp->count;
        return hp->rowno;
}
예제 #9
0
파일: restore.c 프로젝트: alexmiao/moosefs
int do_setxattr(const char *filename,uint64_t lv,uint32_t ts,char *ptr) {
	uint32_t inode,valueleng,mode;
	uint8_t name[256];
	static uint8_t *value = NULL;
	static uint32_t valuesize = 0;
	EAT(ptr,filename,lv,'(');
	GETU32(inode,ptr);
	EAT(ptr,filename,lv,',');
	GETNAME(name,ptr,filename,lv,',');
	EAT(ptr,filename,lv,',');
	GETDATA(value,valueleng,valuesize,ptr,filename,lv,',');
	EAT(ptr,filename,lv,',');
	GETU32(mode,ptr);
	EAT(ptr,filename,lv,')');
	return fs_log_setxattr(ts,inode,strlen((char*)name),name,valueleng,value,mode);
}
예제 #10
0
파일: volume.cpp 프로젝트: Xylaant/Projects
struct Shade GetCR(double x, double y, double z)
/* x,y,z in voxel space, w/o rotation */
{

	struct Shade cl;

	int x2;
	int y2;
	int z2;

	double Id, Ia, Kd, Ka, I;
	Vector3 vec(3);
	Vector3 nvec(3);


	double s, c;


	vec[0] = x;
	vec[1] = y;
	vec[2] = z;

	/* Translate to center */

	vec -= vol_data.size() / 2.0;

	/* un-roate about x; */

	s = sin_neg_y_ang;
	c = cos_neg_y_ang;

	nvec[0] = vec[0];
	nvec[1] = vec[1] * c + vec[2] * s;
	nvec[2] = -vec[1] * s + vec[2] * c;

	vec[0] = nvec[0];
	vec[1] = nvec[1];
	vec[2] = nvec[2];

	/* Unrotate about y */

	s = sin_neg_x_ang;
	c = cos_neg_x_ang;

	nvec[0] = vec[0] * c - vec[2] * s;
	nvec[1] = vec[1];
	nvec[2] = vec[0] * s + vec[2] * c;

	vec[0] = nvec[0];
	vec[1] = nvec[1];
	vec[2] = nvec[2];

	/* Untranslate */
	vec += vol_data.size() / 2.0;

	/*okay, now get the color and data information */

	x2 = (int) vec[0];
	y2 = (int) vec[1];
	z2 = (int) vec[2];

	if ((vec[0] - x2) >= 0.5)
		x2++;
	if ((vec[1] - y2) >= 0.5)
		y2++;
	if ((vec[2] - z2) >= 0.5)
		z2++;

	if (x2 >= vol_data.size_x() || x2 < 0 || y2 >= vol_data.size_y() || y2 < 0 || z2 >= vol_data.size_z()
			|| z2 < 0) {
		cl.red = 0;
		cl.green = 0;
		cl.blue = 0;
		cl.alpha = 0;
	} else
		cl = GetColor(vol_data(x2,y2,z2));

	if (Glighting) {
		int i, j, k;
		int xn[3], yn[3], zn[3], den;
		int xx, yy, zz;

		for (i = 0; i <= 2; i++) {
			j = x2 - 1 + i;
			j = std::max(j, 0);
			j = std::min(j, vol_data.size_x() - 1);
			xn[i] = j;

			j = y2 - 1 + i;
			j = std::max(j, 0);
			j = std::min(j, vol_data.size_y() - 1);
			yn[i] = j;

			j = z2 - 1 + i;
			j = std::max(j, 0);
			j = std::min(j, vol_data.size_z() - 1);
			zn[i] = j;
		}
		nvec[0] = 0;
		nvec[1] = 0;
		nvec[2] = 0;

		for (i = 0; i <= 2; i++) {
			xx = i - 1;
			for (j = 0; j <= 2; j++) {
				yy = j - 1;
				for (k = 0; k <= 2; k++) {
					if (i == 1 && j == 1 && k == 1)
						continue;
					zz = k - 1;
					den = GetDen(vol_data(xn[i],yn[j],zn[k]));
					nvec[0] += xx * den;
					nvec[1] += yy * den;
					nvec[2] += zz * den;
				}
			}
		}

#if 0

		x1=std::max(x2-1,0);
		y1=std::max(y2-1,0);
		z1=std::max(z2-1,0);

		x3=std::min(x2+1,x_size-1);
		y3=std::min(y2+1,vol_data.size_y()-1);
		z3=std::min(z2+1,z_size-1);

		nvec[0]=GetDen(GETDATA(x3,y2,z2))-GetDen(GETDATA(x1,y2,z2));
		nvec[1]=GetDen(GETDATA(x2,y3,z2))-GetDen(GETDATA(x2,y1,z2));
		nvec[2]=GetDen(GETDATA(x2,y2,z3))-GetDen(GETDATA(x2,y2,z1));
#endif  

		normalize(nvec);


		/* Define these !!*/
		Kd = 0.8;

		Ka = 0.4;

		I = dot_prod(nvec, nvec);

		if (I == 0) {
			cl.alpha = 0;
			return cl;
		}
		Id =
				Kd * (dot_prod(lvect, nvec));


		if (Id < 0)
			Id = 0;

		Ia = Ka;

		I = Id + Ia;

		if (I > 1)
			I = 1.0;

		cl.red *= I;
		cl.green *= I;
		cl.blue *= I;

	}
	return cl;

}
예제 #11
0
파일: txtread.c 프로젝트: sharugupta/OpenUH
/*
 * Read TEXT records
 *
 *	Records and blocks are supported only in multiples of 8 bits.
 *	There is no logical limit for the maximum record size.  The 
 *	maximum block size is determined arbitrarily to be 512 words.
 *
 * Parameters:
 *      fio     - Pointer to fdinfo block
 *      bufptr  - bit pointer to where data is to go.
 *      nbytes  - number of bytes to be read
 *      stat    - pointer to status return word
 *      fulp    - full or partial write mode flag
 *      ubc     - pointer to unused bit count (not used)
 */
ssize_t
_txt_read(struct fdinfo *fio, bitptr bufptr, size_t nbytes, struct ffsw *stat,int fulp, int *ubc)
	{
	int64 	nbits, 
		bits,
		movdbits;
	int	ret,
		eorstat;

	nbits = (uint64)nbytes << 3;	/* convert bytes to bits */
	movdbits = 0;
	if (*ubc != 0)		/* ubc should always be zero */
		ERETURN(stat, FDC_ERR_UBC, 0);

	/* read after write error */ 
	if (fio->rwflag == WRITIN) 
		ERETURN(stat, FDC_ERR_RAWR, 0); 

	fio->rwflag = READIN;  /* set operation type */
/*
 * 	If segment is empty, get the next segment.
 */
	fio->ateor = 0;
	if (fio->segbits == 0)
		{
		ret = get_segment(fio, stat);
		/* if EOF or EOD found */
		if (ret > 0)
			return(0);
		if (ret < 0)
			return(ret); /* stat set by get_segment */
		}
/*
 *	Loop until one of the following occurs:
 *		- the caller's request of nbits is satisfied
 *		- an EOR is found
 *		- an EOF is found
 *		- an EOD is found
 */

	eorstat = FFCNT;
	while ( nbits > 0 ) /* while caller is not satisfied */
		{
/*
 *		If more bits are requested than are in the segment, return
 *		segment.  If the scc (segment operation from get_segment())
 *		equals SCCFULL then return (i.e., hit end-of-record (EOR)).
 *		If the scc equals SCCMIDL (i.e., the fio buffer is empty and 
 *		no EOR was hit) subtract the number of bits moved from nbits
 *		and go on.
 */
		bits = nbits;
		if (fio->segbits < nbits)
			bits = fio->segbits;

		GETDATA(bufptr, fio, bits);
		movdbits += bits;
		SET_BPTR(bufptr, INC_BPTR(bufptr, bits));
		nbits -= bits; 

		if (fio->segbits == 0)
			{
			if (fio->scc == SCCFULL)
				{
				nbits = 0; /* return anyway */
				eorstat = FFEOR;
				}
			else
				{
				ret = get_segment(fio, stat);
				/* if EOF or EOD found */
				if (ret > 0)
					return(0);
				if (ret < 0)
					return(ret); /* stat set by get_segment */
				}
			}

		} /* end while */
/*
 *	Set status now, before doing any skip to EOR
 *	Must check EOR status again...
 */
	if ((fio->segbits == 0) && (fio->scc == SCCFULL))
		eorstat = FFEOR;

	fio->recbits += movdbits;
/*
 *	If the mode is FULL and more bits are
 *	available in the current record,  -or- if
 *	the number of bits requested just happpened to
 *      be the number of bits in the record,  skip to the next EOR. 
 *	If EOF/EOD found while skipping, set the status (this is an error)
 *	and return.
 */
	if ((fulp == FULL) || (eorstat == FFEOR))
		{
		ret = skip2eor(fio, stat);
		if (ret > 0) return(0);	/* EOF/EOD */
		if (ret < 0) return(ERR); /* Status should be set */
		fio->last_recbits = fio->recbits;
		fio->recbits = 0;
		}

	SETSTAT(stat, eorstat, (uint64)movdbits >> 3); /* assume CNT */
	return ((uint64)movdbits >> 3);

	} /* end of _txt_read */
예제 #12
0
파일: proc.c 프로젝트: tolimit/nmon
/* Return of 0 means data not available */
void proc_lparcfg(struct cpuinfo_brk * cpuinfo_brk, struct lparcfg_brk * lparcfg_brk)
{
	static FILE *fp = (FILE *)-1;
	/* Only try to read /proc/ppc64/lparcfg once - remember if it's readable */
	static int lparinfo_not_available=0;
	int i;
	char *str;
	/* If we already read and processed /proc/lparcfg in this interval - just return */
	if( lparcfg_brk->lparcfg_processed == 1) {
		lparcfg_brk->result = 1;    
		return;
	}

	if( lparinfo_not_available == 1) {
		lparcfg_brk->result = 0;    
		return;
	}

	if( fp == (FILE *)-1) {
		if( (fp = fopen("/proc/ppc64/lparcfg","r")) == NULL) {
			error("failed to open - /proc/ppc64/lparcfg");
			fp = (FILE *)-1;
			lparinfo_not_available = 1;
			if(cpuinfo_brk->power_vm_type == VM_UNKNOWN) {
				/*  Heuristics for spotting PowerKVM Host
					a) inside ifdef POWER so can't be x86
					b) /proc/ppc64/lparcfg is missing
					c) /etc/ *ease files have hints
					Confirmed true for IBM_POWERKVM 2.1
					*/
				if(strncmp( cpuinfo_brk->easy[1], "IBM_PowerKVM", 12) == 0)
					cpuinfo_brk->power_vm_type = VM_POWERKVM_HOST;
				else
					cpuinfo_brk->power_vm_type = VM_NATIVE;
			}
			lparcfg_brk->result = 0;
			return;
		}
	}

	for(lparcfg_brk->lpar_count=0; lparcfg_brk->lpar_count < LPAR_LINE_MAX - 1; lparcfg_brk->lpar_count++) {
		if(fgets(lparcfg_brk->lpar_buffer[lparcfg_brk->lpar_count],LPAR_LINE_WIDTH-1,fp) == NULL)
			break;
	}
	if(lparcfg_brk->lparcfg_reread) { /* XXXX  unclear if close+open is necessary   - unfortunately this requires version many of Linux on POWER install to test early releases */
		fclose(fp);
		fp = (FILE *)-1;
	} else rewind(fp);

	str=locate(lparcfg_brk, "lparcfg");          sscanf(str, "lparcfg %s", lparcfg_brk->lparcfg.version_string);
	str=locate(lparcfg_brk, "serial_number");    sscanf(str, "serial_number=%s", lparcfg_brk->lparcfg.serial_number);
	str=locate(lparcfg_brk, "system_type");
	for(i=0;i<strlen(str);i++) /* Remove new spaces in massive string meaning PowerKVM Guest !!*/
		if(str[i] == ' ')
			str[i] = '-';
	sscanf(str, "system_type=%s", lparcfg_brk->lparcfg.system_type);
	if(cpuinfo_brk->power_vm_type == VM_UNKNOWN) {
		/*  Heuristics for spotting PowerKVM Guest
			a) inside ifdef POWER so can't be x86
			b) we have a /proc/ppc64/lparcfg - probably mostly missing (1.9)
			c) system type string includes "qemu"
			Confirmed true for SLES11.3 RHEL6.5 and Ubuntu 14.4.1
			*/
		if(strstr( lparcfg_brk->lparcfg.system_type, "(emulated-by-qemu)") == 0)
			cpuinfo_brk->power_vm_type = VM_POWERVM; /* not found */
		else
			cpuinfo_brk->power_vm_type = VM_POWERKVM_GUEST;
	}

#define GETDATA(variable) lparcfg_brk->lparcfg.variable = read_longlong(lparcfg_brk, __STRING(variable) );

	GETDATA(partition_id);
	GETDATA(BoundThrds);
	GETDATA(CapInc);
	GETDATA(DisWheRotPer);
	GETDATA(MinEntCap);
	GETDATA(MinEntCapPerVP);
	GETDATA(MinMem);
	GETDATA(DesMem);
	GETDATA(MinProcs);
	GETDATA(partition_max_entitled_capacity);
	GETDATA(system_potential_processors);
	GETDATA(partition_entitled_capacity);
	GETDATA(system_active_processors);
	GETDATA(pool_capacity);
	GETDATA(unallocated_capacity_weight);
	GETDATA(capacity_weight);
	GETDATA(capped);
	GETDATA(unallocated_capacity);
	lparcfg_brk->lparcfg.pool_idle_saved = lparcfg_brk->lparcfg.pool_idle_time;
	GETDATA(pool_idle_time);
	lparcfg_brk->lparcfg.pool_idle_diff = lparcfg_brk->lparcfg.pool_idle_time - lparcfg_brk->lparcfg.pool_idle_saved;
	GETDATA(pool_num_procs);
	lparcfg_brk->lparcfg.purr_saved = lparcfg_brk->lparcfg.purr;
	GETDATA(purr);
	lparcfg_brk->lparcfg.purr_diff = lparcfg_brk->lparcfg.purr - lparcfg_brk->lparcfg.purr_saved;
	GETDATA(partition_active_processors);
	GETDATA(partition_potential_processors);
	GETDATA(shared_processor_mode);
	/* Brute force, may provide temporary incorrect data during
	 * dynamic reconfiguraiton envents
	 */
	lparcfg_brk->lparcfg.smt_mode = cpuinfo_brk->cpus / lparcfg_brk->lparcfg.partition_active_processors;

	/* AMS additions */
	GETDATA(cmo_enabled);
	if( lparcfg_brk->lparcfg.cmo_enabled == NUMBER_NOT_VALID )      {
		lparcfg_brk->lparcfg.cmo_enabled = 0;
	}
	if( lparcfg_brk->lparcfg.cmo_enabled ) {
		GETDATA(entitled_memory_pool_number);   /*  pool number = 0 */
		GETDATA(entitled_memory_weight);        /* 0 to 255 */

		lparcfg_brk->lparcfg.cmo_faults_save = lparcfg_brk->lparcfg.cmo_faults;
		GETDATA(cmo_faults);                    /* Hypervisor Page-in faults = big number */
		lparcfg_brk->lparcfg.cmo_faults_diff = lparcfg_brk->lparcfg.cmo_faults - lparcfg_brk->lparcfg.cmo_faults_save;

		lparcfg_brk->lparcfg.cmo_fault_time_usec_save = lparcfg_brk->lparcfg.cmo_fault_time_usec;
		GETDATA(cmo_fault_time_usec);           /* Hypervisor time in micro seconds = big number */
		lparcfg_brk->lparcfg.cmo_fault_time_usec_diff = lparcfg_brk->lparcfg.cmo_fault_time_usec - lparcfg_brk->lparcfg.cmo_fault_time_usec_save;

		GETDATA(backing_memory);                /* AIX pmem in bytes */
		GETDATA(cmo_page_size);                 /* AMS page size in bytes */
		GETDATA(entitled_memory_pool_size);     /* AMS whole pool size in bytes */
		GETDATA(entitled_memory_loan_request);  /* AMS requesting more memory loaning */

	}
#ifdef EXPERIMENTAL
	GETDATA(DesEntCap);
	GETDATA(DesProcs);
	GETDATA(DesVarCapWt);
	GETDATA(DedDonMode);
	GETDATA(group);
	GETDATA(pool);
	GETDATA(entitled_memory);
	GETDATA(entitled_memory_group_number);
	GETDATA(unallocated_entitled_memory_weight);
	GETDATA(unallocated_io_mapping_entitlement);
#endif /* EXPERIMENTAL */

	lparcfg_brk->lparcfg_processed=1;
	lparcfg_brk->result = 1;
}
예제 #13
0
int
Pass1(FILE *fd, unsigned applied)
{
    u_char *p,*q;
    MD5_CTX ctx;
    int i,j,sep,cnt;
    u_char *md5=0,*name=0,*trash=0;
    struct CTM_Syntax *sp;
    int slashwarn=0, match=0, total_matches=0;
    unsigned current;
    char md5_1[33];

    if(Verbose>3)
	printf("Pass1 -- Checking integrity of incoming CTM-patch\n");
    MD5Init (&ctx);

    GETFIELD(p,' ');				/* CTM_BEGIN */
    if(strcmp(p,"CTM_BEGIN")) {
	Fatal("Probably not a CTM-patch at all.");
	if(Verbose>3)
	    fprintf(stderr,"Expected \"CTM_BEGIN\" got \"%s\".\n",p);
	return 1;
    }

    GETFIELDCOPY(Version,' ');				/* <Version> */
    if(strcmp(Version,VERSION)) {
	Fatal("CTM-patch is wrong version.");
	if(Verbose>3)
	    fprintf(stderr,"Expected \"%s\" got \"%s\".\n",VERSION,p);
	return 1;
    }

    GETFIELDCOPY(Name,' ');				/* <Name> */
    GETFIELDCOPY(Nbr,' ');				/* <Nbr> */
    GETFIELDCOPY(TimeStamp,' ');			/* <TimeStamp> */
    GETFIELDCOPY(Prefix,'\n');				/* <Prefix> */

    sscanf(Nbr, "%u", &current);
    if (FilterList || ListIt)
	current = 0;	/* ignore if -l or if filters are present */
    if(current && current <= applied) {
	if(Verbose > 0)
	    fprintf(stderr,"Delta number %u is already applied; ignoring.\n",
		    current);
	return Exit_Version;
    }

    for(;;) {
	Delete(md5);
	Delete(name);
	Delete(trash);
	cnt = -1;
	/* if a filter list is defined we assume that all pathnames require
	   an action opposite to that requested by the first filter in the
	   list.
	   If no filter is defined, all pathnames are assumed to match. */
	match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE);

	GETFIELD(p,' ');			/* CTM_something */

	if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') {
	    Fatal("Expected CTM keyword.");
	    fprintf(stderr,"Got [%s]\n",p);
	    return 1;
	}

	if(!strcmp(p+3,"_END"))
	    break;

	for(sp=Syntax;sp->Key;sp++)
	    if(!strcmp(p+3,sp->Key))
		goto found;
	Fatal("Expected CTM keyword.");
	fprintf(stderr,"Got [%s]\n",p);
	return 1;
    found:
	if(Verbose > 5)
	    fprintf(stderr,"%s ",sp->Key);
	for(i=0;(j = sp->List[i]);i++) {
	    if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes)
		sep = ' ';
	    else
		sep = '\n';

	    if(Verbose > 5)
	        fprintf(stderr," %x(%d)",sp->List[i],sep);

	    switch (j & CTM_F_MASK) {
		case CTM_F_Name: /* XXX check for garbage and .. */
		    GETFIELDCOPY(name,sep);
		    j = strlen(name);
		    if(name[j-1] == '/' && !slashwarn)  {
			fprintf(stderr,"Warning: contains trailing slash\n");
			slashwarn++;
		    }
		    if (name[0] == '/') {
			Fatal("Absolute paths are illegal.");
			Delete(name);
			return Exit_Mess;
		    }
		    q = name;
		    for (;;) {
			if (q[0] == '.' && q[1] == '.')
			    if (q[2] == '/' || q[2] == '\0') {
				Fatal("Paths containing '..' are illegal.");
				Delete(name);
				return Exit_Mess;
			    }
			if ((q = strchr(q, '/')) == NULL)
			    break;
			q++;
		    }

		    /* if we have been asked to `keep' files then skip
		       removes; i.e. we don't match these entries at
		       all. */
		    if (KeepIt &&
			(!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR"))) {
			match = CTM_FILTER_DISABLE;
			break;
		    }

		    /* If filter expression have been defined, match the
		       path name against the expression list.  */
		    
		    if (FilterList) {
			struct CTM_Filter *filter;

			for (filter = FilterList; filter; 
			     filter = filter->Next) {
				if (0 == regexec(&filter->CompiledRegex, name,
					0, 0, 0))
					/* if the name matches, adopt the 
					   action */
					match = filter->Action;
			}
		    }

		    /* Add up the total number of matches */
		    total_matches += match;
		    break;
		case CTM_F_Uid:
		    GETFIELD(p,sep);
		    while(*p) {
			if(!isdigit(*p)) {
			    Fatal("Non-digit in uid.");
			    return 32;
			}
			p++;
		    }
		    break;
		case CTM_F_Gid:
		    GETFIELD(p,sep);
		    while(*p) {
			if(!isdigit(*p)) {
			    Fatal("Non-digit in gid.");
			    return 32;
			}
			p++;
		    }
		    break;
		case CTM_F_Mode:
		    GETFIELD(p,sep);
		    while(*p) {
			if(!isdigit(*p)) {
			    Fatal("Non-digit in mode.");
			    return 32;
			}
			p++;
		    }
		    break;
		case CTM_F_MD5:
		    if(j & CTM_Q_MD5_Chunk) {
			GETFIELDCOPY(md5,sep);  /* XXX check for garbage */
		    } else if(j & CTM_Q_MD5_Before) {
			GETFIELD(p,sep);  /* XXX check for garbage */
		    } else if(j & CTM_Q_MD5_After) {
			GETFIELD(p,sep);  /* XXX check for garbage */
		    } else {
			fprintf(stderr,"List = 0x%x\n",j);
			Fatal("Unqualified MD5.");
			return 32;
		    }
		    break;
		case CTM_F_Count:
		    GETBYTECNT(cnt,sep);
		    break;
		case CTM_F_Bytes:
		    if(cnt < 0) WRONG
		    GETDATA(trash,cnt);
		    p = MD5Data(trash,cnt,md5_1);
		    if(md5 && strcmp(md5,p)) {
			Fatal("Internal MD5 failed.");
			return Exit_Garbage;
		default:
			fprintf(stderr,"List = 0x%x\n",j);
			Fatal("List had garbage.");
			return Exit_Garbage;
		    }
	    }
	}
	if(Verbose > 5)
	    putc('\n',stderr);
	if(ListIt && match)
	    printf("> %s %s\n", sp->Key, name);
    }

    Delete(md5);
    Delete(name);
    Delete(trash);

    q = MD5End (&ctx,md5_1);
    if(Verbose > 2)
	printf("Expecting Global MD5 <%s>\n",q);
    GETFIELD(p,'\n');			/* <MD5> */
    if(Verbose > 2)
	printf("Reference Global MD5 <%s>\n",p);
    if(strcmp(q,p)) {
	Fatal("MD5 sum doesn't match.");
	fprintf(stderr,"\tI have:<%s>\n",q);
	fprintf(stderr,"\tShould have been:<%s>\n",p);
	return Exit_Garbage;
    }
    if (-1 != getc(fd)) {
	if(!Force) {
	    Fatal("Trailing junk in CTM-file.  Can Force with -F.");
	    return 16;
	}
    }
    if ((Verbose > 1) && (0 == total_matches))
	printf("No matches in \"%s\"\n", FileName);
    return (total_matches ? Exit_OK : Exit_NoMatch);
}
예제 #14
0
int
PassB(FILE *fd)
{
    u_char *p,*q;
    MD5_CTX ctx;
    int i,j,sep,cnt;
    u_char *md5=0,*md5before=0,*trash=0,*name=0,*uid=0,*gid=0,*mode=0;
    struct CTM_Syntax *sp;
    FILE *b = 0;	/* backup command */
    u_char buf[BUFSIZ];
    char md5_1[33];
    int ret = 0;
    int match = 0;
    struct CTM_Filter *filter = NULL;

    if(Verbose>3)
	printf("PassB -- Backing up files which would be changed.\n");

    MD5Init (&ctx);
    snprintf(buf, sizeof(buf), fmtcheck(TarCmd, TARCMD), BackupFile);
    b=popen(buf, "w");
    if(!b) { warn("%s", buf); return Exit_Garbage; }

    GETFIELD(p,' '); if(strcmp("CTM_BEGIN",p)) WRONG
    GETFIELD(p,' '); if(strcmp(Version,p)) WRONG
    GETFIELD(p,' '); if(strcmp(Name,p)) WRONG
    GETFIELD(p,' '); if(strcmp(Nbr,p)) WRONG
    GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG
    GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG

    for(;;) {
	Delete(md5);
	Delete(uid);
	Delete(gid);
	Delete(mode);
	Delete(md5before);
	Delete(trash);
	Delete(name);
	cnt = -1;

	GETFIELD(p,' ');

	if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') WRONG

	if(!strcmp(p+3,"_END"))
	    break;

	for(sp=Syntax;sp->Key;sp++)
	    if(!strcmp(p+3,sp->Key))
		goto found;
	WRONG
    found:
	for(i=0;(j = sp->List[i]);i++) {
	    if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes)
		sep = ' ';
	    else
		sep = '\n';

	    switch (j & CTM_F_MASK) {
		case CTM_F_Name: GETNAMECOPY(name,sep,j, Verbose); break;
		case CTM_F_Uid:  GETFIELDCOPY(uid,sep); break;
		case CTM_F_Gid:  GETFIELDCOPY(gid,sep); break;
		case CTM_F_Mode: GETFIELDCOPY(mode,sep); break;
		case CTM_F_MD5:
		    if(j & CTM_Q_MD5_Before)
			GETFIELDCOPY(md5before,sep);
		    else
			GETFIELDCOPY(md5,sep);
		    break;
		case CTM_F_Count: GETBYTECNT(cnt,sep); break;
		case CTM_F_Bytes: GETDATA(trash,cnt); break;
		default: WRONG
		}
	    }
	/* XXX This should go away.  Disallow trailing '/' */
	j = strlen(name)-1;
	if(name[j] == '/') name[j] = '\0';

	if (KeepIt && 
	    (!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR")))
	    continue;
		
	/* match the name against the elements of the filter list.  The
	   action associated with the last matched filter determines whether
	   this file should be ignored or backed up. */
	match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE);
	for (filter = FilterList; filter; filter = filter->Next) {
	    if (0 == regexec(&filter->CompiledRegex, name, 0, 0, 0))
		match = filter->Action;
	}

	if (CTM_FILTER_DISABLE == match)
		continue;

	if (!strcmp(sp->Key,"FS") || !strcmp(sp->Key,"FN") ||
	    !strcmp(sp->Key,"AS") || !strcmp(sp->Key,"DR") || 
	    !strcmp(sp->Key,"FR")) {
	    /* send name to the archiver for a backup */
	    cnt = strlen(name);
	    if (cnt != fwrite(name,1,cnt,b) || EOF == fputc('\n',b)) {
		warn("%s", name);
		pclose(b);
		WRONG;
	    }
	}
    }

    ret = pclose(b);

    Delete(md5);
    Delete(uid);
    Delete(gid);
    Delete(mode);
    Delete(md5before);
    Delete(trash);
    Delete(name);

    q = MD5End (&ctx,md5_1);
    GETFIELD(p,'\n');			/* <MD5> */
    if(strcmp(q,p)) WRONG
    if (-1 != getc(fd)) WRONG
    return ret;
}