Exemple #1
0
static int
pass2check(struct inodesc *idesc)
{
	struct ext2fs_direct *dirp = idesc->id_dirp;
	struct inoinfo *inp;
	int n, entrysize, ret = 0;
	struct ext2fs_dinode *dp;
	char *errmsg;
	struct ext2fs_direct proto;
	char namebuf[MAXPATHLEN + 1];
	char pathbuf[MAXPATHLEN + 1];

	/*
	 * check for "."
	 */
	if (idesc->id_entryno != 0)
		goto chk1;
	if (letoh32(dirp->e2d_ino) != 0 && dirp->e2d_namlen == 1 &&
		dirp->e2d_name[0] == '.') {
		if (letoh32(dirp->e2d_ino) != idesc->id_number) {
			direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'");
			dirp->e2d_ino = htole32(idesc->id_number);
			if (reply("FIX") == 1)
				ret |= ALTERED;
		}
		if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
		    (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)
		    && (dirp->e2d_type != EXT2_FT_DIR)) {
			direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'");
			dirp->e2d_type = EXT2_FT_DIR;
			if (reply("FIX") == 1)
				ret |= ALTERED;
		}
		goto chk1;
	}
	direrror(idesc->id_number, "MISSING '.'");
	proto.e2d_ino = htole32(idesc->id_number);
	proto.e2d_namlen = 1;
	if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
	    (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE))
		proto.e2d_type = EXT2_FT_DIR;
	else
		proto.e2d_type = 0;
	(void)strlcpy(proto.e2d_name, ".", sizeof proto.e2d_name);
	entrysize = EXT2FS_DIRSIZ(proto.e2d_namlen);
	if (letoh32(dirp->e2d_ino) != 0 && strcmp(dirp->e2d_name, "..") != 0) {
		pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
			dirp->e2d_name);
	} else if (letoh16(dirp->e2d_reclen) < entrysize) {
		pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
	} else if (letoh16(dirp->e2d_reclen) < 2 * entrysize) {
		proto.e2d_reclen = dirp->e2d_reclen;
		memcpy(dirp, &proto, (size_t)entrysize);
		if (reply("FIX") == 1)
			ret |= ALTERED;
	} else {
		n = letoh16(dirp->e2d_reclen) - entrysize;
		proto.e2d_reclen = htole16(entrysize);
		memcpy(dirp, &proto, (size_t)entrysize);
		idesc->id_entryno++;
		lncntp[letoh32(dirp->e2d_ino)]--;
		dirp = (struct ext2fs_direct *)((char *)(dirp) + entrysize);
		memset(dirp, 0, (size_t)n);
		dirp->e2d_reclen = htole16(n);
		if (reply("FIX") == 1)
			ret |= ALTERED;
	}
chk1:
	if (idesc->id_entryno > 1)
		goto chk2;
	inp = getinoinfo(idesc->id_number);
	proto.e2d_ino = htole32(inp->i_parent);
	proto.e2d_namlen = 2;
	if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
	    (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE))
		proto.e2d_type = EXT2_FT_DIR;
	else
		proto.e2d_type = 0;
	(void)strlcpy(proto.e2d_name, "..", sizeof proto.e2d_name);
	entrysize = EXT2FS_DIRSIZ(2);
	if (idesc->id_entryno == 0) {
		n = EXT2FS_DIRSIZ(dirp->e2d_namlen);
		if (letoh16(dirp->e2d_reclen) < n + entrysize)
			goto chk2;
		proto.e2d_reclen = htole16(letoh16(dirp->e2d_reclen) - n);
		dirp->e2d_reclen = htole16(n);
		idesc->id_entryno++;
		lncntp[letoh32(dirp->e2d_ino)]--;
		dirp = (struct ext2fs_direct *)((char *)(dirp) + n);
		memset(dirp, 0, (size_t)letoh16(proto.e2d_reclen));
		dirp->e2d_reclen = proto.e2d_reclen;
	}
	if (letoh32(dirp->e2d_ino) != 0 &&
	    dirp->e2d_namlen == 2 &&
	    strncmp(dirp->e2d_name, "..", 2) == 0) {
		inp->i_dotdot = letoh32(dirp->e2d_ino);
		if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
		    (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)
		    && dirp->e2d_type != EXT2_FT_DIR) {
			direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
			dirp->e2d_type = EXT2_FT_DIR;
			if (reply("FIX") == 1)
				ret |= ALTERED;
		}
		goto chk2;
	}
	if (letoh32(dirp->e2d_ino) != 0 &&
		dirp->e2d_namlen == 1 &&
		strncmp(dirp->e2d_name, ".", 1) != 0) {
		fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
		pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
			dirp->e2d_name);
		inp->i_dotdot = (ino_t)-1;
	} else if (letoh16(dirp->e2d_reclen) < entrysize) {
		fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
		pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n");
		inp->i_dotdot = (ino_t)-1;
	} else if (inp->i_parent != 0) {
		/*
		 * We know the parent, so fix now.
		 */
		inp->i_dotdot = inp->i_parent;
		fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
		proto.e2d_reclen = dirp->e2d_reclen;
		memcpy(dirp, &proto, (size_t)entrysize);
		if (reply("FIX") == 1)
			ret |= ALTERED;
	}
	idesc->id_entryno++;
	if (letoh32(dirp->e2d_ino) != 0)
		lncntp[letoh32(dirp->e2d_ino)]--;
	return (ret|KEEPON);
chk2:
	if (letoh32(dirp->e2d_ino) == 0)
		return (ret|KEEPON);
	if (dirp->e2d_namlen <= 2 &&
	    dirp->e2d_name[0] == '.' &&
	    idesc->id_entryno >= 2) {
		if (dirp->e2d_namlen == 1) {
			direrror(idesc->id_number, "EXTRA '.' ENTRY");
			dirp->e2d_ino = 0;
			if (reply("FIX") == 1)
				ret |= ALTERED;
			return (KEEPON | ret);
		}
		if (dirp->e2d_name[1] == '.') {
			direrror(idesc->id_number, "EXTRA '..' ENTRY");
			dirp->e2d_ino = 0;
			if (reply("FIX") == 1)
				ret |= ALTERED;
			return (KEEPON | ret);
		}
	}
	idesc->id_entryno++;
	n = 0;
	if (letoh32(dirp->e2d_ino) > maxino ||
		(letoh32(dirp->e2d_ino) < EXT2_FIRSTINO &&
		 letoh32(dirp->e2d_ino) != EXT2_ROOTINO)) {
		fileerror(idesc->id_number, letoh32(dirp->e2d_ino), "I OUT OF RANGE");
		n = reply("REMOVE");
	} else {
again:
		switch (statemap[letoh32(dirp->e2d_ino)]) {
		case USTATE:
			if (idesc->id_entryno <= 2)
				break;
			fileerror(idesc->id_number, letoh32(dirp->e2d_ino), "UNALLOCATED");
			n = reply("REMOVE");
			break;

		case DCLEAR:
		case FCLEAR:
			if (idesc->id_entryno <= 2)
				break;
			if (statemap[letoh32(dirp->e2d_ino)] == FCLEAR)
				errmsg = "DUP/BAD";
			else if (!preen)
				errmsg = "ZERO LENGTH DIRECTORY";
			else {
				n = 1;
				break;
			}
			fileerror(idesc->id_number, letoh32(dirp->e2d_ino), errmsg);
			if ((n = reply("REMOVE")) == 1)
				break;
			dp = ginode(letoh32(dirp->e2d_ino));
			statemap[letoh32(dirp->e2d_ino)] =
			    (letoh16(dp->e2di_mode) & IFMT) == IFDIR ? DSTATE : FSTATE;
			lncntp[letoh32(dirp->e2d_ino)] = letoh16(dp->e2di_nlink);
			goto again;

		case DSTATE:
		case DFOUND:
			inp = getinoinfo(letoh32(dirp->e2d_ino));
			if (inp->i_parent != 0 && idesc->id_entryno > 2) {
				getpathname(pathbuf, sizeof pathbuf,
				    idesc->id_number, idesc->id_number);
				getpathname(namebuf, sizeof namebuf,
				    letoh32(dirp->e2d_ino), letoh32(dirp->e2d_ino));
				pwarn("%s %s %s\n", pathbuf,
				    "IS AN EXTRANEOUS HARD LINK TO DIRECTORY",
				    namebuf);
				if (preen)
					printf(" (IGNORED)\n");
				else if ((n = reply("REMOVE")) == 1)
					break;
			}
			if (idesc->id_entryno > 2)
				inp->i_parent = idesc->id_number;
			/* fall through */

		case FSTATE:
			if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
			    (sblock.e2fs.e2fs_features_incompat &
				EXT2F_INCOMPAT_FTYPE) &&
			    dirp->e2d_type !=
				inot2ext2dt(typemap[letoh32(dirp->e2d_ino)])) {
				dirp->e2d_type =
				    inot2ext2dt(typemap[letoh32(dirp->e2d_ino)]);
				fileerror(idesc->id_number,
				    letoh32(dirp->e2d_ino),
				    "BAD TYPE VALUE");
				if (reply("FIX") == 1)
					ret |= ALTERED;
			}
			lncntp[letoh32(dirp->e2d_ino)]--;
			break;

		default:
			errexit("BAD STATE %d FOR INODE I=%llu\n",
			    statemap[letoh32(dirp->e2d_ino)],
			    (unsigned long long)letoh32(dirp->e2d_ino));
		}
	}
	if (n == 0)
		return (ret|KEEPON);
	dirp->e2d_ino = 0;
	return (ret|KEEPON|ALTERED);
}
Exemple #2
0
void
ieee802_11_radio_if_print(u_int8_t *buf, u_int len)
{
	struct ieee80211_radiotap_header *rh =
	    (struct ieee80211_radiotap_header*)buf;
	struct ieee80211_frame *wh;
	u_int8_t *t;
	u_int32_t present;
	u_int rh_len;

	snapend = buf + len;

	TCHECK(*rh);

	rh_len = letoh16(rh->it_len);
	if (rh->it_version != 0) {
		PRINTF("[?radiotap + 802.11 v:%u]", rh->it_version);
		goto out;
	}

	wh = (struct ieee80211_frame *)(buf + rh_len);
	if (len <= rh_len || ieee80211_print(wh))
		PRINTF("[|802.11]");

	t = (u_int8_t*)buf + sizeof(struct ieee80211_radiotap_header);

	if ((present = letoh32(rh->it_present)) == 0)
		goto out;

	PRINTF(", <radiotap v%u", rh->it_version);

#define RADIOTAP(_x)	\
	(present & (1 << IEEE80211_RADIOTAP_##_x))

	if (RADIOTAP(TSFT)) {
		u_int64_t tsf;
		u_int32_t tsf_v[2];

		TCHECK2(*t, 8);

		tsf = letoh64(*(u_int64_t *)t);
		tsf_v[0] = (u_int32_t)(tsf >> 32);
		tsf_v[1] = (u_int32_t)(tsf & 0x00000000ffffffff);
		if (vflag > 1)
			PRINTF(", tsf 0x%08x%08x", tsf_v[0], tsf_v[1]);
		t += 8;
	}

	if (RADIOTAP(FLAGS)) {
		u_int8_t flags = *(u_int8_t*)t;
		TCHECK2(*t, 1);

		if (flags & IEEE80211_RADIOTAP_F_CFP)
			PRINTF(", CFP");
		if (flags & IEEE80211_RADIOTAP_F_SHORTPRE)
			PRINTF(", SHORTPRE");
		if (flags & IEEE80211_RADIOTAP_F_WEP)
			PRINTF(", WEP");
		if (flags & IEEE80211_RADIOTAP_F_FRAG)
			PRINTF(", FRAG");
		t += 1;
	}

	if (RADIOTAP(RATE)) {
		TCHECK2(*t, 1);
		if (vflag)
			PRINTF(", %uMbit/s", (*(u_int8_t*)t) / 2);
		t += 1;
	}

	if (RADIOTAP(CHANNEL)) {
		u_int16_t freq, flags;
		TCHECK2(*t, 2);

		freq = letoh16(*(u_int16_t*)t);
		t += 2;
		TCHECK2(*t, 2);
		flags = letoh16(*(u_int16_t*)t);
		t += 2;

		PRINTF(", chan %u", ieee80211_any2ieee(freq, flags));

		if (flags & IEEE80211_CHAN_DYN &&
		    flags & IEEE80211_CHAN_2GHZ)
			PRINTF(", 11g");
		else if (flags & IEEE80211_CHAN_CCK &&
		    flags & IEEE80211_CHAN_2GHZ)
			PRINTF(", 11b");
		else if (flags & IEEE80211_CHAN_OFDM &&
		    flags & IEEE80211_CHAN_2GHZ)
			PRINTF(", 11G");
		else if (flags & IEEE80211_CHAN_OFDM &&
		    flags & IEEE80211_CHAN_5GHZ)
			PRINTF(", 11a");

		if (flags & IEEE80211_CHAN_TURBO)
			PRINTF(", TURBO");
		if (flags & IEEE80211_CHAN_XR)
			PRINTF(", XR");
	}

	if (RADIOTAP(FHSS)) {
		TCHECK2(*t, 2);
		PRINTF(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1);
		t += 2;
	}

	if (RADIOTAP(DBM_ANTSIGNAL)) {
		TCHECK(*t);
		PRINTF(", sig %ddBm", *(int8_t*)t);
		t += 1;
	}

	if (RADIOTAP(DBM_ANTNOISE)) {
		TCHECK(*t);
		PRINTF(", noise %ddBm", *(int8_t*)t);
		t += 1;
	}

	if (RADIOTAP(LOCK_QUALITY)) {
		TCHECK2(*t, 2);
		if (vflag)
			PRINTF(", quality %u", letoh16(*(u_int16_t*)t));
		t += 2;
	}

	if (RADIOTAP(TX_ATTENUATION)) {
		TCHECK2(*t, 2);
		if (vflag)
			PRINTF(", txatt %u",
			    letoh16(*(u_int16_t*)t));
		t += 2;
	}

	if (RADIOTAP(DB_TX_ATTENUATION)) {
		TCHECK2(*t, 2);
		if (vflag)
			PRINTF(", txatt %udB",
			    letoh16(*(u_int16_t*)t));
		t += 2;
	}

	if (RADIOTAP(DBM_TX_POWER)) {
		TCHECK(*t);
		PRINTF(", txpower %ddBm", *(int8_t*)t);
		t += 1;
	}

	if (RADIOTAP(ANTENNA)) {
		TCHECK(*t);
		if (vflag)
			PRINTF(", antenna %u", *(u_int8_t*)t);
		t += 1;
	}

	if (RADIOTAP(DB_ANTSIGNAL)) {
		TCHECK(*t);
		PRINTF(", signal %udB", *(u_int8_t*)t);
		t += 1;
	}

	if (RADIOTAP(DB_ANTNOISE)) {
		TCHECK(*t);
		PRINTF(", noise %udB", *(u_int8_t*)t);
		t += 1;
	}

	if (RADIOTAP(FCS)) {
		TCHECK2(*t, 4);
		if (vflag)
			PRINTF(", fcs %08x", letoh32(*(u_int32_t*)t));
		t += 4;
	}

	if (RADIOTAP(RSSI)) {
		u_int8_t rssi, max_rssi;
		TCHECK(*t);
		rssi = *(u_int8_t*)t;
		t += 1;
		TCHECK(*t);
		max_rssi = *(u_int8_t*)t;
		t += 1;

		PRINTF(", rssi %u/%u", rssi, max_rssi);
	}

#undef RADIOTAP

	PRINTF(">");
	goto out;

 trunc:
	/* Truncated frame */
	PRINTF("[|radiotap + 802.11]");

 out:
	PRINTF(NULL);
}
Exemple #3
0
static bool loadSound(const unsigned id)
{
    sound_t ** sound;
    file_t fp;
    wave_header_t header;
    U16 u16Temp;
    U32 u32Temp;
    int bytesRead;
    bool isHeaderValid;

    if (!fromResourceIdToSound(id, &sound))
    {
        return false;
    }

    *sound = sysmem_push(sizeof(**sound));
    if (!*sound)
    {
        return false;
    }

    (*sound)->buf = NULL;
    (*sound)->dispose = true; /* sounds are "fire and forget" by default */

    (*sound)->name = u_strdup(resourceFiles[id]);
    if (!(*sound)->name)
    {
        return false;
    }

    fp = sysfile_open(resourceFiles[id]);
    if (!fp)
    {
        sys_error("(resources) unable to open \"%s\"", resourceFiles[id]);
        return false;
    }

    bytesRead = sysfile_read(fp, &header, sizeof(header), 1);
    sysfile_close(fp);
    if (bytesRead != 1)
    {
        sys_error("(resources) unable to read WAVE header from \"%s\"", resourceFiles[id]);
        return false;
    }

    isHeaderValid = false;
    for (;;)
    {
        if (memcmp(header.riffChunkId, "RIFF", 4) ||
            memcmp(header.riffType, "WAVE", 4) ||
            memcmp(header.formatChunkId, "fmt ", 4) ||
            memcmp(header.dataChunkId, "data", 4))
        {
            break;
        }
        memcpy(&u16Temp, header.audioFormat, sizeof(u16Temp));
        if (letoh16(u16Temp) != Wave_AUDIO_FORMAT)
        {
            break;
        }
        memcpy(&u16Temp, header.channelCount, sizeof(u16Temp));
        if (letoh16(u16Temp) != Wave_CHANNEL_COUNT)
        {
            break;
        }
        memcpy(&u32Temp, header.sampleRate, sizeof(u32Temp));
        if (letoh32(u32Temp) != Wave_SAMPLE_RATE)
        {
            isHeaderValid = false;
            break;
        }
        memcpy(&u16Temp, header.bitsPerSample, sizeof(u16Temp));
        if (letoh16(u16Temp) != Wave_BITS_PER_SAMPLE)
        {
            isHeaderValid = false;
            break;
        }

        memcpy(&u32Temp, header.dataChunkSize, sizeof(u32Temp));
        (*sound)->len = letoh32(u32Temp);

        isHeaderValid = true;
        break;
    }
    if (!isHeaderValid)
    {
        sys_error("(resources) incompatible WAVE header for \"%s\"", resourceFiles[id]);
        return false;
    }
    return true;
}
Exemple #4
0
uint16_t fmle16(uint16_t x) { return letoh16(x); }
Exemple #5
0
int
ieee80211_elements(struct ieee80211_frame *wh)
{
	u_int8_t *frm;
	u_int8_t *tstamp, *bintval, *capinfo;
	int i;

	frm = (u_int8_t *)&wh[1];

	tstamp = frm;
	TCHECK2(*tstamp, 8);
	frm += 8;

	bintval = frm;
	TCHECK2(*bintval, 2);
	frm += 2;

	if (vflag)
		PRINTF(", interval %u", letoh16(*(u_int16_t *)bintval));

	capinfo = frm;
	TCHECK2(*capinfo, 2);
	frm += 2;

#if 0
	if (vflag)
		printb(", caps", letoh16(*(u_int16_t *)capinfo),
		    IEEE80211_CAPINFO_BITS);
#endif

	while (TTEST2(*frm, 2)) {
		u_int len = frm[1];
		u_int8_t *data = frm + 2;

		if (!TTEST2(*data, len))
			break;

#define ELEM_CHECK(l)	if (len != l) break

		switch (*frm) {
		case IEEE80211_ELEMID_SSID:
			PRINTF(", ssid");
			ieee80211_print_essid(data, len);
			break;
		case IEEE80211_ELEMID_RATES:
			if (!vflag)
				break;
			PRINTF(", rates");
			for (i = len; i > 0; i--, data++)
				PRINTF(" %uM",
				    (data[0] & IEEE80211_RATE_VAL) / 2);
			break;
		case IEEE80211_ELEMID_FHPARMS:
			ELEM_CHECK(5);
			PRINTF(", fh (dwell %u, chan %u, index %u)",
			    (data[1] << 8) | data[0],
			    (data[2] - 1) * 80 + data[3],	/* FH_CHAN */
			    data[4]);
			break;
		case IEEE80211_ELEMID_DSPARMS:
			ELEM_CHECK(1);
			if (!vflag)
				break;
			PRINTF(", ds");
			PRINTF(" (chan %u)", data[0]);
			break;
		case IEEE80211_ELEMID_CFPARMS:
			if (!vflag)
				break;
			PRINTF(", cf");
			ieee80211_print_element(data, len);
			break;
		case IEEE80211_ELEMID_TIM:
			if (!vflag)
				break;
			PRINTF(", tim");
			ieee80211_print_element(data, len);
			break;
		case IEEE80211_ELEMID_IBSSPARMS:
			if (!vflag)
				break;
			PRINTF(", ibss");
			ieee80211_print_element(data, len);
			break;
		case IEEE80211_ELEMID_COUNTRY:
			if (!vflag)
				break;
			PRINTF(", country");
			for (i = len; i > 0; i--, data++)
				PRINTF(" %u", data[0]);
			break;
		case IEEE80211_ELEMID_CHALLENGE:
			if (!vflag)
				break;
			PRINTF(", challenge");
			ieee80211_print_element(data, len);
			break;
		case IEEE80211_ELEMID_ERP:
			if (!vflag)
				break;
			PRINTF(", erp");
			ieee80211_print_element(data, len);
			break;
		case IEEE80211_ELEMID_RSN:
			if (!vflag)
				break;
			PRINTF(", rsn");
			ieee80211_print_element(data, len);
			break;
		case IEEE80211_ELEMID_XRATES:
			if (!vflag)
				break;
			PRINTF(", xrates");
			for (i = len; i > 0; i--, data++)
				PRINTF(" %uM",
				    (data[0] & IEEE80211_RATE_VAL) / 2);
			break;
		case IEEE80211_ELEMID_TPC:
			if (!vflag)
				break;
			PRINTF(", tpc");
			ieee80211_print_element(data, len);
			break;
		case IEEE80211_ELEMID_CCKM:
			if (!vflag)
				break;
			PRINTF(", cckm");
			ieee80211_print_element(data, len);
			break;
		case IEEE80211_ELEMID_VENDOR:
			if (!vflag)
				break;
			PRINTF(", vendor");
			ieee80211_print_element(data, len);
			break;
		default:
			if (!vflag)
				break;
			PRINTF(", %u:%u", (u_int) *frm, len);
			ieee80211_print_element(data, len);
			break;
		}
		frm += len + 2;

		if (frm >= snapend)
			break;
	}

#undef ELEM_CHECK

	return (0);

 trunc:
	/* Truncated elements in frame */
	return (1);
}
Exemple #6
0
void
nfe_rxeof(struct nfe_softc *sc)
{
	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
	struct nfe_desc32 *desc32;
	struct nfe_desc64 *desc64;
	struct nfe_rx_data *data;
	struct nfe_jbuf *jbuf;
	struct mbuf *m, *mnew;
	bus_addr_t physaddr;
#if NVLAN > 0
	uint32_t vtag;
#endif
	uint16_t flags;
	int error, len;

	for (;;) {
		data = &sc->rxq.data[sc->rxq.cur];

		if (sc->sc_flags & NFE_40BIT_ADDR) {
			desc64 = &sc->rxq.desc64[sc->rxq.cur];
			nfe_rxdesc64_sync(sc, desc64, BUS_DMASYNC_POSTREAD);

			flags = letoh16(desc64->flags);
			len = letoh16(desc64->length) & 0x3fff;
#if NVLAN > 0
			vtag = letoh32(desc64->physaddr[1]);
#endif
		} else {
			desc32 = &sc->rxq.desc32[sc->rxq.cur];
			nfe_rxdesc32_sync(sc, desc32, BUS_DMASYNC_POSTREAD);

			flags = letoh16(desc32->flags);
			len = letoh16(desc32->length) & 0x3fff;
		}

		if (flags & NFE_RX_READY)
			break;

		if ((sc->sc_flags & (NFE_JUMBO_SUP | NFE_40BIT_ADDR)) == 0) {
			if (!(flags & NFE_RX_VALID_V1))
				goto skip;

			if ((flags & NFE_RX_FIXME_V1) == NFE_RX_FIXME_V1) {
				flags &= ~NFE_RX_ERROR;
				len--;	/* fix buffer length */
			}
		} else {
			if (!(flags & NFE_RX_VALID_V2))
				goto skip;

			if ((flags & NFE_RX_FIXME_V2) == NFE_RX_FIXME_V2) {
				flags &= ~NFE_RX_ERROR;
				len--;	/* fix buffer length */
			}
		}

		if (flags & NFE_RX_ERROR) {
			ifp->if_ierrors++;
			goto skip;
		}

		/*
		 * Try to allocate a new mbuf for this ring element and load
		 * it before processing the current mbuf. If the ring element
		 * cannot be loaded, drop the received packet and reuse the
		 * old mbuf. In the unlikely case that the old mbuf can't be
		 * reloaded either, explicitly panic.
		 */
		MGETHDR(mnew, M_DONTWAIT, MT_DATA);
		if (mnew == NULL) {
			ifp->if_ierrors++;
			goto skip;
		}

		if (sc->sc_flags & NFE_USE_JUMBO) {
			if ((jbuf = nfe_jalloc(sc)) == NULL) {
				m_freem(mnew);
				ifp->if_ierrors++;
				goto skip;
			}
			MEXTADD(mnew, jbuf->buf, NFE_JBYTES, 0, nfe_jfree, sc);

			bus_dmamap_sync(sc->sc_dmat, sc->rxq.jmap,
			    mtod(data->m, caddr_t) - sc->rxq.jpool, NFE_JBYTES,
			    BUS_DMASYNC_POSTREAD);

			physaddr = jbuf->physaddr;
		} else {
			MCLGET(mnew, M_DONTWAIT);
			if (!(mnew->m_flags & M_EXT)) {
				m_freem(mnew);
				ifp->if_ierrors++;
				goto skip;
			}

			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
			    data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
			bus_dmamap_unload(sc->sc_dmat, data->map);

			error = bus_dmamap_load(sc->sc_dmat, data->map,
			    mtod(mnew, void *), MCLBYTES, NULL,
			    BUS_DMA_READ | BUS_DMA_NOWAIT);
			if (error != 0) {
				m_freem(mnew);

				/* try to reload the old mbuf */
				error = bus_dmamap_load(sc->sc_dmat, data->map,
				    mtod(data->m, void *), MCLBYTES, NULL,
				    BUS_DMA_READ | BUS_DMA_NOWAIT);
				if (error != 0) {
					/* very unlikely that it will fail.. */
					panic("%s: could not load old rx mbuf",
					    sc->sc_dev.dv_xname);
				}
				ifp->if_ierrors++;
				goto skip;
			}
			physaddr = data->map->dm_segs[0].ds_addr;
		}

		/*
		 * New mbuf successfully loaded, update Rx ring and continue
		 * processing.
		 */
		m = data->m;
		data->m = mnew;

		/* finalize mbuf */
		m->m_pkthdr.len = m->m_len = len;
		m->m_pkthdr.rcvif = ifp;

		if ((sc->sc_flags & NFE_HW_CSUM) &&
		    (flags & NFE_RX_IP_CSUMOK)) {
			m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
			if (flags & NFE_RX_UDP_CSUMOK)
				m->m_pkthdr.csum_flags |= M_UDP_CSUM_IN_OK;
			if (flags & NFE_RX_TCP_CSUMOK)
				m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK;
		}

#if NVLAN > 0
		if ((vtag & NFE_RX_VTAG) && (sc->sc_flags & NFE_HW_VLAN)) {
			m->m_pkthdr.ether_vtag = vtag & 0xffff;
			m->m_flags |= M_VLANTAG;
		}
#endif

#if NBPFILTER > 0
		if (ifp->if_bpf)
			bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_IN);
#endif
		ifp->if_ipackets++;
		ether_input_mbuf(ifp, m);

		/* update mapping address in h/w descriptor */
		if (sc->sc_flags & NFE_40BIT_ADDR) {
#if defined(__LP64__)
			desc64->physaddr[0] = htole32(physaddr >> 32);
#endif
			desc64->physaddr[1] = htole32(physaddr & 0xffffffff);
		} else {
Exemple #7
0
static void
loadLibs(const char *apkName)
{
  chdir(getenv("GRE_HOME"));

  simple_linker_init();

  struct stat status;
  if (!stat(apkName, &status))
    apk_mtime = status.st_mtime;

  struct timeval t0, t1;
  gettimeofday(&t0, 0);
  struct rusage usage1;
  getrusage(RUSAGE_THREAD, &usage1);

  void *zip = map_file(apkName);
  struct cdir_end *dirend = (struct cdir_end *)((char *)zip + zip_size - sizeof(*dirend));
  while ((void *)dirend > zip &&
         letoh32(dirend->signature) != CDIR_END_SIG)
    dirend = (struct cdir_end *)((char *)dirend - 1);
  if (letoh32(dirend->signature) != CDIR_END_SIG) {
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't find end of central directory record");
    return;
  }

  uint32_t cdir_offset = letoh32(dirend->cdir_offset);
  uint16_t cdir_entries = letoh16(dirend->cdir_entries);

  struct cdir_entry *cdir_start = (struct cdir_entry *)((char *)zip + cdir_offset);

  lib_mapping = (struct mapping_info *)calloc(MAX_MAPPING_INFO, sizeof(*lib_mapping));
#ifdef MOZ_CRASHREPORTER
  file_ids = (char *)extractBuf("lib.id", zip, cdir_start, cdir_entries);
#endif

#define MOZLOAD(name) mozload("lib" name ".so", zip, cdir_start, cdir_entries)
  MOZLOAD("mozalloc");
  MOZLOAD("nspr4");
  MOZLOAD("plc4");
  MOZLOAD("plds4");
  MOZLOAD("mozsqlite3");
  MOZLOAD("nssutil3");
  MOZLOAD("nss3");
  MOZLOAD("ssl3");
  MOZLOAD("smime3");
  xul_handle = MOZLOAD("xul");
  MOZLOAD("xpcom");
  MOZLOAD("nssckbi");
  MOZLOAD("freebl3");
  MOZLOAD("softokn3");
#undef MOZLOAD

  close(zip_fd);

#ifdef MOZ_CRASHREPORTER
  free(file_ids);
  file_ids = NULL;
#endif

  if (!xul_handle)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't get a handle to libxul!");

#define GETFUNC(name) f_ ## name = (name ## _t) __wrap_dlsym(xul_handle, "Java_org_mozilla_gecko_GeckoAppShell_" #name)
  GETFUNC(nativeInit);
  GETFUNC(nativeRun);
  GETFUNC(notifyGeckoOfEvent);
  GETFUNC(processNextNativeEvent);
  GETFUNC(setSurfaceView);
  GETFUNC(setSoftwareLayerClient);
  GETFUNC(onResume);
  GETFUNC(onLowMemory);
  GETFUNC(callObserver);
  GETFUNC(removeObserver);
  GETFUNC(onChangeNetworkLinkStatus);
  GETFUNC(reportJavaCrash);
  GETFUNC(executeNextRunnable);
  GETFUNC(cameraCallbackBridge);
  GETFUNC(notifyUriVisited);
  GETFUNC(notifyBatteryChange);
  GETFUNC(notifySmsReceived);
#undef GETFUNC
  sStartupTimeline = (uint64_t *)__wrap_dlsym(xul_handle, "_ZN7mozilla15StartupTimeline16sStartupTimelineE");
  gettimeofday(&t1, 0);
  struct rusage usage2;
  getrusage(RUSAGE_THREAD, &usage2);
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loaded libs in %dms total, %dms user, %dms system, %d faults",
                      (t1.tv_sec - t0.tv_sec)*1000 + (t1.tv_usec - t0.tv_usec)/1000, 
                      (usage2.ru_utime.tv_sec - usage1.ru_utime.tv_sec)*1000 + (usage2.ru_utime.tv_usec - usage1.ru_utime.tv_usec)/1000,
                      (usage2.ru_stime.tv_sec - usage1.ru_stime.tv_sec)*1000 + (usage2.ru_stime.tv_usec - usage1.ru_stime.tv_usec)/1000,
                      usage2.ru_majflt-usage1.ru_majflt);

  StartupTimeline_Record(LINKER_INITIALIZED, &t0);
  StartupTimeline_Record(LIBRARIES_LOADED, &t1);
}
Exemple #8
0
/* This is called before the superblock is copied.  Watch out for endianity! */
static int
e2fs_sbcheck(struct ext2fs *fs, int ronly)
{
	u_int32_t tmp;

	tmp = letoh16(fs->e2fs_magic);
	if (tmp != E2FS_MAGIC) {
		printf("ext2fs: wrong magic number 0x%x\n", tmp);
		return (EIO);		/* XXX needs translation */
	}

	tmp = letoh32(fs->e2fs_log_bsize);
	if (tmp > 2) {
		/* skewed log(block size): 1024 -> 0 | 2048 -> 1 | 4096 -> 2 */
		tmp += 10;
		printf("ext2fs: wrong log2(block size) %d\n", tmp);
		return (EIO);	   /* XXX needs translation */
	}

	if (fs->e2fs_bpg == 0) {
		printf("ext2fs: zero blocks per group\n");
		return (EIO);
	}

	tmp = letoh32(fs->e2fs_rev);
	if (tmp > E2FS_REV1) {
		printf("ext2fs: wrong revision number 0x%x\n", tmp);
		return (EIO);		/* XXX needs translation */
	}
	else if (tmp == E2FS_REV0)
		return (0);

	tmp = letoh32(fs->e2fs_first_ino);
	if (tmp != EXT2_FIRSTINO) {
		printf("ext2fs: first inode at 0x%x\n", tmp);
		return (EINVAL);      /* XXX needs translation */
	}

	tmp = letoh32(fs->e2fs_features_incompat);
	if (tmp & ~(EXT2F_INCOMPAT_SUPP | EXT4F_RO_INCOMPAT_SUPP)) {
		printf("ext2fs: unsupported incompat features 0x%x\n", tmp);
		return (EINVAL);      /* XXX needs translation */
	}

	if (!ronly && (tmp & EXT4F_RO_INCOMPAT_SUPP)) {
		printf("ext4fs: only read-only support right now\n");
		return (EROFS);      /* XXX needs translation */
	}

	if (tmp & EXT2F_INCOMPAT_RECOVER) {
		printf("ext2fs: your file system says it needs recovery\n");
		if (!ronly)
			return (EROFS);	/* XXX needs translation */
	}

	tmp = letoh32(fs->e2fs_features_rocompat);
	if (!ronly && (tmp & ~EXT2F_ROCOMPAT_SUPP)) {
		printf("ext2fs: unsupported R/O compat features 0x%x\n", tmp);
		return (EROFS);      /* XXX needs translation */
	}

	return (0);
}
Exemple #9
0
static void * mozload(const char * path, void *zip,
                      struct cdir_entry *cdir_start, uint16_t cdir_entries)
{
#ifdef DEBUG
  struct timeval t0, t1;
  gettimeofday(&t0, 0);
#endif

  struct cdir_entry *entry = find_cdir_entry(cdir_start, cdir_entries, path);
  struct local_file_header *file = (struct local_file_header *)((char *)zip + letoh32(entry->offset));
  void * data = ((char *)&file->data) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
  void * handle;

  if (extractLibs) {
    char fullpath[PATH_MAX];
    snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path);
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "resolved %s to %s", path, fullpath);
    extractFile(fullpath, entry, data);
    handle = __wrap_dlopen(fullpath, RTLD_LAZY);
    if (!handle)
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", fullpath, __wrap_dlerror());
#ifdef DEBUG
    gettimeofday(&t1, 0);
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path,
                        (((long long)t1.tv_sec * 1000000LL) +
                          (long long)t1.tv_usec) -
                        (((long long)t0.tv_sec * 1000000LL) +
                          (long long)t0.tv_usec));
#endif
    return handle;
  }

  size_t offset = letoh32(entry->offset) + sizeof(*file) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
  bool skipLibCache = false;
  int fd = zip_fd;
  void * buf = NULL;
  uint32_t lib_size = letoh32(entry->uncompressed_size);
  int cache_fd = 0;
  if (letoh16(file->compression) == DEFLATE) {
    cache_fd = lookupLibCacheFd(path);
    fd = cache_fd;
    if (fd < 0) {
      char fullpath[PATH_MAX];
      snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path);
      fd = open(fullpath, O_RDWR);
      struct stat status;
      if (stat(fullpath, &status) ||
          status.st_size != lib_size ||
          apk_mtime > status.st_mtime) {
        unlink(fullpath);
        fd = -1;
      } else {
        cache_fd = fd;
        addLibCacheFd(path, fd);
      }
    }
    if (fd < 0)
      fd = createAshmem(lib_size, path);
#ifdef DEBUG
    else
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loading %s from cache", path);
#endif
    if (fd < 0) {
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't open " ASHMEM_NAME_DEF ", Error %d, %s, using a file", errno, strerror(errno));
      char fullpath[PATH_MAX];
      snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path);
      fd = open(fullpath, O_RDWR | O_CREAT);
      if (fd < 0) {
        __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't create a file either, giving up");
        return NULL;
      }
      // we'd like to use fallocate here, but it doesn't exist currently?
      if (lseek(fd, lib_size - 1, SEEK_SET) == (off_t) - 1) {
         __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "seeking file failed");
        close(fd);
        return NULL;
      }
      if (write(fd, "", 1) != 1) {
        __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "writting one byte to the file failed");
        close(fd);
        return NULL;
      }
      skipLibCache = true;
      addLibCacheFd(path, fd);
    }
    buf = mmap(NULL, lib_size,
               PROT_READ | PROT_WRITE,
               MAP_SHARED, fd, 0);
    if (buf == (void *)-1) {
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't mmap decompression buffer");
      close(fd);
      return NULL;
    }

    offset = 0;

    if (cache_fd < 0) {
      extractLib(entry, data, buf);
#ifdef ANDROID_ARM_LINKER
      /* We just extracted data that is going to be executed in the future.
       * We thus need to ensure Instruction and Data cache coherency. */
      cacheflush((unsigned) buf, (unsigned) buf + entry->uncompressed_size, 0);
#endif
      if (!skipLibCache)
        addLibCacheFd(path, fd, lib_size, buf);
    }

    // preload libxul, to avoid slowly demand-paging it
    if (!strcmp(path, "libxul.so"))
      madvise(buf, entry->uncompressed_size, MADV_WILLNEED);
    data = buf;
  }

#ifdef DEBUG
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loading %s with len %d (0x%08x) and offset %d (0x%08x)", path, lib_size, lib_size, offset, offset);
#endif

  handle = moz_mapped_dlopen(path, RTLD_LAZY, fd, data,
                             lib_size, offset);
  if (!handle)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", path, __wrap_dlerror());

  // if we're extracting the libs to disk and cache_fd is not valid then 
  // keep this buffer around so it can be used to write to disk
  if (buf && (!extractLibs || cache_fd >= 0))
    munmap(buf, lib_size);

#ifdef DEBUG
  gettimeofday(&t1, 0);
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path, (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) -
               (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec));
#endif

  return handle;
}
Exemple #10
0
int
wi_read_record_usb(struct wi_softc *wsc, struct wi_ltv_gen *ltv)
{
	struct wi_usb_chain	*c;
	struct wi_usb_softc	*sc = wsc->wi_usb_cdata;
	struct wi_rridreq	*prid;
	int			total_len, rnd_len;
	int			err;
	struct wi_ltv_gen	*oltv = NULL, p2ltv;

	DPRINTFN(5,("%s: %s: enter rid=%x\n",
	    sc->wi_usb_dev.dv_xname, __func__, ltv->wi_type));

	/* Do we need to deal with these here, as in _io version?
	 * WI_RID_ENCRYPTION -> WI_RID_P2_ENCRYPTION
	 * WI_RID_TX_CRYPT_KEY -> WI_RID_P2_TX_CRYPT_KEY
	 */
	if (wsc->sc_firmware_type != WI_LUCENT) {
		oltv = ltv;
		switch (ltv->wi_type) {
		case WI_RID_ENCRYPTION:
			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
			p2ltv.wi_len = 2;
			ltv = &p2ltv;
			break;
		case WI_RID_TX_CRYPT_KEY:
			if (ltv->wi_val > WI_NLTV_KEYS)
				return (EINVAL);
			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
			p2ltv.wi_len = 2;
			ltv = &p2ltv;
			break;
		}
	}

	wi_usb_tx_lock(sc);

	c = &sc->wi_usb_tx_chain[0];
	prid = c->wi_usb_buf;

	total_len = sizeof(struct wi_rridreq);
	rnd_len = ROUNDUP64(total_len);

	if (rnd_len > WI_USB_BUFSZ) {
		printf("read_record buf size err %x %x\n", 
		    rnd_len, WI_USB_BUFSZ);
		wi_usb_tx_unlock(sc);
		return EIO;
	}

	sc->ridltv = ltv;
	sc->ridresperr = 0;

	prid->type = htole16(WI_USB_RRIDREQ);
	prid->frmlen = htole16(2);	/* variable size? */
	prid->rid  = htole16(ltv->wi_type);

	bzero(((char*)prid)+total_len, rnd_len - total_len);

	usbd_setup_xfer(c->wi_usb_xfer, sc->wi_usb_ep[WI_USB_ENDPT_TX],
	    c, c->wi_usb_buf, rnd_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
	    WI_USB_TX_TIMEOUT, wi_usb_txeof);

	DPRINTFN(10,("%s: %s: total_len=%x, wilen %d\n",
	    sc->wi_usb_dev.dv_xname, __func__, total_len, ltv->wi_len));

	err = wi_usb_do_transmit_sync(sc, c, &sc->ridresperr);

	/* Do we need to deal with these here, as in _io version?
	 *
	 * WI_RID_TX_RATE
	 * WI_RID_CUR_TX_RATE
	 * WI_RID_ENCRYPTION
	 * WI_RID_TX_CRYPT_KEY
	 * WI_RID_CNFAUTHMODE
	 */
	if (ltv->wi_type == WI_RID_PORTTYPE && wsc->wi_ptype == WI_PORTTYPE_IBSS
	    && ltv->wi_val == wsc->wi_ibss_port) {
		/*
		 * Convert vendor IBSS port type to WI_PORTTYPE_IBSS.
		 * Since Lucent uses port type 1 for BSS *and* IBSS we
		 * have to rely on wi_ptype to distinguish this for us.
		 */
		ltv->wi_val = htole16(WI_PORTTYPE_IBSS);
	} else if (wsc->sc_firmware_type != WI_LUCENT) {
		int v;

		switch (oltv->wi_type) {
		case WI_RID_TX_RATE:
		case WI_RID_CUR_TX_RATE:
			switch (letoh16(ltv->wi_val)) {
			case 1: v = 1; break;
			case 2: v = 2; break;
			case 3:	v = 6; break;
			case 4: v = 5; break;
			case 7: v = 7; break;
			case 8: v = 11; break;
			case 15: v = 3; break;
			default: v = 0x100 + letoh16(ltv->wi_val); break;
			}
			oltv->wi_val = htole16(v);
			break;
		case WI_RID_ENCRYPTION:
			oltv->wi_len = 2;
			if (ltv->wi_val & htole16(0x01))
				oltv->wi_val = htole16(1);
			else
				oltv->wi_val = htole16(0);
			break;
		case WI_RID_TX_CRYPT_KEY:
		case WI_RID_CNFAUTHMODE:
			oltv->wi_len = 2;
			oltv->wi_val = ltv->wi_val;
			break;
		}
	}

	if (err == 0)
		err = sc->ridresperr;

	sc->ridresperr = 0;

	wi_usb_tx_unlock(sc);

	DPRINTFN(5,("%s: %s: exit err=%x\n",
	    sc->wi_usb_dev.dv_xname, __func__, err));
	return err;
}
Exemple #11
0
int
wi_write_record_usb(struct wi_softc *wsc, struct wi_ltv_gen *ltv)
{
	struct wi_usb_chain	*c;
	struct wi_usb_softc	*sc = wsc->wi_usb_cdata;
	struct wi_wridreq	*prid;
	int			total_len, rnd_len;
	int			err;
	struct wi_ltv_gen	p2ltv;
	u_int16_t		val = 0;
	int			i;

	DPRINTFN(5,("%s: %s: enter rid=%x wi_len %d copying %x\n",
	    sc->wi_usb_dev.dv_xname, __func__, ltv->wi_type, ltv->wi_len,
	    (ltv->wi_len-1)*2 ));

	/* Do we need to deal with these here, as in _io version?
	 * WI_PORTTYPE_IBSS -> WI_RID_PORTTYPE
	 * RID_TX_RATE munging
	 * RID_ENCRYPTION
	 * WI_RID_TX_CRYPT_KEY
	 * WI_RID_DEFLT_CRYPT_KEYS
	 */
	if (ltv->wi_type == WI_RID_PORTTYPE &&
	    letoh16(ltv->wi_val) == WI_PORTTYPE_IBSS) {
		/* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */
		p2ltv.wi_type = WI_RID_PORTTYPE;
		p2ltv.wi_len = 2;
		p2ltv.wi_val = wsc->wi_ibss_port;
		ltv = &p2ltv;
	} else if (wsc->sc_firmware_type != WI_LUCENT) {
		int v;

		switch (ltv->wi_type) {
		case WI_RID_TX_RATE:
			p2ltv.wi_type = WI_RID_TX_RATE;
			p2ltv.wi_len = 2;
			switch (letoh16(ltv->wi_val)) {
			case 1: v = 1; break;
			case 2: v = 2; break;
			case 3:	v = 15; break;
			case 5: v = 4; break;
			case 6: v = 3; break;
			case 7: v = 7; break;
			case 11: v = 8; break;
			default: return EINVAL;
			}
			p2ltv.wi_val = htole16(v);
			ltv = &p2ltv;
			break;
		case WI_RID_ENCRYPTION:
			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
			p2ltv.wi_len = 2;
			if (ltv->wi_val & htole16(0x01)) {
				val = PRIVACY_INVOKED;
				/*
				 * If using shared key WEP we must set the
				 * EXCLUDE_UNENCRYPTED bit.  Symbol cards
				 * need this bit set even when not using
				 * shared key. We can't just test for
				 * IEEE80211_AUTH_SHARED since Symbol cards
				 * have 2 shared key modes.
				 */
				if (wsc->wi_authtype != IEEE80211_AUTH_OPEN ||
				    wsc->sc_firmware_type == WI_SYMBOL)
					val |= EXCLUDE_UNENCRYPTED;

				switch (wsc->wi_crypto_algorithm) {
				case WI_CRYPTO_FIRMWARE_WEP:
					/*
					 * TX encryption is broken in
					 * Host AP mode.
					 */
					if (wsc->wi_ptype == WI_PORTTYPE_HOSTAP)
						val |= HOST_ENCRYPT;
					break;
				case WI_CRYPTO_SOFTWARE_WEP:
					val |= HOST_ENCRYPT|HOST_DECRYPT;
					break;
				}
				p2ltv.wi_val = htole16(val);
			} else
				p2ltv.wi_val = htole16(HOST_ENCRYPT | HOST_DECRYPT);
			ltv = &p2ltv;
			break;
		case WI_RID_TX_CRYPT_KEY:
			if (ltv->wi_val > WI_NLTV_KEYS)
				return (EINVAL);
			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
			p2ltv.wi_len = 2;
			p2ltv.wi_val = ltv->wi_val;
			ltv = &p2ltv;
			break;
		case WI_RID_DEFLT_CRYPT_KEYS: {
				int error;
				int keylen;
				struct wi_ltv_str ws;
				struct wi_ltv_keys *wk;

				wk = (struct wi_ltv_keys *)ltv;
				keylen = wk->wi_keys[wsc->wi_tx_key].wi_keylen;
				keylen = letoh16(keylen);

				for (i = 0; i < 4; i++) {
					bzero(&ws, sizeof(ws));
					ws.wi_len = (keylen > 5) ? 8 : 4;
					ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
					bcopy(&wk->wi_keys[i].wi_keydat,
					    ws.wi_str, keylen);
					error = wi_write_record_usb(wsc,
					    (struct wi_ltv_gen *)&ws);
					if (error)
						return (error);
				}
			}
			return (0);
		}
	}

	wi_usb_tx_lock(sc);

	c = &sc->wi_usb_tx_chain[0];

	prid = c->wi_usb_buf;

	total_len = sizeof(prid->type) + sizeof(prid->frmlen) +
	    sizeof(prid->rid) + (ltv->wi_len-1)*2;
	rnd_len = ROUNDUP64(total_len);
	if (rnd_len > WI_USB_BUFSZ) {
		printf("write_record buf size err %x %x\n", 
		    rnd_len, WI_USB_BUFSZ);
		wi_usb_tx_unlock(sc);
		return EIO;
	}

	prid->type = htole16(WI_USB_WRIDREQ);
	prid->frmlen = htole16(ltv->wi_len);
	prid->rid  = htole16(ltv->wi_type);
	if (ltv->wi_len > 1)
		bcopy((u_int8_t *)&ltv->wi_val, (u_int8_t *)&prid->data[0],
		    (ltv->wi_len-1)*2);

	bzero(((char*)prid)+total_len, rnd_len - total_len);

	usbd_setup_xfer(c->wi_usb_xfer, sc->wi_usb_ep[WI_USB_ENDPT_TX],
	    c, c->wi_usb_buf, rnd_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
	    WI_USB_TX_TIMEOUT, wi_usb_txeof);

	err = wi_usb_do_transmit_sync(sc, c, &sc->ridresperr);

	if (err == 0)
		err = sc->ridresperr;

	sc->ridresperr = 0;

	wi_usb_tx_unlock(sc);

	DPRINTFN(5,("%s: %s: exit err=%x\n",
	    sc->wi_usb_dev.dv_xname, __func__, err));
	return err;
}
Exemple #12
0
int
wi_send_packet(struct wi_usb_softc *sc, int id)
{
	struct wi_usb_chain	*c;
	struct wi_frame		*wibuf;
	int			total_len, rnd_len;
	int			err;

	c = &sc->wi_usb_tx_chain[0];

	DPRINTFN(10,("%s: %s: id=%x\n",
	    sc->wi_usb_dev.dv_xname, __func__, id));

	/* assemble packet from write_data buffer */
	if (id == 0 || id == 1) {
		/* tx_lock acquired before wi_start() */
		wibuf = sc->wi_usb_txmem[id];

		total_len = sizeof (struct wi_frame) +
		    letoh16(wibuf->wi_dat_len);
		rnd_len = ROUNDUP64(total_len);
		if ((total_len > sc->wi_usb_txmemsize[id]) ||
		   (rnd_len > WI_USB_BUFSZ )){
			printf("invalid packet len: %x memsz %x max %x\n",
			    total_len, sc->wi_usb_txmemsize[id], WI_USB_BUFSZ);

			err = EIO;
			goto err_ret;
		}

		sc->txresp = WI_CMD_TX;
		sc->txresperr = 0;

		bcopy(wibuf, c->wi_usb_buf, total_len);

		bzero(((char *)c->wi_usb_buf)+total_len,
		    rnd_len - total_len);

		/* zero old packet for next TX */
		bzero(wibuf, total_len);

		total_len = rnd_len;

		DPRINTFN(5,("%s: %s: id=%x len=%x\n",
		    sc->wi_usb_dev.dv_xname, __func__, id, total_len));

		usbd_setup_xfer(c->wi_usb_xfer, sc->wi_usb_ep[WI_USB_ENDPT_TX],
		    c, c->wi_usb_buf, rnd_len,
		    USBD_FORCE_SHORT_XFER | USBD_NO_COPY,
		    WI_USB_TX_TIMEOUT, wi_usb_txeof_frm);

		err = usbd_transfer(c->wi_usb_xfer);
		if (err != USBD_IN_PROGRESS && err != USBD_NORMAL_COMPLETION) {
			printf("%s: %s: error=%s\n",
			    sc->wi_usb_dev.dv_xname, __func__,
			    usbd_errstr(err));
			/* Stop the interface from process context. */
			wi_usb_stop(sc);
			err = EIO;
		} else {
			err = 0;
		}

		DPRINTFN(5,("%s: %s: exit err=%x\n",
		    sc->wi_usb_dev.dv_xname, __func__, err));
err_ret:
		return err;
	}
	printf("%s:%s: invalid packet id sent %x\n",
	    sc->wi_usb_dev.dv_xname, __func__, id);
	return 0;
}
Exemple #13
0
/*
 * A frame has been received.
 */
void
wi_usb_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
{
	struct wi_usb_chain	*c = priv;
	struct wi_usb_softc	*sc = c->wi_usb_sc;
	wi_usb_usbin		*uin;
	int			total_len = 0;
	u_int16_t		rtype;

	if (sc->wi_usb_dying)
		return;

	DPRINTFN(10,("%s: %s: enter status=%d\n", sc->wi_usb_dev.dv_xname,
		    __func__, status));


	if (status != USBD_NORMAL_COMPLETION) {
		if (status == USBD_NOT_STARTED || status == USBD_IOERROR
		    || status == USBD_CANCELLED) {
			printf("%s: %u usb errors on rx: %s\n",
			    sc->wi_usb_dev.dv_xname, 1,
			    /* sc->wi_usb_rx_errs, */
			    usbd_errstr(status));
			return;
		}
#if 0
		sc->wi_usb_rx_errs++;
		if (usbd_ratecheck(&sc->wi_usb_rx_notice)) {
			printf("%s: %u usb errors on rx: %s\n",
			    sc->wi_usb_dev.dv_xname, sc->wi_usb_rx_errs,
			    usbd_errstr(status));
			sc->wi_usb_rx_errs = 0;
		}
#endif
		if (status == USBD_STALLED) {
			sc->wi_usb_refcnt++;
			usbd_clear_endpoint_stall_async(
			    sc->wi_usb_ep[WI_USB_ENDPT_RX]);
			if (--sc->wi_usb_refcnt < 0)
				usb_detach_wakeup(&sc->wi_usb_dev);
		}
		goto done;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);

	if (total_len < 6) /* short XXX */
		goto done;

	uin = (wi_usb_usbin *)(c->wi_usb_buf);

	rtype = letoh16(uin->type);


#if 0
	wi_dump_data(c->wi_usb_buf, total_len);
#endif

	if (WI_USB_ISRXFRM(rtype)) {
		wi_usb_rxfrm(sc, uin, total_len);
		goto done;
	}
	if (WI_USB_ISTXFRM(rtype)) {
		DPRINTFN(2,("%s: %s: txfrm type %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, rtype));
		wi_usb_txfrm(sc, uin, total_len);
		goto done;
	}

	switch (rtype) {
	case WI_USB_INFOFRM:
		/* info packet, INFO_FID hmm */
		DPRINTFN(10,("%s: %s: infofrm type %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, rtype));
		wi_usb_infofrm(c, total_len);
		break;
	case WI_USB_CMDRESP:
		wi_usb_cmdresp(c);
		break;
	case WI_USB_WRIDRESP:
		wi_usb_wridresp(c);
		break;
	case WI_USB_RRIDRESP:
		wi_usb_rridresp(c);
		break;
	case WI_USB_WMEMRESP:
		/* Not currently used */
		DPRINTFN(2,("%s: %s: wmemresp type %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, rtype));
		break;
	case WI_USB_RMEMRESP:
		/* Not currently used */
		DPRINTFN(2,("%s: %s: rmemresp type %x\n",
		    sc->wi_usb_dev.dv_xname, __func__, rtype));
		break;
	case WI_USB_BUFAVAIL:
		printf("wi_usb: received USB_BUFAVAIL packet\n"); /* XXX */
		break;
	case WI_USB_ERROR:
		printf("wi_usb: received USB_ERROR packet\n"); /* XXX */
		break;
#if 0
	default:
		printf("wi_usb: received Unknown packet 0x%x len %x\n",
		    rtype, total_len);
		wi_dump_data(c->wi_usb_buf, total_len);
#endif
	}

 done:
	/* Setup new transfer. */
	usbd_setup_xfer(c->wi_usb_xfer, sc->wi_usb_ep[WI_USB_ENDPT_RX],
	    c, c->wi_usb_buf, WI_USB_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
	    USBD_NO_TIMEOUT, wi_usb_rxeof);
	sc->wi_usb_refcnt++;
	usbd_transfer(c->wi_usb_xfer);
	if (--sc->wi_usb_refcnt < 0)
		usb_detach_wakeup(&sc->wi_usb_dev);

	DPRINTFN(10,("%s: %s: start rx\n", sc->wi_usb_dev.dv_xname,
		    __func__));
}
Exemple #14
0
/*
 * If filename is NULL, just throw away the result
 */
bool unshield_file_save (Unshield* unshield, int index, const char* filename)/*{{{*/
{
  bool success = false;
  FILE* output = NULL;
  unsigned char* input_buffer   = (unsigned char*)malloc(BUFFER_SIZE+1);
  unsigned char* output_buffer  = (unsigned char*)malloc(BUFFER_SIZE);
  int bytes_left;
  uLong total_written = 0;
  UnshieldReader* reader = NULL;
  FileDescriptor* file_descriptor;
	MD5_CTX md5;

	MD5Init(&md5);

  if (!unshield)
    goto exit;

  if (!(file_descriptor = unshield_get_file_descriptor(unshield, index)))
  {
    unshield_error("Failed to get file descriptor for file %i", index);
    goto exit;
  }

  if ((file_descriptor->flags & FILE_INVALID) || 0 == file_descriptor->data_offset)
  {
    /* invalid file */
    goto exit;
  }

  if (file_descriptor->link_flags & LINK_PREV)
  {
    success = unshield_file_save(unshield, file_descriptor->link_previous, filename);
    goto exit;
  }

  reader = unshield_reader_create(unshield, index, file_descriptor);
  if (!reader)
  {
    unshield_error("Failed to create data reader for file %i", index);
    goto exit;
  }

  if (unshield_fsize(reader->volume_file) == (long)file_descriptor->data_offset)
  {
    unshield_error("File %i is not inside the cabinet.", index);
    goto exit;
  }

  if (filename) 
  {
    output = fopen(filename, "w");
    if (!output)
    {
      unshield_error("Failed to open output file '%s'", filename);
      goto exit;
    }
  }

  if (file_descriptor->flags & FILE_COMPRESSED)
    bytes_left = file_descriptor->compressed_size;
  else
    bytes_left = file_descriptor->expanded_size;

  /*unshield_trace("Bytes to read: %i", bytes_left);*/

  while (bytes_left > 0)
  {
    uLong bytes_to_write = BUFFER_SIZE;
    int result;

    if (file_descriptor->flags & FILE_COMPRESSED)
    {
      uLong read_bytes;
      uint16_t bytes_to_read = 0;

      if (!unshield_reader_read(reader, &bytes_to_read, sizeof(bytes_to_read)))
      {
#if VERBOSE
        unshield_error("Failed to read %i bytes of file %i (%s) from input cabinet file %i", 
            sizeof(bytes_to_read), index, unshield_file_name(unshield, index), file_descriptor->volume);
#endif
        goto exit;
      }

      bytes_to_read = letoh16(bytes_to_read);
      if (!unshield_reader_read(reader, input_buffer, bytes_to_read))
      {
#if VERBOSE
        unshield_error("Failed to read %i bytes of file %i (%s) from input cabinet file %i", 
            bytes_to_read, index, unshield_file_name(unshield, index), file_descriptor->volume);
#endif
        goto exit;
      }

      /* add a null byte to make inflate happy */
      input_buffer[bytes_to_read] = 0;
      read_bytes = bytes_to_read+1;
      result = unshield_uncompress(output_buffer, &bytes_to_write, input_buffer, &read_bytes);

      if (Z_OK != result)
      {
        unshield_error("Decompression failed with code %i. bytes_to_read=%i, volume_bytes_left=%i, volume=%i, read_bytes=%i", 
            result, bytes_to_read, reader->volume_bytes_left, file_descriptor->volume, read_bytes);
        goto exit;
      }

#if VERBOSE >= 3
    unshield_trace("read_bytes = %i", 
        read_bytes);
#endif

      bytes_left -= 2;
      bytes_left -= bytes_to_read;
    }
    else
    {
      bytes_to_write = MIN(bytes_left, BUFFER_SIZE);

      if (!unshield_reader_read(reader, output_buffer, bytes_to_write))
      {
#if VERBOSE
        unshield_error("Failed to read %i bytes from input cabinet file %i", 
            bytes_to_write, file_descriptor->volume);
#endif
        goto exit;
      }

      bytes_left -= bytes_to_write;
    }

    MD5Update(&md5, output_buffer, bytes_to_write);

    if (output)
    {
      if (bytes_to_write != fwrite(output_buffer, 1, bytes_to_write, output))
      {
        unshield_error("Failed to write %i bytes to file '%s'", bytes_to_write, filename);
        goto exit;
      }
    }

    total_written += bytes_to_write;
  }

  if (file_descriptor->expanded_size != total_written)
  {
    unshield_error("Expanded size expected to be %i, but was %i", 
        file_descriptor->expanded_size, total_written);
    goto exit;
  }

  if (unshield->header_list->major_version >= 6)
  {
    unsigned char md5result[16];
    MD5Final(md5result, &md5);

    if (0 != memcmp(md5result, file_descriptor->md5, 16))
    {
      unshield_error("MD5 checksum failure for file %i (%s)", 
          index, unshield_file_name(unshield, index));
      goto exit;
    }
  }

  success = true;
  
exit:
  unshield_reader_destroy(reader);
  FCLOSE(output);
  FREE(input_buffer);
  FREE(output_buffer);
  return success;
}/*}}}*/
Exemple #15
0
void
pass2(void)
{
	struct ext2fs_dinode *dp;
	struct inoinfo **inpp, *inp;
	struct inoinfo **inpend;
	struct inodesc curino;
	struct ext2fs_dinode dino;
	char pathbuf[MAXPATHLEN + 1];

	switch (statemap[EXT2_ROOTINO]) {

	case USTATE:
		pfatal("ROOT INODE UNALLOCATED");
		if (reply("ALLOCATE") == 0)
			errexit("%s\n", "");
		if (allocdir(EXT2_ROOTINO, EXT2_ROOTINO, 0755) != EXT2_ROOTINO)
			errexit("CANNOT ALLOCATE ROOT INODE\n");
		break;

	case DCLEAR:
		pfatal("DUPS/BAD IN ROOT INODE");
		if (reply("REALLOCATE")) {
			freeino(EXT2_ROOTINO);
			if (allocdir(EXT2_ROOTINO, EXT2_ROOTINO, 0755) != EXT2_ROOTINO)
				errexit("CANNOT ALLOCATE ROOT INODE\n");
			break;
		}
		if (reply("CONTINUE") == 0)
			errexit("%s\n", "");
		break;

	case FSTATE:
	case FCLEAR:
		pfatal("ROOT INODE NOT DIRECTORY");
		if (reply("REALLOCATE")) {
			freeino(EXT2_ROOTINO);
			if (allocdir(EXT2_ROOTINO, EXT2_ROOTINO, 0755) != EXT2_ROOTINO)
				errexit("CANNOT ALLOCATE ROOT INODE\n");
			break;
		}
		if (reply("FIX") == 0)
			errexit("%s\n", "");
		dp = ginode(EXT2_ROOTINO);
		dp->e2di_mode = htole16((letoh16(dp->e2di_mode) & ~IFMT) | IFDIR);
		inodirty();
		break;

	case DSTATE:
		break;

	default:
		errexit("BAD STATE %d FOR ROOT INODE\n", statemap[EXT2_ROOTINO]);
	}

	/*
	 * Sort the directory list into disk block order.
	 */
	qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort);
	/*
	 * Check the integrity of each directory.
	 */
	memset(&curino, 0, sizeof(struct inodesc));
	curino.id_type = DATA;
	curino.id_func = pass2check;
	inpend = &inpsort[inplast];
	for (inpp = inpsort; inpp < inpend; inpp++) {
		inp = *inpp;
		if (inp->i_isize == 0)
			continue;
		if (inp->i_isize < MINDIRSIZE) {
			direrror(inp->i_number, "DIRECTORY TOO SHORT");
			inp->i_isize = roundup(MINDIRSIZE, sblock.e2fs_bsize);
			if (reply("FIX") == 1) {
				dp = ginode(inp->i_number);
				inossize(dp, inp->i_isize);
				inodirty();
			}
		} else if ((inp->i_isize & (sblock.e2fs_bsize - 1)) != 0) {
			getpathname(pathbuf, sizeof pathbuf, inp->i_number,
			    inp->i_number);
			pwarn("DIRECTORY %s: LENGTH %lu NOT MULTIPLE OF %d",
			    pathbuf, (u_long)inp->i_isize, sblock.e2fs_bsize);
			if (preen)
				printf(" (ADJUSTED)\n");
			inp->i_isize = roundup(inp->i_isize, sblock.e2fs_bsize);
			if (preen || reply("ADJUST") == 1) {
				dp = ginode(inp->i_number);
				inossize(dp, inp->i_isize);
				inodirty();
			}
		}
		memset(&dino, 0, sizeof(struct ext2fs_dinode));
		dino.e2di_mode = htole16(IFDIR);
		inossize(&dino, inp->i_isize);
		memcpy(&dino.e2di_blocks[0], &inp->i_blks[0], (size_t)inp->i_numblks);
		curino.id_number = inp->i_number;
		curino.id_parent = inp->i_parent;
		(void)ckinode(&dino, &curino);
	}
	/*
	 * Now that the parents of all directories have been found,
	 * make another pass to verify the value of `..'
	 */
	for (inpp = inpsort; inpp < inpend; inpp++) {
		inp = *inpp;
		if (inp->i_parent == 0 || inp->i_isize == 0)
			continue;
		if (inp->i_dotdot == inp->i_parent ||
		    inp->i_dotdot == (ino_t)-1)
			continue;
		if (inp->i_dotdot == 0) {
			inp->i_dotdot = inp->i_parent;
			fileerror(inp->i_parent, inp->i_number, "MISSING '..'");
			if (reply("FIX") == 0)
				continue;
			(void)makeentry(inp->i_number, inp->i_parent, "..");
			lncntp[inp->i_parent]--;
			continue;
		}
		fileerror(inp->i_parent, inp->i_number,
		    "BAD INODE NUMBER FOR '..'");
		if (reply("FIX") == 0)
			continue;
		lncntp[inp->i_dotdot]++;
		lncntp[inp->i_parent]--;
		inp->i_dotdot = inp->i_parent;
		(void)changeino(inp->i_number, "..", inp->i_parent);
	}
	/*
	 * Mark all the directories that can be found from the root.
	 */
	propagate();
}
Exemple #16
0
void
ubcmtp_tp_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
	struct ubcmtp_softc *sc = priv;
	struct ubcmtp_finger *pkt;
	u_int32_t pktlen;
	int i, diff = 0, finger = 0, fingers = 0, s, t;

	if (usbd_is_dying(sc->sc_udev) || !(sc->sc_status & UBCMTP_ENABLED))
		return;

	if (status != USBD_NORMAL_COMPLETION) {
		DPRINTF("%s: %s with status 0x%x\n", sc->sc_dev.dv_xname,
		    __func__, status);

		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
			return;
		if (status == USBD_STALLED)
			usbd_clear_endpoint_stall_async(sc->sc_tp_pipe);
		return;
	}

	usbd_get_xfer_status(xfer, NULL, NULL, &pktlen, NULL);

	if (sc->tp_pkt == NULL || pktlen < sc->tp_offset)
		return;

	pkt = (struct ubcmtp_finger *)(sc->tp_pkt + sc->tp_offset);
	fingers = (pktlen - sc->tp_offset) / sizeof(struct ubcmtp_finger);

	for (i = 0; i < fingers; i++) {
		if ((int16_t)letoh16(pkt[i].touch_major) == 0) {
			/* finger lifted */
			sc->pos[i].down = 0;
			diff = 1;
			continue;
		}

		if (!sc->pos[finger].down) {
			sc->pos[finger].down = 1;
			diff = 1;
		}

		if ((t = (int16_t)letoh16(pkt[i].abs_x)) != sc->pos[finger].x) {
			sc->pos[finger].x = t;
			diff = 1;
		}

		if ((t = (int16_t)letoh16(pkt[i].abs_y)) != sc->pos[finger].y) {
			sc->pos[finger].y = t;
			diff = 1;
		}

		if ((t = (int16_t)letoh16(pkt[i].rel_x)) != sc->pos[finger].dx) {
			sc->pos[finger].dx = t;
			diff = 1;
		}

		if ((t = (int16_t)letoh16(pkt[i].rel_y)) != sc->pos[finger].dy) {
			sc->pos[finger].dy = t;
			diff = 1;
		}

		finger++;
	}

	if (sc->dev_type->type == UBCMTP_TYPE2 ||
	    sc->dev_type->type == UBCMTP_TYPE3) {
		if (sc->dev_type->type == UBCMTP_TYPE2)
			t = !!((int16_t)letoh16(sc->tp_pkt[UBCMTP_TYPE2_BTOFF]));
		else if (sc->dev_type->type == UBCMTP_TYPE3)
			t = !!((int16_t)letoh16(sc->tp_pkt[UBCMTP_TYPE3_BTOFF]));

		if (sc->btn != t) {
			sc->btn = t;
			diff = 1;

			DPRINTF("%s: [button]\n", sc->sc_dev.dv_xname);
		}
	}

	if (diff) {
		s = spltty();

		DPRINTF("%s: ", sc->sc_dev.dv_xname);

		if (sc->wsmode == WSMOUSE_NATIVE) {
			DPRINTF("absolute input %d, %d (finger %d, button %d)\n",
			    sc->pos[0].x, sc->pos[0].y, finger, sc->btn);
			wsmouse_input(sc->sc_wsmousedev, sc->btn, sc->pos[0].x,
			    sc->pos[0].y,
			    (finger == 0 ? 0 : 50), /* fake z for now */
			    finger,
			    WSMOUSE_INPUT_ABSOLUTE_X |
			    WSMOUSE_INPUT_ABSOLUTE_Y |
			    WSMOUSE_INPUT_ABSOLUTE_Z |
			    WSMOUSE_INPUT_ABSOLUTE_W);
		} else {
			DPRINTF("relative input %d, %d (button %d)\n",
			    sc->pos[0].dx, sc->pos[0].dy, sc->btn);
			wsmouse_input(sc->sc_wsmousedev, sc->btn,
			    sc->pos[0].dx, sc->pos[0].dy, 0, 0,
			    WSMOUSE_INPUT_DELTA);
		}
		splx(s);
	}
}
Exemple #17
0
int getifinfo(char *ifname, struct ifinfo_t *info)
{
	struct ifreq ifr;
	int r;
	struct sockaddr_in *sa;

#ifdef linux
	static FILE *froute = NULL;
	static FILE *fwireless = NULL;
	static FILE *fdev = NULL;
#elif defined(__OpenBSD__)
	struct ifreq ibuf[32];
	struct ifconf ifc;
	struct ifreq *ifrp, *ifend;
#endif

	char parent[16];
	char buf[1024];
	char *p;
	char a[16];
	int b,c,d;

#ifdef linux
	if(froute == NULL) froute = fopen("/proc/net/route", "r");
	if(fwireless == NULL) fwireless = fopen("/proc/net/wireless", "r");
	if(fdev == NULL) fdev = fopen("/proc/net/dev", "r");
#endif


	strcpy(parent, ifname);
	p=strchr(parent, ':');
	if(p) *p=0;

	strcpy(info->id, ifname);

	strcpy(ifr.ifr_name, ifname);

	// Get status (UP/DOWN)

	if(ioctl(fd, SIOCGIFFLAGS, &ifr) != -1) {
		sa = (struct sockaddr_in *)&(ifr.ifr_addr);
		info->state = (ifr.ifr_flags & 1) ? 1 : 0;
	} else {
		info->state = 0;
	}

	// Get mac address

#ifdef linux
	if(ioctl(fd, SIOCGIFHWADDR, &ifr) != -1) {
		memcpy(info->hw, ifr.ifr_hwaddr.sa_data, 6);
	} else {
		memset(info->hw, 0, 6);
	}
#elif defined(__OpenBSD__)
	ifc.ifc_len = sizeof(ibuf);
	ifc.ifc_buf = (caddr_t) ibuf;
	if (ioctl(fd, SIOCGIFCONF, (char *) &ifc) == -1 ||
			ifc.ifc_len < sizeof(struct ifreq)) {
		memset(info->hw, 0, 6);
	} else {
		/* Search interface configuration list for link layer address. */
		ifrp = ibuf;
		ifend = (struct ifreq *) ((char *) ibuf + ifc.ifc_len);
		while (ifrp < ifend) {
			/* Look for interface */
			if (strcmp(ifname, ifrp->ifr_name) == 0 &&
					ifrp->ifr_addr.sa_family == AF_LINK &&
					((struct sockaddr_dl *) &ifrp->ifr_addr)->sdl_type == IFT_ETHER) {
				memcpy(info->hw, LLADDR((struct sockaddr_dl *) &ifrp->ifr_addr), 6);
				break;
			}
			/* Bump interface config pointer */
			r = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
			if (r < sizeof(*ifrp))
				r = sizeof(*ifrp);
			ifrp = (struct ifreq *) ((char *) ifrp + r);
		}
	}
#endif

	// Get IP address

	if(ioctl(fd, SIOCGIFADDR, &ifr) != -1) {
		sa = (struct sockaddr_in *)&(ifr.ifr_addr);
		info->ip = sa->sin_addr.s_addr;
	} else {
		info->ip = 0;
	}

	// Get netmask

	if(ioctl(fd, SIOCGIFNETMASK, &ifr) != -1) {
		sa = (struct sockaddr_in *)&(ifr.ifr_addr);
		info->nm = sa->sin_addr.s_addr;
	} else {
		info->nm = 0;
	}

	// Get default gateway if on this interface

	info->gw = 0;
#ifdef linux
	if(froute != NULL) {
		fseek(froute, 0, 0);

		while(fgets(buf, sizeof(buf), froute)) {
			r = sscanf(buf, "%s %x %x", a, &b, &c);

			if((strcmp(a, info->id) == 0) && (b == 0)) {
				info->gw = c;
			}
		}

	}
#elif defined(__OpenBSD__)
	{
	struct rt_msghdr *rtm = NULL;
	char *buf = NULL, *next, *lim = NULL;
	size_t needed;
	int mib[6];
	struct sockaddr *sa;
	struct sockaddr_in *sin;

	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;
	mib[3] = AF_INET;
	mib[4] = NET_RT_DUMP;
	mib[5] = 0;
	if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) {
		perror("route-sysctl-estimate");
		exit(1);
	}
	if (needed > 0) {
		if ((buf = malloc(needed)) == 0) {
			printf("out of space\n");
			exit(1);
		}
		if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) {
			perror("sysctl of routing table");
			exit(1);
		}
		lim  = buf + needed;
	}

	if (buf) {
		for (next = buf; next < lim; next += rtm->rtm_msglen) {
			rtm = (struct rt_msghdr *)next;
			sa = (struct sockaddr *)(rtm + 1);
			sin = (struct sockaddr_in *)sa;

			if (sin->sin_addr.s_addr == 0) {
				sa = (struct sockaddr *)(ROUNDUP(sa->sa_len) + (char *)sa);
				sin = (struct sockaddr_in *)sa;
				info->gw = sin->sin_addr.s_addr;
				break;
			}
		}
		free(buf);
	}
	}
#endif

	// Get wireless link status if wireless

	info->sl = 0;
#ifdef linux
	if(fwireless != NULL) {
		fseek(fwireless, 0, 0);

		while(fgets(buf, sizeof(buf), fwireless)) {
			r = sscanf(buf, "%s %d %d ", a, &b, &c);
			if(strchr(a, ':'))  *(strchr(a, ':')) = 0;
			if(strcmp(a, parent) == 0) {
				info->sl = c;
			}
		}
	}

#ifdef ENABLE_NWN_SUPPORT
	if (info->sl == 0) {
		info->sl = nwn_get_link(parent);
	}
#endif
#elif defined(__OpenBSD__)
	{
	struct wi_req	wreq;
	struct ifreq	ifr;

	wreq.wi_len = WI_MAX_DATALEN;
	wreq.wi_type = WI_RID_COMMS_QUALITY;

	strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
	ifr.ifr_data = (caddr_t)&wreq;

	if (ioctl(fd, SIOCGWAVELAN, &ifr) != -1)
		info->sl = letoh16(wreq.wi_val[0]);
	}
#endif

	// Get Total tx/rx bytes

#ifdef linux
	if(fdev != NULL) {
		fseek(fdev, 0, 0);

		while(fgets(buf, sizeof(buf), fdev)) {
			r = sscanf(buf, "%s %d %d %d %d %d %d %d %d %d", a, &b, &d,&d,&d,&d,&d,&d,&d, &c);
			if(strchr(a, ':'))  *(strchr(a, ':')) = 0;
			if(strcmp(a, parent) == 0) {
				info->bytes = b + c;
			}
		}
	}
#endif

	return(0);
}
Exemple #18
0
static int
verify_signature(struct key *key, FILE *fin)
{
	struct gzip_header gh;
	struct gzip_xfield *gx;
	struct gzsig_data *gd;
	u_char *sig, digest[20], buf[8192], sbuf[4096];
	SHA_CTX ctx;
	int i, siglen;

	/* Read gzip header. */
	if ((i = fread((u_char *)&gh, 1, sizeof(gh), fin)) != sizeof(gh)) {
		fprintf(stderr, "Error reading gzip header: %s\n",
		    strerror(errno));
		return (-1);
	}
	/* Verify gzip header. */
	if (memcmp(gh.magic, GZIP_MAGIC, sizeof(gh.magic)) != 0) {
		fprintf(stderr, "Invalid gzip file\n");
		return (-1);
	} else if (gh.flags & GZIP_FCONT){
		fprintf(stderr, "Multi-part gzip files not supported\n");
		return (-1);
	} else if ((gh.flags & GZIP_FEXTRA) == 0) {
		fprintf(stderr, "No gzip signature found\n");
		return (-1);
	}
	/* Read signature. */
	gx = (struct gzip_xfield *)buf;
	
	if ((i = fread((u_char *)gx, 1, sizeof(*gx), fin)) != sizeof(*gx)) {
		fprintf(stderr, "Error reading extra field: %s\n",
		    strerror(errno));
		return (-1);
	}
	if (memcmp(gx->subfield.id, GZSIG_ID, sizeof(gx->subfield.id)) != 0) {
		fprintf(stderr, "Unknown extra field\n");
		return (-1);
	}
	gx->subfield.len = letoh16(gx->subfield.len);

	if (gx->subfield.len <= 0 || gx->subfield.len > sizeof(sbuf)) {
		fprintf(stderr, "Invalid signature length\n");
		return (-1);
	}
	gd = (struct gzsig_data *)sbuf;
	
	if ((i = fread((u_char *)gd, 1, gx->subfield.len, fin)) !=
	    gx->subfield.len) {
		fprintf(stderr, "Error reading signature: %s\n",
		    strerror(errno));
		return (-1);
	}
	/* Skip over any options. */
	if (gh.flags & GZIP_FNAME) {
		if (skip_string(fin))
			return (-1);
	}
	if (gh.flags & GZIP_FCOMMENT) {
		if (skip_string(fin))
			return (-1);
	}
	if (gh.flags & GZIP_FENCRYPT &&
	    fread(buf, 1, GZIP_FENCRYPT_LEN, fin) != GZIP_FENCRYPT_LEN)
		return (-1);
	
	/* Check signature version. */
	if (gd->version != GZSIG_VERSION) {
		fprintf(stderr, "Unknown signature version: %d\n",
		    gd->version);
		return (-1);
	}
	/* Compute SHA1 checksum over compressed data and trailer. */
	sig = (u_char *)(gd + 1);
	siglen = gx->subfield.len - sizeof(*gd);

	SHA1_Init(&ctx);
	
	while ((i = fread(buf, 1, sizeof(buf), fin)) > 0) {
		SHA1_Update(&ctx, buf, i);
	}
	SHA1_Final(digest, &ctx);
	
	/* Verify signature. */
	if (key_verify(key, digest, sizeof(digest), sig, siglen) < 0) {
		fprintf(stderr, "Error verifying signature\n");
		return (-1);
	}
	return (0);
}
Exemple #19
0
static void * mozload(const char * path, void *zip,
                      struct cdir_entry *cdir_start, uint16_t cdir_entries)
{
#ifdef DEBUG
  struct timeval t0, t1;
  gettimeofday(&t0, 0);
#endif

  struct cdir_entry *entry = find_cdir_entry(cdir_start, cdir_entries, path);
  struct local_file_header *file = (struct local_file_header *)((char *)zip + letoh32(entry->offset));
  void * data = ((char *)&file->data) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
  void * handle;

  if (extractLibs) {
    char fullpath[PATH_MAX];
    snprintf(fullpath, PATH_MAX, "%s/%s", getenv("CACHE_PATH"), path);
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "resolved %s to %s", path, fullpath);
    extractFile(fullpath, entry, data);
    handle = __wrap_dlopen(fullpath, RTLD_LAZY);
    if (!handle)
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", fullpath, __wrap_dlerror());
#ifdef DEBUG
    gettimeofday(&t1, 0);
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path,
                        (((long long)t1.tv_sec * 1000000LL) +
                          (long long)t1.tv_usec) -
                        (((long long)t0.tv_sec * 1000000LL) +
                          (long long)t0.tv_usec));
#endif
    return handle;
  }

  size_t offset = letoh32(entry->offset) + sizeof(*file) + letoh16(file->filename_size) + letoh16(file->extra_field_size);
  bool skipLibCache = false;
  int fd = zip_fd;
  void * buf = NULL;
  uint32_t lib_size = letoh32(entry->uncompressed_size);
  int cache_fd = 0;
  if (letoh16(file->compression) == DEFLATE) {
    cache_fd = lookupLibCacheFd(path);
    fd = cache_fd;
    if (fd < 0)
      fd = createAshmem(lib_size, path);
#ifdef DEBUG
    else
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loading %s from cache", path);
#endif
    if (fd < 0) {
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't open " ASHMEM_NAME_DEF ", Error %d, %s, bailing out", errno, strerror(errno));
      return NULL;
    }
    buf = mmap(NULL, lib_size,
               PROT_READ | PROT_WRITE,
               MAP_SHARED, fd, 0);
    if (buf == (void *)-1) {
      __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't mmap decompression buffer");
      close(fd);
      return NULL;
    }

    offset = 0;

    if (cache_fd < 0) {
      extractLib(entry, data, buf);
#ifdef ANDROID_ARM_LINKER
      /* We just extracted data that is going to be executed in the future.
       * We thus need to ensure Instruction and Data cache coherency. */
      cacheflush((unsigned) buf, (unsigned) buf + entry->uncompressed_size, 0);
#endif
      addLibCacheFd(path, fd, lib_size, buf);
    }

    // preload libxul, to avoid slowly demand-paging it
    if (!strcmp(path, "libxul.so"))
      madvise(buf, entry->uncompressed_size, MADV_WILLNEED);
    data = buf;
  }

#ifdef DEBUG
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Loading %s with len %d (0x%08x) and offset %d (0x%08x)", path, lib_size, lib_size, offset, offset);
#endif

  handle = moz_mapped_dlopen(path, RTLD_LAZY, fd, data,
                             lib_size, offset);
  if (!handle)
    __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "Couldn't load %s because %s", path, __wrap_dlerror());

  if (buf)
    munmap(buf, lib_size);

#ifdef DEBUG
  gettimeofday(&t1, 0);
  __android_log_print(ANDROID_LOG_ERROR, "GeckoLibLoad", "%s: spent %d", path, (((long long)t1.tv_sec * 1000000LL) + (long long)t1.tv_usec) -
               (((long long)t0.tv_sec * 1000000LL) + (long long)t0.tv_usec));
#endif

  return handle;
}
Exemple #20
0
int
udf_mountfs(struct vnode *devvp, struct mount *mp, uint32_t lb, struct proc *p)
{
	struct buf *bp = NULL;
	struct anchor_vdp avdp;
	struct umount *ump = NULL;
	struct part_desc *pd;
	struct logvol_desc *lvd;
	struct fileset_desc *fsd;
	struct file_entry *root_fentry;
	uint32_t sector, size, mvds_start, mvds_end;
	uint32_t fsd_offset = 0;
	uint16_t part_num = 0, fsd_part = 0;
	int error = EINVAL;
	int logvol_found = 0, part_found = 0, fsd_found = 0;
	int bsize;

	/*
	 * Disallow multiple mounts of the same device.
	 * Disallow mounting of a device that is currently in use
	 * (except for root, which might share swap device for miniroot).
	 * Flush out any old buffers remaining from a previous use.
	 */
	if ((error = vfs_mountedon(devvp)))
		return (error);
	if (vcount(devvp) > 1 && devvp != rootvp)
		return (EBUSY);
	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
	error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0);
	VOP_UNLOCK(devvp, 0, p);
	if (error)
		return (error);

	error = VOP_OPEN(devvp, FREAD, FSCRED, p);
	if (error)
		return (error);

	MALLOC(ump, struct umount *, sizeof(struct umount), M_UDFMOUNT,
	    M_WAITOK);
	bzero(ump, sizeof(struct umount));

	mp->mnt_data = (qaddr_t) ump;
	mp->mnt_stat.f_fsid.val[0] = devvp->v_rdev;
	mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_UDF);
	mp->mnt_flag |= MNT_LOCAL;

	ump->um_mountp = mp;
	ump->um_dev = devvp->v_rdev;
	ump->um_devvp = devvp;

	bsize = 2048;	/* Should probe the media for its size. */

	/* 
	 * Get the Anchor Volume Descriptor Pointer from sector 256.
	 * Should also check sector n - 256, n, and 512.
	 */
	sector = 256;
	if ((error = bread(devvp, sector * btodb(bsize), bsize, NOCRED,
			   &bp)) != 0)
		goto bail;
	if ((error = udf_checktag((struct desc_tag *)bp->b_data, TAGID_ANCHOR)))
		goto bail;

	bcopy(bp->b_data, &avdp, sizeof(struct anchor_vdp));
	brelse(bp);
	bp = NULL;

	/*
	 * Extract the Partition Descriptor and Logical Volume Descriptor
	 * from the Volume Descriptor Sequence.
	 * Should we care about the partition type right now?
	 * What about multiple partitions?
	 */
	mvds_start = letoh32(avdp.main_vds_ex.loc);
	mvds_end = mvds_start + (letoh32(avdp.main_vds_ex.len) - 1) / bsize;
	for (sector = mvds_start; sector < mvds_end; sector++) {
		if ((error = bread(devvp, sector * btodb(bsize), bsize, 
				   NOCRED, &bp)) != 0) {
			printf("Can't read sector %d of VDS\n", sector);
			goto bail;
		}
		lvd = (struct logvol_desc *)bp->b_data;
		if (!udf_checktag(&lvd->tag, TAGID_LOGVOL)) {
			ump->um_bsize = letoh32(lvd->lb_size);
			ump->um_bmask = ump->um_bsize - 1;
			ump->um_bshift = ffs(ump->um_bsize) - 1;
			fsd_part = letoh16(lvd->_lvd_use.fsd_loc.loc.part_num);
			fsd_offset = letoh32(lvd->_lvd_use.fsd_loc.loc.lb_num);
			if (udf_find_partmaps(ump, lvd))
				break;
			logvol_found = 1;
		}
		pd = (struct part_desc *)bp->b_data;
		if (!udf_checktag(&pd->tag, TAGID_PARTITION)) {
			part_found = 1;
			part_num = letoh16(pd->part_num);
			ump->um_len = letoh32(pd->part_len);
			ump->um_start = letoh32(pd->start_loc);
		}

		brelse(bp); 
		bp = NULL;
		if ((part_found) && (logvol_found))
			break;
	}

	if (!part_found || !logvol_found) {
		error = EINVAL;
		goto bail;
	}

	if (fsd_part != part_num) {
		printf("FSD does not lie within the partition!\n");
		error = EINVAL;
		goto bail;
	}

	mtx_init(&ump->um_hashmtx, IPL_NONE);
	ump->um_hashtbl = hashinit(UDF_HASHTBLSIZE, M_UDFMOUNT, M_WAITOK,
	    &ump->um_hashsz);

	/* Get the VAT, if needed */
	if (ump->um_flags & UDF_MNT_FIND_VAT) {
		error = udf_vat_get(ump, lb);
		if (error)
			goto bail;
	}

	/*
	 * Grab the Fileset Descriptor
	 * Thanks to Chuck McCrobie <*****@*****.**> for pointing
	 * me in the right direction here.
	 */
	sector = fsd_offset;
	udf_vat_map(ump, &sector);
	if ((error = RDSECTOR(devvp, sector, ump->um_bsize, &bp)) != 0) {
		printf("Cannot read sector %d of FSD\n", sector);
		goto bail;
	}
	fsd = (struct fileset_desc *)bp->b_data;
	if (!udf_checktag(&fsd->tag, TAGID_FSD)) {
		fsd_found = 1;
		bcopy(&fsd->rootdir_icb, &ump->um_root_icb,
		    sizeof(struct long_ad));
	}

	brelse(bp);
	bp = NULL;

	if (!fsd_found) {
		printf("Couldn't find the fsd\n");
		error = EINVAL;
		goto bail;
	}

	/*
	 * Find the file entry for the root directory.
	 */
	sector = letoh32(ump->um_root_icb.loc.lb_num);
	size = letoh32(ump->um_root_icb.len);
	udf_vat_map(ump, &sector);
	if ((error = udf_readlblks(ump, sector, size, &bp)) != 0) {
		printf("Cannot read sector %d\n", sector);
		goto bail;
	}

	root_fentry = (struct file_entry *)bp->b_data;
	if ((error = udf_checktag(&root_fentry->tag, TAGID_FENTRY))) {
		printf("Invalid root file entry!\n");
		goto bail;
	}

	brelse(bp);
	bp = NULL;

	devvp->v_specmountpoint = mp;

	return (0);

bail:
	if (ump->um_hashtbl != NULL)
		free(ump->um_hashtbl, M_UDFMOUNT);

	if (ump != NULL) {
		FREE(ump, M_UDFMOUNT);
		mp->mnt_data = NULL;
		mp->mnt_flag &= ~MNT_LOCAL;
	}
	if (bp != NULL)
		brelse(bp);
	VOP_CLOSE(devvp, FREAD, FSCRED, p);

	return (error);
}
Exemple #21
0
static short readShort() {
	short ret = *(short*)(s_data + s_pos);
	ret = letoh16(ret);
	s_pos += sizeof(short);
	return ret;
}
Exemple #22
0
CEOID _CeReadRecordProps(/*{{{*/
                RapiContext *context,
		HANDLE hDbase,
		DWORD dwFlags,
		LPWORD lpcPropID,
		CEPROPID *rgPropID,
		LPBYTE *lplpBuffer,
		LPDWORD lpcbBuffer)
{

	/* need to do something with rgPropID */

	CEOID return_value = 0;
	uint16_t prop_id_count = 0;
	uint32_t recv_size = 0;
	size_t out_size = 0;
	uint32_t i;
	unsigned char* recv_buffer = NULL;
	unsigned char* out_buffer = NULL;
	size_t recv_propval_size = 0;
	size_t extra_data_size = 0;
	size_t out_propval_size = 0;

	rapi_database_trace("begin");

	if (! lpcbBuffer ) {
	  return_value = 0;
	  context->last_error = ERROR_INVALID_PARAMETER;
	  goto exit;
	}

	rapi_context_begin_command(context, 0x10);
	rapi_buffer_write_uint32(context->send_buffer, hDbase);
	rapi_buffer_write_uint32(context->send_buffer, dwFlags);
	rapi_buffer_write_uint32(context->send_buffer, 0);
	rapi_buffer_write_uint32(context->send_buffer, 0);
	rapi_buffer_write_uint32(context->send_buffer, 0);
	rapi_buffer_write_uint16(context->send_buffer, 0);

	if ( !rapi_context_call(context) )
		goto fail;

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &context->last_error) )
		goto fail;
	rapi_database_trace("context->last_error=0x%08x", context->last_error);

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &return_value) )
		goto fail;
	rapi_database_trace("return_value=0x%08x", return_value);

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &recv_size) )
		goto fail;
	rapi_database_trace("received size=%i", recv_size);

	if ( !rapi_buffer_read_uint16(context->recv_buffer, &prop_id_count) )
		goto fail;
	rapi_database_trace("prop_id_count=%i", prop_id_count);

	if (lpcPropID)
		*lpcPropID = prop_id_count;

	/* 
	 *  the data buffer we recieve consists of CEPROPVAL items, followed by
	 *  misc data eg. strings
	 *
	 *  we cannot do a direct cast to a CEPROPVAL array because we cannot guarantee
	 *  that pointer items will be the same size on both platforms
	 */

	/* size of CEPROPVAL over the wire is 16 bytes, ie pointers are 32 bit */
	recv_propval_size = 16 * prop_id_count;
	rapi_database_trace("original propval size = %u", recv_propval_size);

	extra_data_size = recv_size - recv_propval_size;
	rapi_database_trace("extra data size = %u", extra_data_size);

	out_propval_size = sizeof(CEPROPVAL) * prop_id_count;
	rapi_database_trace("new provpval size = %u", out_propval_size);

	out_size = extra_data_size + out_propval_size;
	rapi_database_trace("out buffer size = %u", out_size);

	if (lplpBuffer)
	{
		if (*lplpBuffer != NULL) {
		  if (*lpcbBuffer < out_size) {
		    if  (dwFlags & CEDB_ALLOWREALLOC)
		      *lplpBuffer = realloc(*lplpBuffer, out_size);
		    else
		      {
			context->last_error = ERROR_INSUFFICIENT_BUFFER;
			return_value = 0;
			*lpcbBuffer = out_size;
			goto exit;
		      }
		  }
		} else
		  *lplpBuffer = malloc(out_size);

		if (!(*lplpBuffer)) {
		  context->last_error = ERROR_NOT_ENOUGH_MEMORY;
		  return_value = 0;
		  *lpcbBuffer = out_size;
		  goto exit;
		}

		out_buffer = *lplpBuffer;

		recv_buffer = calloc(1, recv_size);
		if (!recv_buffer) {
		  rapi_database_error("failed to allocate 0x%08x bytes", recv_size);
		  context->last_error = ERROR_NOT_ENOUGH_MEMORY;
		  return_value = 0;
		  *lpcbBuffer = out_size;
		  goto exit;
		}

		CEPROPVAL* propval;
		unsigned char * buf_pos = recv_buffer;

		if ( !rapi_buffer_read_data(context->recv_buffer, recv_buffer, recv_size) )
		  {
		    rapi_database_error("failed to read buffer");
		    goto fail;
		  }

		memcpy(out_buffer + out_propval_size, recv_buffer + recv_propval_size, extra_data_size);

		propval = (CEPROPVAL*)out_buffer;

		rapi_database_trace("buffer = %p", recv_buffer);

		for (i = 0; i < prop_id_count; i++)
		  {

		    propval[i].propid = letoh32(*((uint32_t*)buf_pos));
		    buf_pos = buf_pos + 4;
		    propval[i].wLenData = letoh16(*((uint16_t*)buf_pos));
		    buf_pos = buf_pos + 2;
		    propval[i].wFlags = letoh16(*((uint16_t*)buf_pos));
		    buf_pos = buf_pos + 2;

		    rapi_database_trace("propval[%i].propid = %08x", i, propval[i].propid);


		    switch (propval[i].propid & 0xffff)
		      {

		      case CEVT_BLOB:

			rapi_database_trace("CEVT_BLOB");

			propval[i].val.blob.dwCount = letoh32(*((uint32_t*)buf_pos));
			buf_pos = buf_pos + 4;

			propval[i].val.blob.lpb = letoh32(*((uint32_t*)buf_pos)) - recv_propval_size + (sizeof(CEPROPVAL) * prop_id_count) + out_buffer;
			buf_pos = buf_pos + 4;

			rapi_database_trace("propval[%i].val.blob.dwCount = %08x",
					    i, propval[i].val.blob.dwCount);
			rapi_database_trace("propval[%i].val.blob.lpb = %08x",
					    i, propval[i].val.blob.lpb);

			rapi_database_trace("blob=%s",(char*)propval[i].val.blob.lpb);
			break;

		      case CEVT_LPWSTR:

			rapi_database_trace("CEVT_LPWSTR");

			propval[i].val.lpwstr = (LPWSTR)(letoh32(*((uint32_t*)buf_pos)) - recv_propval_size + (sizeof(CEPROPVAL) * prop_id_count) + out_buffer);
			buf_pos = buf_pos + 8;

			rapi_database_trace("string offset = %p", propval[i].val.lpwstr);
			rapi_database_trace_wstr(propval[i].val.lpwstr);
			rapi_database_trace("propval[i].val.lpwstr = %p", propval[i].val.lpwstr);
			break;

		      case CEVT_I2:
			rapi_database_trace("CEVT_I2");
			propval[i].val.iVal = letoh16(*((int16_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_I4:
			rapi_database_trace("CEVT_I4");
			propval[i].val.lVal = letoh32(*((int32_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_R8:

			/* TODO: convert endianness for this, need to set up 64 swap in synce.h */

			rapi_database_trace("CEVT_R8");
			memcpy(&(propval[i].val), buf_pos, 8);
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_BOOL:
			rapi_database_trace("CEVT_BOOL");
			propval[i].val.boolVal = letoh16(*((int16_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_UI2:
			rapi_database_trace("CEVT_UI2");
			propval[i].val.uiVal = letoh16(*((uint16_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_UI4:
			rapi_database_trace("CEVT_UI4");
			propval[i].val.ulVal = letoh32(*((uint32_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_FILETIME:
			rapi_database_trace("CEVT_FILETIME");
			propval[i].val.filetime.dwLowDateTime = letoh32(*((uint32_t*)buf_pos));
			buf_pos += 4;
			propval[i].val.filetime.dwHighDateTime = letoh32(*((uint32_t*)buf_pos));
			buf_pos += 4;
			break;
		      }
		  }

		free(recv_buffer);
	}

	*lpcbBuffer = out_size;

exit:
	return return_value;

fail:
 	rapi_database_error("failed");
	if (recv_buffer)
	  free(recv_buffer);
	return 0;
}/*}}}*/