Exemplo n.º 1
0
/**
 * Pre-print macro expression to be expanded.
 * @param mb		macro expansion state
 * @param s		current expansion string
 * @param se		end of string
 */
static void
printMacro(MacroBuf mb, const char * s, const char * se)
{
    const char *senl;
    const char *ellipsis;
    int choplen;

    if (s >= se) {	/* XXX just in case */
	fprintf(stderr, _("%3d>%*s(empty)"), mb->depth,
		(2 * mb->depth + 1), "");
	return;
    }

    if (s[-1] == '{')
	s--;

    /* Print only to first end-of-line (or end-of-string). */
    for (senl = se; *senl && !iseol(*senl); senl++)
	{};

    /* Limit trailing non-trace output */
    choplen = 61 - (2 * mb->depth);
    if ((senl - s) > choplen) {
	senl = s + choplen;
	ellipsis = "...";
    } else
	ellipsis = "";

    /* Substitute caret at end-of-macro position */
    fprintf(stderr, "%3d>%*s%%%.*s^", mb->depth,
	(2 * mb->depth + 1), "", (int)(se - s), s);
    if (se[1] != '\0' && (senl - (se+1)) > 0)
	fprintf(stderr, "%-.*s%s", (int)(senl - (se+1)), se+1, ellipsis);
    fprintf(stderr, "\n");
}
Exemplo n.º 2
0
/**
 * Post-print expanded macro expression.
 * @param mb		macro expansion state
 * @param t		current expansion string result
 * @param te		end of string
 */
static void
printExpansion(MacroBuf mb, const char * t, const char * te)
{
    const char *ellipsis;
    int choplen;

    if (!(te > t)) {
	rpmlog(RPMLOG_DEBUG, _("%3d<%*s(empty)\n"), mb->depth, (2 * mb->depth + 1), "");
	return;
    }

    /* Shorten output which contains newlines */
    while (te > t && iseol(te[-1]))
	te--;
    ellipsis = "";
    if (mb->depth > 0) {
	const char *tenl;

	/* Skip to last line of expansion */
	while ((tenl = strchr(t, '\n')) && tenl < te)
	    t = ++tenl;

	/* Limit expand output */
	choplen = 61 - (2 * mb->depth);
	if ((te - t) > choplen) {
	    te = t + choplen;
	    ellipsis = "...";
	}
    }

    rpmlog(RPMLOG_DEBUG,"%3d<%*s", mb->depth, (2 * mb->depth + 1), "");
    if (te > t)
	rpmlog(RPMLOG_DEBUG, "%.*s%s", (int)(te - t), t, ellipsis);
    rpmlog(RPMLOG_DEBUG, "\n");
}
Exemplo n.º 3
0
/**
 * Expand output of shell command into target buffer.
 * @param mb		macro expansion state
 * @param cmd		shell command
 * @param clen		no. bytes in shell command
 * @return		result of expansion
 */
static int
doShellEscape(MacroBuf mb, const char * cmd, size_t clen)
{
    char *buf = NULL;
    FILE *shf;
    int rc = 0;
    int c;

    rc = expandThis(mb, cmd, clen, &buf);
    if (rc)
	goto exit;

    if ((shf = popen(buf, "r")) == NULL) {
	rc = 1;
	goto exit;
    }

    size_t tpos = mb->tpos;
    while((c = fgetc(shf)) != EOF) {
	mbAppend(mb, c);
    }
    (void) pclose(shf);

    /* Delete trailing \r \n */
    while (mb->tpos > tpos && iseol(mb->buf[mb->tpos-1])) {
	mb->buf[--mb->tpos] = '\0';
	mb->nb++;
    }

exit:
    _free(buf);
    return rc;
}
Exemplo n.º 4
0
/**
 * Parse (and execute) macro undefinition.
 * @param mc		macro context
 * @param se		macro name to undefine
 * @param slen		length of se argument
 * @return		address to continue parsing
 */
static const char *
doUndefine(rpmMacroContext mc, const char * se, size_t slen)
{
    const char *s = se;
    char *buf = xmalloc(slen + 1);
    char *n = buf, *ne = n;
    int c;

    COPYNAME(ne, s, c);

    /* Move scan over body */
    while (iseol(*s))
	s++;
    se = s;

    /* Names must start with alphabetic or _ and be at least 3 chars */
    if (!((c = *n) && (risalpha(c) || c == '_') && (ne - n) > 2)) {
	rpmlog(RPMLOG_ERR,
		_("Macro %%%s has illegal name (%%undefine)\n"), n);
	goto exit;
    }

    popMacro(mc, n);

exit:
    _free(buf);
    return se;
}
Exemplo n.º 5
0
static unsigned char *
pnm_read_white(fz_context *ctx, unsigned char *p, unsigned char *e, int single_line)
{
	if (e - p < 1)
		fz_throw(ctx, FZ_ERROR_GENERIC, "cannot parse whitespace in pnm image");

	if (single_line)
	{
		if (!iswhiteeol(*p) && *p != '#')
			fz_throw(ctx, FZ_ERROR_GENERIC, "expected whitespace/comment in pnm image");
		while (p < e && iswhite(*p))
			p++;

		if (p < e && *p == '#')
			while (p < e && !iseol(*p))
				p++;
		if (p < e && iseol(*p))
			p++;
	}
	else
	{
		if (!iswhiteeol(*p) && *p != '#')
			fz_throw(ctx, FZ_ERROR_GENERIC, "expected whitespace in pnm image");
		while (p < e && iswhiteeol(*p))
			p++;

		while (p < e && *p == '#')
		{
			while (p < e && !iseol(*p))
				p++;

			if (p < e && iseol(*p))
				p++;

			while (p < e && iswhiteeol(*p))
				p++;

			if (p < e && iseol(*p))
				p++;
		}

	}

	return p;
}
Exemplo n.º 6
0
static void
skipeol(int fd)
{
    char c;

    while (read(fd, &c, 1) == 1) {
	if (iseol(c))
	    break;
    }
}
Exemplo n.º 7
0
int handle_auth_parameter(str* line, ssize_t offset)
{
  const char* ptr;

  ptr = skipspace(line->s + offset);
  /* No parameter, so just pass it through. */
  if (iseol(*ptr))
    return 0;
  if (strncasecmp(ptr, "LOGIN", 5) == 0) {
    if (ptr[5] == ' ' && !iseol(*(ptr = skipspace(ptr + 5))))
      handle_auth_login_response(line, ptr - line->s);
    else
      saw_auth_login = 1;
  }
  else if (strncasecmp(ptr, "PLAIN", 5) == 0) {
    if (ptr[5] == ' ' && !iseol(*(ptr = skipspace(ptr + 5))))
      handle_auth_plain_response(line, ptr - line->s);
    else
      saw_auth_plain = 1;
  }
  return 1;
}
Exemplo n.º 8
0
/**
 * fgets(3) analogue that reads \ continuations. Last newline always trimmed.
 * @param buf		input buffer
 * @param size		inbut buffer size (bytes)
 * @param f		file handle
 * @return		buffer, or NULL on end-of-file
 */
static char *
rdcl(char * buf, size_t size, FILE *f)
{
    char *q = buf - 1;		/* initialize just before buffer. */
    size_t nb = 0;
    size_t nread = 0;
    int pc = 0, bc = 0;
    char *p = buf;

    if (f != NULL)
    do {
	*(++q) = '\0';			/* terminate and move forward. */
	if (fgets(q, size, f) == NULL)	/* read next line. */
	    break;
	nb = strlen(q);
	nread += nb;			/* trim trailing \r and \n */
	for (q += nb - 1; nb > 0 && iseol(*q); q--)
	    nb--;
	for (; p <= q; p++) {
	    switch (*p) {
		case '\\':
		    switch (*(p+1)) {
			case '\0': break;
			default: p++; break;
		    }
		    break;
		case '%':
		    switch (*(p+1)) {
			case '{': p++, bc++; break;
			case '(': p++, pc++; break;
			case '%': p++; break;
		    }
		    break;
		case '{': if (bc > 0) bc++; break;
		case '}': if (bc > 0) bc--; break;
		case '(': if (pc > 0) pc++; break;
		case ')': if (pc > 0) pc--; break;
	    }
	}
	if (nb == 0 || (*q != '\\' && !bc && !pc) || *(q+1) == '\0') {
	    *(++q) = '\0';		/* trim trailing \r, \n */
	    break;
	}
	q++; p++; nb++;			/* copy newline too */
	size -= nb;
	if (*q == '\r')			/* XXX avoid \r madness */
	    *q = '\n';
    } while (size > 0);
    return (nread > 0 ? buf : NULL);
}
Exemplo n.º 9
0
Arquivo: macro.c Projeto: xrg/RPM
/**
 * Expand output of shell command into target buffer.
 * @param mb		macro expansion state
 * @param cmd		shell command
 * @param clen		no. bytes in shell command
 * @return		result of expansion
 */
static int
doShellEscape(MacroBuf mb, const char * cmd, size_t clen)
{
    size_t blen = MACROBUFSIZ + clen;
    char *buf = xmalloc(blen);
    FILE *shf;
    int rc = 0;
    int c;

    strncpy(buf, cmd, clen);
    buf[clen] = '\0';
    rc = expandU(mb, buf, blen);
    if (rc)
	goto exit;

    if ((shf = popen(buf, "r")) == NULL) {
	rc = 1;
	goto exit;
    }
    while((c = fgetc(shf)) != EOF) {
	if (mb->nb > 1) {
	    SAVECHAR(mb, c);
	} 
    }
    (void) pclose(shf);

    /* XXX delete trailing \r \n */
    while (iseol(mb->t[-1])) {
	*(mb->t--) = '\0';
	mb->nb++;
    }

exit:
    _free(buf);
    return rc;
}
Exemplo n.º 10
0
/*
 * Mangle the "Transport:" header:
 *   - Replace all occurences of "client_port=<spec>"
 *   - Handle destination parameter
 *
 * In:
 *   ct, ctinfo = conntrack context
 *   skb        = packet
 *   tranoff    = Transport header offset from TCP data
 *   tranlen    = Transport header length (incl. CRLF)
 *   rport_lo   = replacement low  port (host endian)
 *   rport_hi   = replacement high port (host endian)
 *
 * Returns packet size difference.
 *
 * Assumes that a complete transport header is present, ending with CR or LF
 */
static int
rtsp_mangle_tran(enum ip_conntrack_info ctinfo,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
		 unsigned int protoff,
#endif
		 struct nf_conntrack_expect* rtp_exp,
		 struct nf_conntrack_expect* rtcp_exp,
		 struct ip_ct_rtsp_expect* prtspexp,
		 struct sk_buff* skb, uint tranoff, uint tranlen)
{
	char*  ptcp;
	uint   tcplen;
	char*  ptran;
	char   rbuf1[16];	  /* Replacement buffer (one port) */
	uint   rbuf1len;	  /* Replacement len (one port) */
	char   rbufa[16];	  /* Replacement buffer (all ports) */
	uint   rbufalen;	  /* Replacement len (all ports) */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	union nf_inet_addr newip;
#else
	u_int32_t  newip;
#endif
	u_int16_t loport, hiport;
	uint      off = 0;
	uint      diff;		   /* Number of bytes we removed */

	struct nf_conn *ct = rtp_exp->master;
	/* struct nf_conn *ct = nf_ct_get(skb, &ctinfo); */
	struct nf_conntrack_tuple *rtp_t;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	char szextaddr[INET6_ADDRSTRLEN];
#else
	char szextaddr[INET_ADDRSTRLEN];
#endif
	uint extaddrlen;
	int  is_stun;

	get_skb_tcpdata(skb, &ptcp, &tcplen);
	ptran = ptcp+tranoff;

	if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen ||
	    tranlen < 10 || !iseol(ptran[tranlen-1]) ||
	    nf_strncasecmp(ptran, "Transport:", 10) != 0) {
		pr_info("sanity check failed\n");
		return 0;
	}
	off += 10;
	SKIP_WSPACE(ptcp+tranoff, tranlen, off);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3;
	rtp_t = &rtp_exp->tuple;
	rtp_t->dst.u3 = newip;
	if (rtcp_exp) {
		rtcp_exp->tuple.dst.u3 = newip;
	}
	extaddrlen = rtsp_sprintf_addr(ct, szextaddr, &newip, true); // FIXME handle extip
	pr_debug("stunaddr=%s (auto)\n", szextaddr);
#else
	newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
	rtp_t = &rtp_exp->tuple;
	rtp_t->dst.u3.ip = newip;
	if (rtcp_exp) {
		rtcp_exp->tuple.dst.u3.ip = newip;
	}
	extaddrlen = extip ? sprintf(szextaddr, "%pI4", &extip)
			   : sprintf(szextaddr, "%pI4", &newip);
	pr_debug("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto"));
#endif
	hiport = 0;
	rbuf1len = rbufalen = 0;
	switch (prtspexp->pbtype) {
	case pb_single:
		for (loport = prtspexp->loport; loport != 0; loport++) { /* XXX: improper wrap? */
			rtp_t->dst.u.udp.port = htons(loport);
			if (nf_ct_expect_related(rtp_exp) == 0) {
				pr_debug("using port %hu\n", loport);
				break;
			}
		}
		if (loport != 0) {
			rbuf1len = sprintf(rbuf1, "%hu", loport);
			rbufalen = sprintf(rbufa, "%hu", loport);
		}
		break;
	case pb_range:
		for (loport = prtspexp->loport; loport != 0; loport += 2) { /* XXX: improper wrap? */
			rtp_t->dst.u.udp.port = htons(loport);
			if (nf_ct_expect_related(rtp_exp) != 0) {
				continue;
			}
			hiport = loport + 1;
			rtcp_exp->tuple.dst.u.udp.port = htons(hiport);
			if (nf_ct_expect_related(rtcp_exp) != 0) {
				nf_ct_unexpect_related(rtp_exp);
				continue;
			}

			/* FIXME: invalid print in case of ipv6 */
			pr_debug("nat expect_related %pI4:%u-%u-%pI4:%u-%u\n",
				 &rtp_exp->tuple.src.u3.ip,
				 ntohs(rtp_exp->tuple.src.u.udp.port),
				 ntohs(rtcp_exp->tuple.src.u.udp.port),
				 &rtp_exp->tuple.dst.u3.ip,
				 ntohs(rtp_exp->tuple.dst.u.udp.port),
				 ntohs(rtcp_exp->tuple.dst.u.udp.port));
			break;
		}
		if (loport != 0) {
			rbuf1len = sprintf(rbuf1, "%hu", loport);
			rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport);
		}
		break;
	case pb_discon:
		for (loport = prtspexp->loport; loport != 0; loport++) { /* XXX: improper wrap? */
			rtp_t->dst.u.udp.port = htons(loport);
			if (nf_ct_expect_related(rtp_exp) == 0) {
				pr_debug("using port %hu (1 of 2)\n", loport);
				break;
			}
		}
		for (hiport = prtspexp->hiport; hiport != 0; hiport++) { /* XXX: improper wrap? */
			rtp_t->dst.u.udp.port = htons(hiport);
			if (nf_ct_expect_related(rtp_exp) == 0) {
				pr_debug("using port %hu (2 of 2)\n", hiport);
				break;
			}
		}
		if (loport != 0 && hiport != 0) {
			rbuf1len = sprintf(rbuf1, "%hu", loport);
			rbufalen = sprintf(rbufa, hiport == loport+1 ?
					   "%hu-%hu":"%hu/%hu", loport, hiport);
		}
		break;
	}

	if (rbuf1len == 0)
		return 0;   /* cannot get replacement port(s) */

	/* Transport: tran;field;field=val,tran;field;field=val,...
	   `off` is set to the start of Transport value from start of line
	*/
	while (off < tranlen) {
		uint        saveoff;
		const char* pparamend;
		uint        nextparamoff;

		pparamend = memchr(ptran+off, ',', tranlen-off);
		pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
		nextparamoff = pparamend-ptran;

		/*
		 * We pass over each param twice.  On the first pass, we look for a
		 * destination= field.  It is handled by the security policy.  If it
		 * is present, allowed, and equal to our external address, we assume
		 * that STUN is being used and we leave the client_port= field alone.
		 */
		is_stun = 0;
		saveoff = off;
		while (off < nextparamoff) {
			const char* pfieldend;
			uint        nextfieldoff;

			pfieldend = memchr(ptran+off, ';', nextparamoff-off);
			nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;

			if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0) {
				if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0)
					is_stun = 1;

				if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun)) {
					uint dstoff = (ptran-ptcp)+off;
					uint dstlen = nextfieldoff-off;
					char* pdstrep = NULL;
					uint dstreplen = 0;
					diff = dstlen;
					if (dstact == DSTACT_AUTO && !is_stun) {
						pr_debug("RTSP: replace dst addr\n");
						dstoff += 12;
						dstlen -= 13;
						pdstrep = szextaddr;
						dstreplen = extaddrlen;
						diff = nextfieldoff-off-13-extaddrlen;
					}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
					if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff,
								      dstoff, dstlen, pdstrep, dstreplen)) {
#else
					if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
								      dstoff, dstlen, pdstrep, dstreplen)) {
#endif
						/* mangle failed, all we can do is bail */
						nf_ct_unexpect_related(rtp_exp);
						if (rtcp_exp)
							nf_ct_unexpect_related(rtcp_exp);
						return 0;
					}
					get_skb_tcpdata(skb, &ptcp, &tcplen);
					ptran = ptcp+tranoff;
					tranlen -= diff;
					nextparamoff -= diff;
					nextfieldoff -= diff;
				}
			}

			off = nextfieldoff;
		}

		if (is_stun)
			continue;

		off = saveoff;
		while (off < nextparamoff) {
			const char* pfieldend;
			uint        nextfieldoff;

			pfieldend = memchr(ptran+off, ';', nextparamoff-off);
			nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;

			if (strncmp(ptran+off, "client_port=", 12) == 0) {
				u_int16_t port;
				uint	  numlen;
				uint      origoff;
				uint      origlen;
				char*     rbuf = rbuf1;
				uint      rbuflen = rbuf1len;

				off += 12;
				origoff = (ptran-ptcp)+off;
				origlen = 0;
				numlen = nf_strtou16(ptran+off, &port);
				off += numlen;
				origlen += numlen;
				if (port != prtspexp->loport) {
					pr_debug("multiple ports found, port %hu ignored\n", port);
				} else {
					if (ptran[off] == '-' || ptran[off] == '/') {
						off++;
						origlen++;
						numlen = nf_strtou16(ptran+off, &port);
						off += numlen;
						origlen += numlen;
						rbuf = rbufa;
						rbuflen = rbufalen;
					}

					/*
					 * note we cannot just memcpy() if the sizes are the same.
					 * the mangle function does skb resizing, checks for a
					 * cloned skb, and updates the checksums.
					 *
					 * parameter 4 below is offset from start of tcp data.
					 */
					diff = origlen-rbuflen;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
					if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, protoff,
								      origoff, origlen, rbuf, rbuflen)) {
#else
					if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
								      origoff, origlen, rbuf, rbuflen)) {
#endif
						/* mangle failed, all we can do is bail */
						nf_ct_unexpect_related(rtp_exp);
						if (rtcp_exp)
							nf_ct_unexpect_related(rtcp_exp);
						return 0;
					}
					get_skb_tcpdata(skb, &ptcp, &tcplen);
					ptran = ptcp+tranoff;
					tranlen -= diff;
					nextparamoff -= diff;
					nextfieldoff -= diff;
				}
			}

			off = nextfieldoff;
		}

		off = nextparamoff;
	}

	return 1;
}

static uint
help_out(struct sk_buff *skb, enum ip_conntrack_info ctinfo,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	 unsigned int protoff,
#endif
	 unsigned int matchoff, unsigned int matchlen,
	 struct ip_ct_rtsp_expect* prtspexp,
	 struct nf_conntrack_expect* rtp_exp,
	 struct nf_conntrack_expect* rtcp_exp)
{
	char* ptcp;
	uint  tcplen;
	uint  hdrsoff;
	uint  hdrslen;
	uint  lineoff;
	uint  linelen;
	uint  off;
	int   dir = CTINFO2DIR(ctinfo);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	union nf_inet_addr saddr = rtp_exp->master->tuplehash[dir].tuple.src.u3;
#else
	__be32 saddr = rtp_exp->master->tuplehash[dir].tuple.src.u3.ip;
#endif

	//struct iphdr* iph = (struct iphdr*)(*pskb)->nh.iph;
	//struct tcphdr* tcph = (struct tcphdr*)((void*)iph + iph->ihl*4);

	get_skb_tcpdata(skb, &ptcp, &tcplen);
	hdrsoff = matchoff;//exp->seq - ntohl(tcph->seq);
	hdrslen = matchlen;
	off = hdrsoff;
	pr_debug("NAT rtsp help_out\n");

	while (nf_mime_nextline(ptcp, hdrsoff+hdrslen, &off, &lineoff, &linelen)) {
		if (linelen == 0)
			break;

		if (off > hdrsoff+hdrslen) {
			pr_info("!! overrun !!");
			break;
		}
		pr_debug("hdr: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff);

		if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0) {
			uint oldtcplen = tcplen;
			pr_debug("hdr: Transport\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
			if (!rtsp_mangle_tran(ctinfo, protoff, rtp_exp, rtcp_exp,
					      prtspexp, skb, lineoff, linelen)) {
#else
			if (!rtsp_mangle_tran(ctinfo, rtp_exp, rtcp_exp, prtspexp,
					      skb, lineoff, linelen)) {
#endif
				pr_debug("hdr: Transport mangle failed");
				break;
			}
			rtp_exp->expectfn = nf_nat_rtsp_expected;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
			rtp_exp->saved_addr = saddr;
#else
			rtp_exp->saved_ip = saddr;
#endif
			rtp_exp->saved_proto.udp.port = htons(prtspexp->loport);
			rtp_exp->dir = !dir;
			if (rtcp_exp) {
				rtcp_exp->expectfn = nf_nat_rtsp_expected;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
				rtcp_exp->saved_addr = saddr;
#else
				rtcp_exp->saved_ip = saddr;
#endif
				rtcp_exp->saved_proto.udp.port = htons(prtspexp->hiport);
				rtcp_exp->dir = !dir;
			}
			get_skb_tcpdata(skb, &ptcp, &tcplen);
			hdrslen -= (oldtcplen-tcplen);
			off -= (oldtcplen-tcplen);
			lineoff -= (oldtcplen-tcplen);
			linelen -= (oldtcplen-tcplen);
			pr_debug("rep: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff);
		}
	}

	return NF_ACCEPT;
}

static unsigned int
nf_nat_rtsp(struct sk_buff *skb, enum ip_conntrack_info ctinfo,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	    unsigned int protoff,
#endif
	    unsigned int matchoff, unsigned int matchlen,
	    struct ip_ct_rtsp_expect* prtspexp,
	    struct nf_conntrack_expect* rtp_exp,
	    struct nf_conntrack_expect* rtcp_exp)
{
	int dir = CTINFO2DIR(ctinfo);
	int rc = NF_ACCEPT;

	switch (dir) {
	case IP_CT_DIR_ORIGINAL:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
		rc = help_out(skb, ctinfo, protoff, matchoff, matchlen, prtspexp,
			      rtp_exp, rtcp_exp);
#else
		rc = help_out(skb, ctinfo, matchoff, matchlen, prtspexp,
			      rtp_exp, rtcp_exp);
#endif
		break;
	case IP_CT_DIR_REPLY:
		pr_debug("unmangle ! %u\n", ctinfo);
		/* XXX: unmangle */
		rc = NF_ACCEPT;
		break;
	}
	//UNLOCK_BH(&ip_rtsp_lock);

	return rc;
}

static void nf_nat_rtsp_expected(struct nf_conn* ct, struct nf_conntrack_expect *exp)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	struct nf_nat_range range;
#else
	struct nf_nat_ipv4_range range;
#endif

	/* This must be a fresh one. */
	BUG_ON(ct->status & IPS_NAT_DONE_MASK);

	/* For DST manip, map port here to where it's expected. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	range.min_proto = range.max_proto = exp->saved_proto;
	range.min_addr = range.max_addr = exp->saved_addr;
#else
	range.min = range.max = exp->saved_proto;
	range.min_ip = range.max_ip = exp->saved_ip;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
	range.flags = (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED);
	nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
#else
	range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
	nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
#endif

	/* Change src to where master sends to, but only if the connection
	 * actually came from the same source. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
	if (nf_inet_addr_cmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
			     &ct->master->tuplehash[exp->dir].tuple.src.u3)) {
		range.min_addr = range.max_addr
			= ct->master->tuplehash[!exp->dir].tuple.dst.u3;
#else
	if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip ==
	    ct->master->tuplehash[exp->dir].tuple.src.u3.ip) {
		range.min_ip = range.max_ip
			= ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
		range.flags = NF_NAT_RANGE_MAP_IPS;
		nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
#else
		range.flags = IP_NAT_RANGE_MAP_IPS;
		nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
#endif
	}
}


static void __exit fini(void)
{
	rcu_assign_pointer(nf_nat_rtsp_hook, NULL);
	synchronize_net();
}

static int __init init(void)
{
	printk("nf_nat_rtsp v" IP_NF_RTSP_VERSION " loading\n");

	BUG_ON(nf_nat_rtsp_hook);
	rcu_assign_pointer(nf_nat_rtsp_hook, nf_nat_rtsp);

	if (stunaddr != NULL)
		extip = in_aton(stunaddr);

	if (destaction != NULL) {
		if (strcmp(destaction, "auto") == 0)
			dstact = DSTACT_AUTO;

		if (strcmp(destaction, "strip") == 0)
			dstact = DSTACT_STRIP;

		if (strcmp(destaction, "none") == 0)
			dstact = DSTACT_NONE;
	}

	return 0;
}
Exemplo n.º 11
0
/**
 * Parse (and execute) new macro definition.
 * @param mb		macro expansion state
 * @param se		macro definition to parse
 * @param slen		length of se argument
 * @param level		macro recursion level
 * @param expandbody	should body be expanded?
 * @return		address to continue parsing
 */
static const char *
doDefine(MacroBuf mb, const char * se, size_t slen, int level, int expandbody)
{
    const char *s = se;
    char *buf = xmalloc(slen + 3); /* Some leeway for termination issues... */
    char *n = buf, *ne = n;
    char *o = NULL, *oe;
    char *b, *be, *ebody = NULL;
    int c;
    int oc = ')';
    const char *sbody; /* as-is body start */

    /* Copy name */
    COPYNAME(ne, s, c);

    /* Copy opts (if present) */
    oe = ne + 1;
    if (*s == '(') {
	s++;	/* skip ( */
	/* Options must be terminated with ')' */
	if (strchr(s, ')')) {
	    o = oe;
	    COPYOPTS(oe, s, oc);
	    s++;	/* skip ) */
	} else {
	    rpmlog(RPMLOG_ERR, _("Macro %%%s has unterminated opts\n"), n);
	    goto exit;
	}
    }

    /* Copy body, skipping over escaped newlines */
    b = be = oe + 1;
    sbody = s;
    SKIPBLANK(s, c);
    if (c == '{') {	/* XXX permit silent {...} grouping */
	if ((se = matchchar(s, c, '}')) == NULL) {
	    rpmlog(RPMLOG_ERR,
		_("Macro %%%s has unterminated body\n"), n);
	    se = s;	/* XXX W2DO? */
	    goto exit;
	}
	s++;	/* XXX skip { */
	strncpy(b, s, (se - s));
	b[se - s] = '\0';
	be += strlen(b);
	se++;	/* XXX skip } */
	s = se;	/* move scan forward */
    } else {	/* otherwise free-field */
	int bc = 0, pc = 0;
	while (*s && (bc || pc || !iseol(*s))) {
	    switch (*s) {
		case '\\':
		    switch (*(s+1)) {
			case '\0': break;
			default: s++; break;
		    }
		    break;
		case '%':
		    switch (*(s+1)) {
			case '{': *be++ = *s++; bc++; break;
			case '(': *be++ = *s++; pc++; break;
			case '%': *be++ = *s++; break;
		    }
		    break;
		case '{': if (bc > 0) bc++; break;
		case '}': if (bc > 0) bc--; break;
		case '(': if (pc > 0) pc++; break;
		case ')': if (pc > 0) pc--; break;
	    }
	    *be++ = *s++;
	}
	*be = '\0';

	if (bc || pc) {
	    rpmlog(RPMLOG_ERR,
		_("Macro %%%s has unterminated body\n"), n);
	    se = s;	/* XXX W2DO? */
	    goto exit;
	}

	/* Trim trailing blanks/newlines */
	while (--be >= b && (c = *be) && (isblank(c) || iseol(c)))
	    {};
	*(++be) = '\0';	/* one too far */
    }

    /* Move scan over body */
    while (iseol(*s))
	s++;
    se = s;

    /* Names must start with alphabetic or _ and be at least 3 chars */
    if (!((c = *n) && (risalpha(c) || c == '_') && (ne - n) > 2)) {
	rpmlog(RPMLOG_ERR,
		_("Macro %%%s has illegal name (%%define)\n"), n);
	goto exit;
    }

    if ((be - b) < 1) {
	rpmlog(RPMLOG_ERR, _("Macro %%%s has empty body\n"), n);
	goto exit;
    }

    if (!isblank(*sbody) && !(*sbody == '\\' && iseol(sbody[1])))
	rpmlog(RPMLOG_WARNING, _("Macro %%%s needs whitespace before body\n"), n);

    if (expandbody) {
	if (expandThis(mb, b, 0, &ebody)) {
	    rpmlog(RPMLOG_ERR, _("Macro %%%s failed to expand\n"), n);
	    goto exit;
	}
	b = ebody;
    }

    pushMacro(mb->mc, n, o, b, (level - 1), ME_NONE);

exit:
    _free(buf);
    _free(ebody);
    return se;
}
Exemplo n.º 12
0
BOOL FormatFile (LPTSTR pszName, LPTSTR pszText)
{
   // Find the appropriate output filename
   //
   TCHAR szName[ MAX_PATH ];
   lstrcpy (szName, pszName);

   LPTSTR pchSlash = NULL;
   for (LPTSTR pch = szName; *pch; ++pch)
      {
      if (*pch == TEXT('\\'))
         pchSlash = NULL;
      else if (*pch == TEXT('.'))
         pchSlash = pch;
      }
   if (pchSlash)
      lstrcpy (pchSlash, TEXT(".rtf"));
   else // (!pchSlash)
      lstrcat (szName, TEXT(".rtf"));

   // Open an output file handle
   //
   HANDLE hFile;
   if ((hFile = CreateFile (szName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
      {
      printf ("failed to create %s; error %lu\n", szName, GetLastError());
      return FALSE;
      }

   // Write the RTF prolog
   //
   char *pszPROLOG = "{\\rtf1\\ansi\\deff0\\deftab720\\ansicpg%lu\n"
                     "{\\colortbl\\red0\\green0\\blue0;}\\pard";

   char szProlog[ 1024 ];
   wsprintf (szProlog, pszPROLOG, g::CodePage);

   DWORD dwWrote;
   WriteFile (hFile, szProlog, lstrlen(szProlog), &dwWrote, NULL);

   // Translate the file itself
   //
   BOOL fAllowCRLF = FALSE;
   BOOL fInFormatted = FALSE;
   size_t cFormatted = FALSE;
   LPTSTR pchNext = NULL;
   for (LPTSTR pchRead = pszText; pchRead && *pchRead; pchRead = pchNext)
      {
      while (iswhiteeol(*pchRead))
         ++pchRead;
      if (!*pchRead)
         break;

      if (*pchRead == '<')
         {
         pchNext = &pchRead[1];
         while (*pchNext && (*pchNext != '>'))
            ++pchNext;
         if (*pchNext == '>')
            ++pchNext;

         // If this was a "<p>", write an EOL.
         // If this was a "<d>", write paragraph-header formatting info.
         // If this was a "<?>", write an EOL.
         //
         if (tolower(pchRead[1]) == '?')
            {
            if (fAllowCRLF)
               WriteFile (hFile, "\r\n\\par ", lstrlen("\r\n\\par "), &dwWrote, NULL);
            }
         else if (tolower(pchRead[1]) == 'p')
            {
            if (fAllowCRLF)
               WriteFile (hFile, "\r\n\\par \r\n\\par ", lstrlen("\r\n\\par \r\n\\par "), &dwWrote, NULL);
            if (fInFormatted)
               {
               char *pszPLAIN = "\\plain\\fs20 ";
               WriteFile (hFile, pszPLAIN, lstrlen(pszPLAIN), &dwWrote, NULL);
               }
            fInFormatted = FALSE;
            }
         else if (tolower(pchRead[1]) == 'd')
            {
            if (fAllowCRLF)
               WriteFile (hFile, "\r\n\\par \r\n\\par ", lstrlen("\r\n\\par \r\n\\par "), &dwWrote, NULL);

            char *pszWrite;
            if ((++cFormatted) <= 2)
               pszWrite = "\\plain\\fs28\\b ";
            else // (cFormatted > 2)
               pszWrite = "\\plain\\fs24\\b ";

            WriteFile (hFile, pszWrite, lstrlen(pszWrite), &dwWrote, NULL);

            fInFormatted = TRUE;
            }
         }
      else // (*pchRead != '<')
         {
         pchNext = &pchRead[1];
         while (*pchNext && (*pchNext != '<') && !iseol(*pchNext))
            ++pchNext;

         LPTSTR pszEscaped;
         if ((pszEscaped = EscapeSpecialCharacters (pchRead, pchNext - pchRead)) == NULL)
            break;

         WriteFile (hFile, pszEscaped, lstrlen(pszEscaped), &dwWrote, NULL);
         fAllowCRLF = TRUE;
         }
      }

   // Write the RTF trailer
   //
   char *pszTRAILER = "\\par }";

   WriteFile (hFile, pszTRAILER, lstrlen(pszTRAILER), &dwWrote, NULL);

   SetEndOfFile (hFile);
   CloseHandle (hFile);
   return TRUE;
}
Exemplo n.º 13
0
static pgeObjMtl *pgeObjLoadMaterial(const char *matname)
{
	int fd = sceIoOpen(matname, PSP_O_RDONLY, 0777);
	
	if(fd < 0)
		return NULL;

	long filesize;
	
	filesize = sceIoLseek32(fd, 0, PSP_SEEK_END);
	sceIoLseek32(fd, 0, PSP_SEEK_SET);
	
	unsigned char *data = pgeMalloc(filesize);
	
	if(!data)
		return NULL;
	
	sceIoRead(fd, data, filesize);
	
	sceIoClose(fd);
	
	unsigned char *currentpos, *endpos;
	unsigned int position = 0;
	unsigned int numnewmtl = 0;
	unsigned int newmtlpos = 0, kapos = 0, kdpos = 0, kspos = 0, nspos = 0; 
	char readbuffer[512];
	
	currentpos = data;
	endpos = currentpos + filesize;
		
	while(currentpos != endpos)
	{
		position = 0;
		
		while((isdeadspace(*currentpos)) && (currentpos != endpos))
			currentpos++;
			
		while((!iseol(*currentpos)) && (currentpos != endpos) && (position < 512))
		{
			readbuffer[position++] = *currentpos;
			currentpos++;
		}
		
		readbuffer[position] = 0;
		
		if(strequal(readbuffer, "newmtl", &readbuffer[position], 6))
			numnewmtl++;
	}
	
	// Allocate what we need
	
	pgeObjMtl *mtl = pgeMalloc(sizeof(pgeObjMtl));
	
	if(!mtl)
	{
		pgeFree(data);
		return NULL;
	}
	
	mtl->materials = (pgeObjMtlEntry *)pgeMalloc(sizeof(pgeObjMtlEntry) * numnewmtl);
	
	if(!mtl->materials)
	{
		pgeFree(mtl);
		pgeFree(data);
		return NULL;
	}
	
	mtl->nummaterials = numnewmtl;
	
	// Read back through and populate
	
	currentpos = data;
	
	char namebuffer[128];
	
	while(currentpos != endpos)
	{
		position = 0;
		
		while((isdeadspace(*currentpos)) && (currentpos != endpos))
			currentpos++;
			
		while((!iseol(*currentpos)) && (currentpos != endpos) && (position < 512))
		{
			readbuffer[position++] = *currentpos;
			currentpos++;
		}
		
		readbuffer[position] = 0;
		
		if(strequal(readbuffer, "newmtl", &readbuffer[position], 6))
		{
			sscanf(readbuffer, "newmtl %s", namebuffer);
			mtl->materials[newmtlpos].name = pgeMalloc(strlen(namebuffer) + 1);
			
			if(!mtl->materials[newmtlpos].name)
			{
				pgeFree(mtl->materials);
				pgeFree(mtl);
				pgeFree(data);
				return NULL;
			}
			
			strcpy(mtl->materials[newmtlpos].name, namebuffer);
			
			newmtlpos++;
		}
		else if(strequal(readbuffer, "Ka", &readbuffer[position], 2))
		{
			sscanf(readbuffer, "Ka %f %f %f", &mtl->materials[kapos].ambient[0], &mtl->materials[kapos].ambient[1], &mtl->materials[kapos].ambient[2]);
			kapos++;
		}
		else if(strequal(readbuffer, "Kd", &readbuffer[position], 2))
		{
			sscanf(readbuffer, "Kd %f %f %f", &mtl->materials[kdpos].diffuse[0], &mtl->materials[kdpos].diffuse[1], &mtl->materials[kdpos].diffuse[2]);
			kdpos++;
		}
		else if(strequal(readbuffer, "Ks", &readbuffer[position], 2))
		{
			sscanf(readbuffer, "Ks %f %f %f", &mtl->materials[kspos].specular[0], &mtl->materials[kspos].specular[1], &mtl->materials[kspos].specular[2]);
			kspos++;
		}
		else if(strequal(readbuffer, "Ns", &readbuffer[position], 2))
		{
			sscanf(readbuffer, "Ns %f", &mtl->materials[nspos].shinyness);
			nspos++;
		}
	}
		
	return mtl;
}
Exemplo n.º 14
0
static pgeObj *pgeObjLoadInternal(unsigned char *buffer, unsigned int size)
{
	typedef struct objVertex
	{
		float x, y, z;
		
	} objVertex;
	
	typedef objVertex objNormal;
	
	typedef struct objTexCoord
	{
		float u, v;
		
	} objTexCoord;
	
	typedef struct objTriangle
	{
		unsigned int vertex[3];
		unsigned int normal[3];
		unsigned int texcoord[3];
		unsigned int color;
		
	} objTriangle;
	
	typedef struct objModel
	{
		unsigned int numVertex, numNormal, numTexCoord, numTriangle, numMaterial;
		objVertex *vertexArray;
		objNormal *normalArray;
		objTexCoord *texCoordArray;
		objTriangle *triangleArray;
	 
	 } objModel;
	 
	 objModel *model = pgeMalloc(sizeof(objModel));
	 
	 pgeObjMtl *mtl = NULL;
	 
	 unsigned char *currentpos, *endpos;
	 unsigned int position = 0;
	 int vertpos = 0, normalpos = 0, texvertpos = 0, facepos = 0;
	 char readbuffer[512];
	 char materialname[128];
	 
	 currentpos = buffer;
	 endpos = buffer + size;
	
	// Seek through file, counting number of entries we are interesting in
	
	while(currentpos != endpos)
	{
		position = 0;
		
		while((isdeadspace(*currentpos)) && (currentpos != endpos))
			currentpos++;
			
		while((!iseol(*currentpos)) && (currentpos != endpos) && (position < 512))
		{
			readbuffer[position++] = *currentpos;
			currentpos++;
		}
		
		readbuffer[position] = 0;
		
		if(strequal(readbuffer, "vn", &readbuffer[position], 2))
			model->numNormal++;
		else if(strequal(readbuffer, "vt", &readbuffer[position], 2))
			model->numTexCoord++;
		else if(strequal(readbuffer, "v", &readbuffer[position], 1))
			model->numVertex++;
		else if(strequal(readbuffer, "f", &readbuffer[position], 1))
			model->numTriangle++;
		else if(strequal(readbuffer, "mtllib", &readbuffer[position], 6))
			model->numMaterial++;
	}
			
	// Allocate what we need
	if(model->numVertex > 0)
	{
		model->vertexArray = pgeMalloc(model->numVertex * sizeof(objVertex));
		
		if(!model->vertexArray)
		{
			pgeFree(model);
			return NULL;
		}
	}
	
	if(model->numNormal > 0)
	{
		model->normalArray = pgeMalloc(model->numNormal * sizeof(objNormal));
		
		if(!model->normalArray)
		{
			pgeFree(model->vertexArray);
			pgeFree(model);
			return NULL;
		}
	}
	
	if(model->numTexCoord > 0)
	{
		model->texCoordArray = pgeMalloc(model->numTexCoord * sizeof(objTexCoord));
		
		if(!model->texCoordArray)
		{
			pgeFree(model->vertexArray);
			pgeFree(model->normalArray);
			pgeFree(model);
			return NULL;
		}
	}
	
	if(model->numTriangle > 0)
	{
		model->triangleArray = pgeMalloc(model->numTriangle * sizeof(objTriangle));
		
		if(!model->triangleArray)
		{
			pgeFree(model->vertexArray);
			pgeFree(model->normalArray);
			pgeFree(model->texCoordArray);
			pgeFree(model);
			return NULL;
		}
	}
	
	// Read from the start of the file again and fill our arrays
	
	currentpos = buffer;
	
	unsigned int currentcolor = 0xFFFFFFFF;
	
	float tempnv = 0.0f;
	
	while(currentpos != endpos)
	{
		position = 0;
		
		while((isdeadspace(*currentpos)) && (currentpos != endpos))
			currentpos++;
			
		while((!iseol(*currentpos)) && (currentpos != endpos) && (position < 512))
		{
			readbuffer[position++] = *currentpos;
			currentpos++;
		}
		
		readbuffer[position] = 0;
		
		if(strequal(readbuffer, "vn", &readbuffer[position], 2))
		{
			sscanf(readbuffer, "vn %f %f %f", &model->normalArray[normalpos].x, &model->normalArray[normalpos].y, &model->normalArray[normalpos].z);
			normalpos++;
		}
		else if(strequal(readbuffer, "vt", &readbuffer[position], 2))
		{
			sscanf(readbuffer, "vt %f %f", &model->texCoordArray[texvertpos].u, &model->texCoordArray[texvertpos].v);
			texvertpos++;
		}
		else if(strequal(readbuffer, "v", &readbuffer[position], 1))
		{
			sscanf(readbuffer, "v %f %f %f", &model->vertexArray[vertpos].x, &model->vertexArray[vertpos].y, &model->vertexArray[vertpos].z);
			vertpos++;
		}
		else if(strequal(readbuffer, "f", &readbuffer[position], 1))
		{
			if(model->numMaterial > 0)
				model->triangleArray[facepos].color = currentcolor;
			
			if(model->numTexCoord > 0 && model->numNormal > 0)
			{
				sscanf(readbuffer, "f %d/%d/%d %d/%d/%d %d/%d/%d", &model->triangleArray[facepos].vertex[0], &model->triangleArray[facepos].texcoord[0], &model->triangleArray[facepos].normal[0], &model->triangleArray[facepos].vertex[1], &model->triangleArray[facepos].texcoord[1], &model->triangleArray[facepos].normal[1], &model->triangleArray[facepos].vertex[2], &model->triangleArray[facepos].texcoord[2], &model->triangleArray[facepos].normal[2]);
				facepos++;
			}
			else if(model->numNormal > 0)
			{
				sscanf(readbuffer, "f %d//%d %d//%d %d//%d", &model->triangleArray[facepos].vertex[0], &model->triangleArray[facepos].normal[0], &model->triangleArray[facepos].vertex[1], &model->triangleArray[facepos].normal[1], &model->triangleArray[facepos].vertex[2], &model->triangleArray[facepos].normal[2]);
				facepos++;
			}
			else if(model->numTexCoord > 0)
			{
				sscanf(readbuffer, "f %d/%d %d/%d %d/%d", &model->triangleArray[facepos].vertex[0], &model->triangleArray[facepos].texcoord[0], &model->triangleArray[facepos].vertex[1], &model->triangleArray[facepos].texcoord[1], &model->triangleArray[facepos].vertex[2], &model->triangleArray[facepos].texcoord[2]);
				facepos++;
			}
			else
			{
				sscanf(readbuffer, "f %d %d %d", &model->triangleArray[facepos].vertex[0], &model->triangleArray[facepos].vertex[1], &model->triangleArray[facepos].vertex[2]);
				facepos++;
			}
		}
		else if(strequal(readbuffer, "mtllib", &readbuffer[position], 6))
		{
			sscanf(readbuffer, "mtllib %s", materialname);
			mtl = pgeObjLoadMaterial(materialname);
			
			if(!mtl)
			{
				pgeFree(model->vertexArray);
				pgeFree(model->normalArray);
				pgeFree(model->texCoordArray);
				pgeFree(model);
				return NULL;
			}
		}
		else if(strequal(readbuffer, "usemtl", &readbuffer[position], 6))
		{
			sscanf(readbuffer, "usemtl %s", materialname);
			currentcolor = pgeObjSetColorFromMaterial(mtl, materialname);
		}
	}
	
	pgeObj *obj = (pgeObj *)pgeMalloc(sizeof(pgeObj));
	
	if(!obj)
	{
		pgeFree(model->vertexArray);
		pgeFree(model->normalArray);
		pgeFree(model->texCoordArray);
		pgeFree(model->triangleArray);
		pgeFree(model);
		return NULL;
	}
	
	memset(obj, 0, sizeof(obj));
	
	// Arrange the data into our vert array.
	obj->numvertices = model->numTriangle * 3;
	
	int i = 0;
	int f = 0;
	int v = 0;
	
	if(model->numTexCoord > 0 && model->numNormal > 0)
	{
		if(model->numMaterial == 0)
		{
			obj->vertices =  (pgeVertTNV *)pgeMalloc(sizeof(pgeVertTNV) * model->numTriangle * 3);
			pgeVertTNV *ptr = (pgeVertTNV *)obj->vertices;
			obj->drawflag = GU_TEXTURE_32BITF|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D;
			
			for(i = 0; i < model->numTriangle;i++)
			{
				for(f = 0; f < 3;f++)
				{
					ptr[v].u = model->texCoordArray[model->triangleArray[i].texcoord[f]-1].u;
					ptr[v].v = 1.0f - model->texCoordArray[model->triangleArray[i].texcoord[f]-1].v;
		
					ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x;
					ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y;
					ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z;
					
					tempnv = 1.0f/(pgeMathSqrt(ptr[v].x*ptr[v].x + ptr[v].y*ptr[v].y + ptr[v].z*ptr[v].z));
					ptr[v].nx = ptr[v].x * tempnv;
					ptr[v].ny = ptr[v].y * tempnv;
					ptr[v].nz = ptr[v].z * tempnv;
					
					v++;
				}
			}
		}
		else
		{
			obj->vertices =  (pgeVertTCNV *)pgeMalloc(sizeof(pgeVertTCNV) * model->numTriangle * 3);
			pgeVertTCNV *ptr = (pgeVertTCNV *)obj->vertices;
			obj->drawflag = GU_COLOR_8888|GU_TEXTURE_32BITF|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D;
			
			for(i = 0; i < model->numTriangle;i++)
			{
				for(f = 0; f < 3;f++)
				{
					ptr[v].u = model->texCoordArray[model->triangleArray[i].texcoord[f]-1].u;
					ptr[v].v = 1.0f - model->texCoordArray[model->triangleArray[i].texcoord[f]-1].v;
					
					ptr[v].color = model->triangleArray[i].color;
		
					ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x;
					ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y;
					ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z;
					
					tempnv = 1.0f/(pgeMathSqrt(ptr[v].x*ptr[v].x + ptr[v].y*ptr[v].y + ptr[v].z*ptr[v].z));
					ptr[v].nx = ptr[v].x * tempnv;
					ptr[v].ny = ptr[v].y * tempnv;
					ptr[v].nz = ptr[v].z * tempnv;
					
					v++;
				}
			}
		}
		
	}
	else if(model->numTexCoord > 0)
	{
		if(model->numMaterial == 0)
		{
			obj->vertices = (pgeVertTV *)pgeMalloc(sizeof(pgeVertTV) * model->numTriangle * 3);
			pgeVertTV *ptr = (pgeVertTV *)obj->vertices;
			obj->drawflag = GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D;
		
			for(i = 0; i < model->numTriangle;i++)
			{
				for(f = 0; f < 3;f++)
				{
					ptr[v].u = model->texCoordArray[model->triangleArray[i].texcoord[f]-1].u;
					ptr[v].v = 1.0f - model->texCoordArray[model->triangleArray[i].texcoord[f]-1].v;
		
					ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x;
					ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y;
					ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z;
					
					v++;
				}
			}
		}
		else
		{
			obj->vertices = (pgeVertTCV *)pgeMalloc(sizeof(pgeVertTCV) * model->numTriangle * 3);
			pgeVertTCV *ptr = (pgeVertTCV *)obj->vertices;
			obj->drawflag = GU_COLOR_8888|GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D;
		
			for(i = 0; i < model->numTriangle;i++)
			{
				for(f = 0; f < 3;f++)
				{
					ptr[v].u = model->texCoordArray[model->triangleArray[i].texcoord[f]-1].u;
					ptr[v].v = 1.0f - model->texCoordArray[model->triangleArray[i].texcoord[f]-1].v;
					
					ptr[v].color = model->triangleArray[i].color;
		
					ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x;
					ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y;
					ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z;
					
					v++;
				}
			}
		}
	}
	else if(model->numNormal > 0)
	{
		if(model->numMaterial == 0)
		{
			obj->vertices = (pgeVertNV *)pgeMalloc(sizeof(pgeVertNV) * model->numTriangle * 3);
			pgeVertNV *ptr = (pgeVertNV *)obj->vertices;
			obj->drawflag = GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D;
		
			for(i = 0; i < model->numTriangle;i++)
			{
				for(f = 0; f < 3;f++)
				{
					ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x;
					ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y;
					ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z;
					
					tempnv = 1.0f/(pgeMathSqrt(ptr[v].x*ptr[v].x + ptr[v].y*ptr[v].y + ptr[v].z*ptr[v].z));
					ptr[v].nx = ptr[v].x * tempnv;
					ptr[v].ny = ptr[v].y * tempnv;
					ptr[v].nz = ptr[v].z * tempnv;

					v++;
				}
			}
		}
		else
		{
			obj->vertices = (pgeVertCNV *)pgeMalloc(sizeof(pgeVertCNV) * model->numTriangle * 3);
			pgeVertCNV *ptr = (pgeVertCNV *)obj->vertices;
			obj->drawflag = GU_COLOR_8888|GU_NORMAL_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D;
		
			for(i = 0; i < model->numTriangle;i++)
			{
				for(f = 0; f < 3;f++)
				{
					ptr[v].color = model->triangleArray[i].color;
		
					ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x;
					ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y;
					ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z;

					tempnv = 1.0f/(pgeMathSqrt(ptr[v].x*ptr[v].x + ptr[v].y*ptr[v].y + ptr[v].z*ptr[v].z));
					ptr[v].nx = ptr[v].x * tempnv;
					ptr[v].ny = ptr[v].y * tempnv;
					ptr[v].nz = ptr[v].z * tempnv;

					v++;
				}
			}
		}
	}
	else
	{
		if(model->numMaterial == 0)
		{
			obj->vertices = (pgeVertV *)pgeMalloc(sizeof(pgeVertV) * model->numTriangle * 3);
			pgeVertV *ptr = (pgeVertV *)obj->vertices;
			obj->drawflag = GU_VERTEX_32BITF|GU_TRANSFORM_3D;
		
			for(i = 0; i < model->numTriangle;i++)
			{
				for(f = 0; f < 3;f++)
				{
					ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x;
					ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y;
					ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z;
					
					v++;
				}
			}
		}
		else
		{
			obj->vertices = (pgeVertCV *)pgeMalloc(sizeof(pgeVertCV) * model->numTriangle * 3);
			pgeVertCV *ptr = (pgeVertCV *)obj->vertices;
			obj->drawflag = GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_3D;
		
			for(i = 0; i < model->numTriangle;i++)
			{
				for(f = 0; f < 3;f++)
				{
					ptr[v].color = model->triangleArray[i].color;
					
					ptr[v].x = model->vertexArray[model->triangleArray[i].vertex[f]-1].x;
					ptr[v].y = model->vertexArray[model->triangleArray[i].vertex[f]-1].y;
					ptr[v].z = model->vertexArray[model->triangleArray[i].vertex[f]-1].z;
					
					v++;
				}
			}
		}
	}
	
	// Tidy up
	if(model->vertexArray)
		pgeFree(model->vertexArray);
		
	if(model->normalArray)
		pgeFree(model->normalArray);
		
	if(model->texCoordArray)
		pgeFree(model->texCoordArray);
		
	if(model->triangleArray)
		pgeFree(model->triangleArray);
		
	if(model)
		pgeFree(model);
		
	if(mtl)
	{
		for(i = 0;i < mtl->nummaterials;i++)
		{
			if(mtl->materials[i].name)
				pgeFree(mtl->materials[i].name);
				
			if(mtl->materials)
				pgeFree(mtl->materials);
		}
		
		pgeFree(mtl);
	}
		
	sceKernelDcacheWritebackInvalidateAll();
	
	return obj;
}
Exemplo n.º 15
0
/*
 * Mangle the "Transport:" header:
 *   - Replace all occurences of "client_port=<spec>"
 *   - Handle destination parameter
 *
 * In:
 *   ct, ctinfo = conntrack context
 *   skb        = packet
 *   tranoff    = Transport header offset from TCP data
 *   tranlen    = Transport header length (incl. CRLF)
 *   rport_lo   = replacement low  port (host endian)
 *   rport_hi   = replacement high port (host endian)
 *
 * Returns packet size difference.
 *
 * Assumes that a complete transport header is present, ending with CR or LF
 */
static int
rtsp_mangle_tran(enum ip_conntrack_info ctinfo,
                 struct nf_conntrack_expect* exp,
                 struct ip_ct_rtsp_expect* prtspexp,
                 struct sk_buff* skb, uint tranoff, uint tranlen)
{
    char*       ptcp;
    uint        tcplen;
    char*       ptran;
    char        rbuf1[16];      /* Replacement buffer (one port) */
    uint        rbuf1len;       /* Replacement len (one port) */
    char        rbufa[16];      /* Replacement buffer (all ports) */
    uint        rbufalen;       /* Replacement len (all ports) */
    u_int32_t   newip;
    u_int16_t   loport, hiport;
    uint        off = 0;
    uint        diff;           /* Number of bytes we removed */

    struct nf_conn *ct = exp->master;
    struct nf_conntrack_tuple *t;

    char    szextaddr[15+1];
    uint    extaddrlen;
    int     is_stun;

    get_skb_tcpdata(skb, &ptcp, &tcplen);
    ptran = ptcp+tranoff;

    if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen ||
            tranlen < 10 || !iseol(ptran[tranlen-1]) ||
            nf_strncasecmp(ptran, "Transport:", 10) != 0)
    {
        pr_info("sanity check failed\n");
        return 0;
    }
    off += 10;
    SKIP_WSPACE(ptcp+tranoff, tranlen, off);

    newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
    t = &exp->tuple;
    t->dst.u3.ip = newip;

    extaddrlen = extip ? sprintf(szextaddr, "%pI4", &extip)
                 : sprintf(szextaddr, "%pI4", &newip);
    pr_debug("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto"));

    rbuf1len = rbufalen = 0;
    switch (prtspexp->pbtype)
    {
    case pb_single:
        for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */
        {
            t->dst.u.udp.port = htons(loport);
            if (nf_ct_expect_related(exp) == 0)
            {
                pr_debug("using port %hu\n", loport);
                break;
            }
        }
        if (loport != 0)
        {
            rbuf1len = sprintf(rbuf1, "%hu", loport);
            rbufalen = sprintf(rbufa, "%hu", loport);
        }
        break;
    case pb_range:
        for (loport = prtspexp->loport; loport != 0; loport += 2) /* XXX: improper wrap? */
        {
            t->dst.u.udp.port = htons(loport);
            if (nf_ct_expect_related(exp) == 0)
            {
                hiport = loport + 1; //~exp->mask.dst.u.udp.port;
                pr_debug("using ports %hu-%hu\n", loport, hiport);
                break;
            }
        }
        if (loport != 0)
        {
            rbuf1len = sprintf(rbuf1, "%hu", loport);
            rbufalen = sprintf(rbufa, "%hu-%hu", loport, loport+1);
        }
        break;
    case pb_discon:
        for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */
        {
            t->dst.u.udp.port = htons(loport);
            if (nf_ct_expect_related(exp) == 0)
            {
                pr_debug("using port %hu (1 of 2)\n", loport);
                break;
            }
        }
        for (hiport = prtspexp->hiport; hiport != 0; hiport++) /* XXX: improper wrap? */
        {
            t->dst.u.udp.port = htons(hiport);
            if (nf_ct_expect_related(exp) == 0)
            {
                pr_debug("using port %hu (2 of 2)\n", hiport);
                break;
            }
        }
        if (loport != 0 && hiport != 0)
        {
            rbuf1len = sprintf(rbuf1, "%hu", loport);
            if (hiport == loport+1)
            {
                rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport);
            }
            else
            {
                rbufalen = sprintf(rbufa, "%hu/%hu", loport, hiport);
            }
        }
        break;
    }

    if (rbuf1len == 0)
    {
        return 0;   /* cannot get replacement port(s) */
    }

    /* Transport: tran;field;field=val,tran;field;field=val,... */
    while (off < tranlen)
    {
        uint        saveoff;
        const char* pparamend;
        uint        nextparamoff;

        pparamend = memchr(ptran+off, ',', tranlen-off);
        pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
        nextparamoff = pparamend-ptcp;

        /*
         * We pass over each param twice.  On the first pass, we look for a
         * destination= field.  It is handled by the security policy.  If it
         * is present, allowed, and equal to our external address, we assume
         * that STUN is being used and we leave the client_port= field alone.
         */
        is_stun = 0;
        saveoff = off;
        while (off < nextparamoff)
        {
            const char* pfieldend;
            uint        nextfieldoff;

            pfieldend = memchr(ptran+off, ';', nextparamoff-off);
            nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;

            if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0)
            {
                if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0)
                {
                    is_stun = 1;
                }
                if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun))
                {
                    diff = nextfieldoff-off;
                    if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
                                                  off, diff, NULL, 0))
                    {
                        /* mangle failed, all we can do is bail */
                        nf_ct_unexpect_related(exp);
                        return 0;
                    }
                    get_skb_tcpdata(skb, &ptcp, &tcplen);
                    ptran = ptcp+tranoff;
                    tranlen -= diff;
                    nextparamoff -= diff;
                    nextfieldoff -= diff;
                }
            }

            off = nextfieldoff;
        }
        if (is_stun)
        {
            continue;
        }
        off = saveoff;
        while (off < nextparamoff)
        {
            const char* pfieldend;
            uint        nextfieldoff;

            pfieldend = memchr(ptran+off, ';', nextparamoff-off);
            nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;

            if (strncmp(ptran+off, "client_port=", 12) == 0)
            {
                u_int16_t   port;
                uint        numlen;
                uint        origoff;
                uint        origlen;
                char*       rbuf    = rbuf1;
                uint        rbuflen = rbuf1len;

                off += 12;
                origoff = (ptran-ptcp)+off;
                origlen = 0;
                numlen = nf_strtou16(ptran+off, &port);
                off += numlen;
                origlen += numlen;
                if (port != prtspexp->loport)
                {
                    pr_debug("multiple ports found, port %hu ignored\n", port);
                }
                else
                {
                    if (ptran[off] == '-' || ptran[off] == '/')
                    {
                        off++;
                        origlen++;
                        numlen = nf_strtou16(ptran+off, &port);
                        off += numlen;
                        origlen += numlen;
                        rbuf = rbufa;
                        rbuflen = rbufalen;
                    }

                    /*
                     * note we cannot just memcpy() if the sizes are the same.
                     * the mangle function does skb resizing, checks for a
                     * cloned skb, and updates the checksums.
                     *
                     * parameter 4 below is offset from start of tcp data.
                     */
                    diff = origlen-rbuflen;
                    if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
                                                  origoff, origlen, rbuf, rbuflen))
                    {
                        /* mangle failed, all we can do is bail */
                        nf_ct_unexpect_related(exp);
                        return 0;
                    }
                    get_skb_tcpdata(skb, &ptcp, &tcplen);
                    ptran = ptcp+tranoff;
                    tranlen -= diff;
                    nextparamoff -= diff;
                    nextfieldoff -= diff;
                }
            }

            off = nextfieldoff;
        }

        off = nextparamoff;
    }

    return 1;
}
Exemplo n.º 16
0
Arquivo: macro.c Projeto: xrg/RPM
/**
 * Parse (and execute) new macro definition.
 * @param mb		macro expansion state
 * @param se		macro definition to parse
 * @param level		macro recursion level
 * @param expandbody	should body be expanded?
 * @return		address to continue parsing
 */
static const char *
doDefine(MacroBuf mb, const char * se, int level, int expandbody)
{
    const char *s = se;
    size_t blen = MACROBUFSIZ;
    char *buf = xmalloc(blen);
    char *n = buf, *ne = n;
    char *o = NULL, *oe;
    char *b, *be;
    int c;
    int oc = ')';

    /* Copy name */
    COPYNAME(ne, s, c);

    /* Copy opts (if present) */
    oe = ne + 1;
    if (*s == '(') {
	s++;	/* skip ( */
	o = oe;
	COPYOPTS(oe, s, oc);
	s++;	/* skip ) */
    }

    /* Copy body, skipping over escaped newlines */
    b = be = oe + 1;
    SKIPBLANK(s, c);
    if (c == '{') {	/* XXX permit silent {...} grouping */
	if ((se = matchchar(s, c, '}')) == NULL) {
	    rpmlog(RPMLOG_ERR,
		_("Macro %%%s has unterminated body\n"), n);
	    se = s;	/* XXX W2DO? */
	    return se;
	}
	s++;	/* XXX skip { */
	strncpy(b, s, (se - s));
	b[se - s] = '\0';
	be += strlen(b);
	se++;	/* XXX skip } */
	s = se;	/* move scan forward */
    } else {	/* otherwise free-field */
	int bc = 0, pc = 0;
	while (*s && (bc || pc || !iseol(*s))) {
	    switch (*s) {
		case '\\':
		    switch (*(s+1)) {
			case '\0': break;
			default: s++; break;
		    }
		    break;
		case '%':
		    switch (*(s+1)) {
			case '{': *be++ = *s++; bc++; break;
			case '(': *be++ = *s++; pc++; break;
			case '%': *be++ = *s++; break;
		    }
		    break;
		case '{': if (bc > 0) bc++; break;
		case '}': if (bc > 0) bc--; break;
		case '(': if (pc > 0) pc++; break;
		case ')': if (pc > 0) pc--; break;
	    }
	    *be++ = *s++;
	}
	*be = '\0';

	if (bc || pc) {
	    rpmlog(RPMLOG_ERR,
		_("Macro %%%s has unterminated body\n"), n);
	    se = s;	/* XXX W2DO? */
	    return se;
	}

	/* Trim trailing blanks/newlines */
	while (--be >= b && (c = *be) && (isblank(c) || iseol(c)))
	    {};
	*(++be) = '\0';	/* one too far */
    }

    /* Move scan over body */
    while (iseol(*s))
	s++;
    se = s;

    /* Names must start with alphabetic or _ and be at least 3 chars */
    if (!((c = *n) && (risalpha(c) || c == '_') && (ne - n) > 2)) {
	rpmlog(RPMLOG_ERR,
		_("Macro %%%s has illegal name (%%define)\n"), n);
	return se;
    }

    /* Options must be terminated with ')' */
    if (o && oc != ')') {
	rpmlog(RPMLOG_ERR, _("Macro %%%s has unterminated opts\n"), n);
	goto exit;
    }

    if ((be - b) < 1) {
	rpmlog(RPMLOG_ERR, _("Macro %%%s has empty body\n"), n);
	goto exit;
    }

    if (expandbody && expandU(mb, b, (&buf[blen] - b))) {
	rpmlog(RPMLOG_ERR, _("Macro %%%s failed to expand\n"), n);
	goto exit;
    }

    addMacro(mb->mc, n, o, b, (level - 1));

exit:
    _free(buf);
    return se;
}
Exemplo n.º 17
0
Arquivo: macro.c Projeto: xrg/RPM
/**
 * The main macro recursion loop.
 * @todo Dynamically reallocate target buffer.
 * @param mb		macro expansion state
 * @return		0 on success, 1 on failure
 */
static int
expandMacro(MacroBuf mb)
{
    rpmMacroEntry *mep;
    rpmMacroEntry me;
    const char *s = mb->s, *se;
    const char *f, *fe;
    const char *g, *ge;
    size_t fn, gn;
    char *t = mb->t;	/* save expansion pointer for printExpand */
    int c;
    int rc = 0;
    int negate;
    const char * lastc;
    int chkexist;

    if (++mb->depth > max_macro_depth) {
	rpmlog(RPMLOG_ERR,
		_("Recursion depth(%d) greater than max(%d)\n"),
		mb->depth, max_macro_depth);
	mb->depth--;
	mb->expand_trace = 1;
	return 1;
    }

    while (rc == 0 && mb->nb > 0 && (c = *s) != '\0') {
	s++;
	/* Copy text until next macro */
	switch(c) {
	case '%':
		if (*s) {	/* Ensure not end-of-string. */
		    if (*s != '%')
			break;
		    s++;	/* skip first % in %% */
		}
	default:
		SAVECHAR(mb, c);
		continue;
		break;
	}

	/* Expand next macro */
	f = fe = NULL;
	g = ge = NULL;
	if (mb->depth > 1)	/* XXX full expansion for outermost level */
		t = mb->t;	/* save expansion pointer for printExpand */
	negate = 0;
	lastc = NULL;
	chkexist = 0;
	switch ((c = *s)) {
	default:		/* %name substitution */
		while (strchr("!?", *s) != NULL) {
			switch(*s++) {
			case '!':
				negate = ((negate + 1) % 2);
				break;
			case '?':
				chkexist++;
				break;
			}
		}
		f = se = s;
		if (*se == '-')
			se++;
		while((c = *se) && (risalnum(c) || c == '_'))
			se++;
		/* Recognize non-alnum macros too */
		switch (*se) {
		case '*':
			se++;
			if (*se == '*') se++;
			break;
		case '#':
			se++;
			break;
		default:
			break;
		}
		fe = se;
		/* For "%name " macros ... */
		if ((c = *fe) && isblank(c))
			if ((lastc = strchr(fe,'\n')) == NULL)
                lastc = strchr(fe, '\0');
		break;
	case '(':		/* %(...) shell escape */
		if ((se = matchchar(s, c, ')')) == NULL) {
			rpmlog(RPMLOG_ERR,
				_("Unterminated %c: %s\n"), (char)c, s);
			rc = 1;
			continue;
		}
		if (mb->macro_trace)
			printMacro(mb, s, se+1);

		s++;	/* skip ( */
		rc = doShellEscape(mb, s, (se - s));
		se++;	/* skip ) */

		s = se;
		continue;
		break;
	case '{':		/* %{...}/%{...:...} substitution */
		if ((se = matchchar(s, c, '}')) == NULL) {
			rpmlog(RPMLOG_ERR,
				_("Unterminated %c: %s\n"), (char)c, s);
			rc = 1;
			continue;
		}
		f = s+1;/* skip { */
		se++;	/* skip } */
		while (strchr("!?", *f) != NULL) {
			switch(*f++) {
			case '!':
				negate = ((negate + 1) % 2);
				break;
			case '?':
				chkexist++;
				break;
			}
		}
		for (fe = f; (c = *fe) && !strchr(" :}", c);)
			fe++;
		switch (c) {
		case ':':
			g = fe + 1;
			ge = se - 1;
			break;
		case ' ':
			lastc = se-1;
			break;
		default:
			break;
		}
		break;
	}

	/* XXX Everything below expects fe > f */
	fn = (fe - f);
	gn = (ge - g);
	if ((fe - f) <= 0) {
/* XXX Process % in unknown context */
		c = '%';	/* XXX only need to save % */
		SAVECHAR(mb, c);
#if 0
		rpmlog(RPMLOG_ERR,
			_("A %% is followed by an unparseable macro\n"));
#endif
		s = se;
		continue;
	}

	if (mb->macro_trace)
		printMacro(mb, s, se);

	/* Expand builtin macros */
	if (STREQ("global", f, fn)) {
		s = doDefine(mb, se, RMIL_GLOBAL, 1);
		continue;
	}
	if (STREQ("define", f, fn)) {
		s = doDefine(mb, se, mb->depth, 0);
		continue;
	}
	if (STREQ("undefine", f, fn)) {
		s = doUndefine(mb->mc, se);
		continue;
	}

	if (STREQ("echo", f, fn) ||
	    STREQ("warn", f, fn) ||
	    STREQ("error", f, fn)) {
		int waserror = 0;
		if (STREQ("error", f, fn))
			waserror = 1;
		if (g != NULL && g < ge)
			doOutput(mb, waserror, g, gn);
		else
			doOutput(mb, waserror, f, fn);
		s = se;
		continue;
	}

	if (STREQ("trace", f, fn)) {
		/* XXX TODO restore expand_trace/macro_trace to 0 on return */
		mb->expand_trace = mb->macro_trace = (negate ? 0 : mb->depth);
		if (mb->depth == 1) {
			print_macro_trace = mb->macro_trace;
			print_expand_trace = mb->expand_trace;
		}
		s = se;
		continue;
	}

	if (STREQ("dump", f, fn)) {
		rpmDumpMacroTable(mb->mc, NULL);
		while (iseol(*se))
			se++;
		s = se;
		continue;
	}

#ifdef	WITH_LUA
	if (STREQ("lua", f, fn)) {
		rpmlua lua = NULL; /* Global state. */
		const char *ls = s+sizeof("{lua:")-1;
		const char *lse = se-sizeof("}")+1;
		char *scriptbuf = (char *)xmalloc((lse-ls)+1);
		const char *printbuf;
		memcpy(scriptbuf, ls, lse-ls);
		scriptbuf[lse-ls] = '\0';
		rpmluaSetPrintBuffer(lua, 1);
		if (rpmluaRunScript(lua, scriptbuf, NULL) == -1)
		    rc = 1;
		printbuf = rpmluaGetPrintBuffer(lua);
		if (printbuf) {
		    size_t len = strlen(printbuf);
		    if (len > mb->nb)
			len = mb->nb;
		    memcpy(mb->t, printbuf, len);
		    mb->t += len;
		    mb->nb -= len;
		}
		rpmluaSetPrintBuffer(lua, 0);
		free(scriptbuf);
		s = se;
		continue;
	}
#endif

	/* XXX necessary but clunky */
	if (STREQ("basename", f, fn) ||
	    STREQ("suffix", f, fn) ||
	    STREQ("expand", f, fn) ||
	    STREQ("verbose", f, fn) ||
	    STREQ("uncompress", f, fn) ||
	    STREQ("url2path", f, fn) ||
	    STREQ("u2p", f, fn) ||
	    STREQ("getenv", f, fn) ||
	    STREQ("S", f, fn) ||
	    STREQ("P", f, fn) ||
	    STREQ("F", f, fn)) {
		/* FIX: verbose may be set */
		doFoo(mb, negate, f, fn, g, gn);
		s = se;
		continue;
	}

	/* Expand defined macros */
	mep = findEntry(mb->mc, f, fn);
	me = (mep ? *mep : NULL);

	/* XXX Special processing for flags */
	if (*f == '-') {
		if (me)
			me->used++;	/* Mark macro as used */
		if ((me == NULL && !negate) ||	/* Without -f, skip %{-f...} */
		    (me != NULL && negate)) {	/* With -f, skip %{!-f...} */
			s = se;
			continue;
		}

		if (g && g < ge) {		/* Expand X in %{-f:X} */
			rc = expandT(mb, g, gn);
		} else
		if (me && me->body && *me->body) {/* Expand %{-f}/%{-f*} */
			rc = expandT(mb, me->body, strlen(me->body));
		}
		s = se;
		continue;
	}

	/* XXX Special processing for macro existence */
	if (chkexist) {
		if ((me == NULL && !negate) ||	/* Without -f, skip %{?f...} */
		    (me != NULL && negate)) {	/* With -f, skip %{!?f...} */
			s = se;
			continue;
		}
		if (g && g < ge) {		/* Expand X in %{?f:X} */
			rc = expandT(mb, g, gn);
		} else
		if (me && me->body && *me->body) { /* Expand %{?f}/%{?f*} */
			rc = expandT(mb, me->body, strlen(me->body));
		}
		s = se;
		continue;
	}
	
	if (me == NULL) {	/* leave unknown %... as is */
#ifndef HACK
#if DEAD
		/* XXX hack to skip over empty arg list */
		if (fn == 1 && *f == '*') {
			s = se;
			continue;
		}
#endif
		/* XXX hack to permit non-overloaded %foo to be passed */
		c = '%';	/* XXX only need to save % */
		SAVECHAR(mb, c);
#else
		rpmlog(RPMLOG_ERR,
			_("Macro %%%.*s not found, skipping\n"), fn, f);
		s = se;
#endif
		continue;
	}

	/* Setup args for "%name " macros with opts */
	if (me && me->opts != NULL) {
		if (lastc != NULL) {
			se = grabArgs(mb, me, fe, lastc);
		} else {
			addMacro(mb->mc, "**", NULL, "", mb->depth);
			addMacro(mb->mc, "*", NULL, "", mb->depth);
			addMacro(mb->mc, "#", NULL, "0", mb->depth);
			addMacro(mb->mc, "0", NULL, me->name, mb->depth);
		}
	}

	/* Recursively expand body of macro */
	if (me->body && *me->body) {
		mb->s = me->body;
		rc = expandMacro(mb);
		if (rc == 0)
			me->used++;	/* Mark macro as used */
	}

	/* Free args for "%name " macros with opts */
	if (me->opts != NULL)
		freeArgs(mb);

	s = se;
    }

    *mb->t = '\0';
    mb->s = s;
    mb->depth--;
    if (rc != 0 || mb->expand_trace)
	printExpansion(mb, t, mb->t);
    return rc;
}
Exemplo n.º 18
0
int
include(const char *filename)
{
    struct includeline	*script, *se, *sp;
    char		input[256];			/* big enough? */
    int			argc,res;
    char		**argv, *cp;
    int			fd, flags, line;

    if (((fd = rel_open(filename, NULL, O_RDONLY)) == -1)) {
	command_errmsg = command_errbuf;
	snprintf(command_errbuf, 256, "cannot find \"%s\"", filename);
	return(CMD_ERROR);
    }

    /*
     * Read the script into memory.
     */
    script = se = NULL;
    line = 0;

    while (fgets(input, sizeof(input), fd) != NULL) {
	line++;
	flags = 0;
	if(strlen(input) == sizeof(input) - 1 &&
	    !iseol(input[sizeof(input) - 2])) {
	    printf("WARNING: %s: %s: Line too long: truncating; have:\n",
		__func__, filename);
	    printf("%s\n", input);
	    skipeol(fd);
	}
	/* Discard comments */
	if (strncmp(input+strspn(input, " "), "\\ ", 2) == 0)
	    continue;
	cp = input;
	/* Echo? */
	if (input[0] == '@') {
	    cp++;
	    flags |= SL_QUIET;
	}
	/* Error OK? */
	if (input[0] == '-') {
	    cp++;
	    flags |= SL_IGNOREERR;
	}
	/* Allocate script line structure and copy line, flags */
	sp = malloc(sizeof(struct includeline) + strlen(cp) + 1);
	sp->text = (char *)sp + sizeof(struct includeline);
	strcpy(sp->text, cp);
	sp->flags = flags;
	sp->line = line;
	sp->next = NULL;

	if (script == NULL) {
	    script = sp;
	} else {
	    se->next = sp;
	}
	se = sp;
    }
    close(fd);

    /*
     * Execute the script
     */
    argv = NULL;
    res = CMD_OK;
    for (sp = script; sp != NULL; sp = sp->next) {

#if 0
	/* print if not being quiet */
	if (!(sp->flags & SL_QUIET)) {
	    prompt();
	    printf("%s\n", sp->text);
	}
#endif

	/* Parse the command */
	if (!parse(&argc, &argv, sp->text)) {
	    if ((argc > 0) && (perform(argc, argv) != 0)) {
		/* normal command */
		printf("%s: %s\n", argv[0], command_errmsg);
		if (!(sp->flags & SL_IGNOREERR)) {
		    res=CMD_ERROR;
		    break;
		}
	    }
	    free(argv);
	    argv = NULL;
	} else {
	    printf("%s line %d: parse error\n", filename, sp->line);
	    res=CMD_ERROR;
	    break;
	}
    }
    if (argv != NULL)
	free(argv);
    while(script != NULL) {
	se = script;
	script = script->next;
	free(se);
    }
    return(res);
}
Exemplo n.º 19
0
CC_STRING CMaExpander::Expand_FLM(CMacro *ma)
{
	CC_STRING outs;
	CC_ARRAY<CC_STRING> margs;
	CC_STRING carg;
	const char *p = pos;
	int level;

	skip_blanks(p);
	if( iseol(*p) ) {
		gex.format("Macro \"%s\" expects arguments", TR(tc,ma->id));
		throw &gex;
	}
	if( *p != '(' ) {
		gex = "Macro expects '('";
		throw &gex;
	}

	p++;
	skip_blanks(p);
	level = 1;
	while( 1 ) {
		if( iseol(*p) )
			break;

		if( *p == ','  ) {
			if( level == 1 && ( ! ma->va_args || (margs.size() + 1 < ma->nr_args) ) ) {
				Trim(carg);
				margs.push_back(carg);
				carg.clear();
			} else {
				carg += ',';
				skip_blanks(p);
			}
		} else if(*p == '(') {
			level ++;
			carg += '(';
		} else if(*p == ')') {
			level --;
			if(level == 0) {
				p++;
				Trim(carg);
				margs.push_back(carg);
				carg.clear();
				break;
			} else
				carg += ')';
		} else {
			carg += *p;
		}
		p++;
	}
	pos = p;

	XCHAR *xc;
	CC_STRING s;
	size_t n;

	n = ma->nr_args;
	assert(n != CMacro::OL_M);
	if(n != margs.size()) {
		if( ma->va_args && margs.size() + 1 == n ) {
			margs.push_back(CC_STRING(""));
		} else {
			gex.format("Macro \"%s\" requires %u arguments, but %u given",
				TR(tc,ma->id), n, margs.size() );
			throw &gex;
		}
	}

	for(xc = ma->parsed; *xc != 0; xc++) {
		if(IS_MA_PAR2(*xc) || IS_MA_PAR0(*xc)) {
			const CC_STRING& carg = margs[(uint8_t)*xc];
			CMaExpander expander2(tc, carg.c_str(), for_include);
			CC_STRING tmp;
			tmp = expander2.TryExpand();
			s += tmp;
		} else if(IS_MA_PAR1(*xc)) {
			const CC_STRING& carg = margs[(uint8_t)*xc];
			s += '"';
			s += carg;
			s += '"';
		} else {
			s += (char) *xc;
		}
	}
	outs += s;

	return outs;
}
Exemplo n.º 20
0
/*
 * Find lo/hi client ports (if any) in transport header
 * In:
 *   ptcp, tcplen = packet
 *   tranoff, tranlen = buffer to search
 *
 * Out:
 *   pport_lo, pport_hi = lo/hi ports (host endian)
 *
 * Returns nonzero if any client ports found
 *
 * Note: it is valid (and expected) for the client to request multiple
 * transports, so we need to parse the entire line.
 */
static int
rtsp_parse_transport(char* ptran, uint tranlen,
                     struct ip_ct_rtsp_expect* prtspexp)
{
	int     rc = 0;
	uint    off = 0;
	
	if (tranlen < 10 || !iseol(ptran[tranlen-1]) ||
	    nf_strncasecmp(ptran, "Transport:", 10) != 0) {
		pr_info("sanity check failed\n");
		return 0;
	}
	
	pr_debug("tran='%.*s'\n", (int)tranlen, ptran);
	off += 10;
	SKIP_WSPACE(ptran, tranlen, off);
	
	/* Transport: tran;field;field=val,tran;field;field=val,... */
	while (off < tranlen) {
		const char* pparamend;
		uint        nextparamoff;
		
		pparamend = memchr(ptran+off, ',', tranlen-off);
		pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
		nextparamoff = pparamend-ptran;
		
		while (off < nextparamoff) {
			const char* pfieldend;
			uint        nextfieldoff;
			
			pfieldend = memchr(ptran+off, ';', nextparamoff-off);
			nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;
		   
			if (strncmp(ptran+off, "client_port=", 12) == 0) {
				u_int16_t   port;
				uint        numlen;
		    
				off += 12;
				numlen = nf_strtou16(ptran+off, &port);
				off += numlen;
				if (prtspexp->loport != 0 && prtspexp->loport != port)
					pr_debug("multiple ports found, port %hu ignored\n", port);
				else {
					pr_debug("lo port found : %hu\n", port);
					prtspexp->loport = prtspexp->hiport = port;
					if (ptran[off] == '-') {
						off++;
						numlen = nf_strtou16(ptran+off, &port);
						off += numlen;
						prtspexp->pbtype = pb_range;
						prtspexp->hiport = port;
						
						// If we have a range, assume rtp:
						// loport must be even, hiport must be loport+1
						if ((prtspexp->loport & 0x0001) != 0 ||
						    prtspexp->hiport != prtspexp->loport+1) {
							pr_debug("incorrect range: %hu-%hu, correcting\n",
							       prtspexp->loport, prtspexp->hiport);
							prtspexp->loport &= 0xfffe;
							prtspexp->hiport = prtspexp->loport+1;
						}
					} else if (ptran[off] == '/') {
						off++;
						numlen = nf_strtou16(ptran+off, &port);
						off += numlen;
						prtspexp->pbtype = pb_discon;
						prtspexp->hiport = port;
					}
					rc = 1;
				}
			}
			
			/*
			 * Note we don't look for the destination parameter here.
			 * If we are using NAT, the NAT module will handle it.  If not,
			 * and the client is sending packets elsewhere, the expectation
			 * will quietly time out.
			 */
			
			off = nextfieldoff;
		}
		
		off = nextparamoff;
	}
	
	return rc;
}
Exemplo n.º 21
0
static void handle_define(TCC_CONTEXT *tc, sym_t mid, CMacro *ma)
{
	enum {
		STA_OKAY,
		STA_LEFT_PARENTHESIS,
		STA_PARAMETER,
		STA_SEPERATOR,
		STA_TRIDOT,
	} state;

	const char *line = ma->line;
	CToken token;

	if( ! get_token(tc, &line, &token, false) )
		return;

	if(token.attr == CToken::TA_IDENT) {
		if(*line == '(') {
			CC_ARRAY<sym_t>  para_list;
			XCHAR *xc;
			const char *last_pos;
			sym_t last_para = SSID_INVALID;
			bool has_va_args = false;
		
			state = STA_LEFT_PARENTHESIS;
			line++;
			while( get_token(tc, &line, &token, false) ) {
				switch(state) {
				case STA_LEFT_PARENTHESIS:	
					if( token.id == SSID_RIGHT_PARENTHESIS) {
						state = STA_OKAY;
						goto okay;
					} else if(token.attr == CToken::TA_IDENT) {
						para_list.push_back(token.id);
						state = STA_SEPERATOR;
					} else if(token.id == SSID_TRIDOT) {
						state = STA_TRIDOT;
						continue;
					} else {
						gEx.format("\"%s\" may not appear in macro parameter list", TR(tc,token.id));
						goto error;
					}
					break;
		
				case STA_SEPERATOR:
					if(token.id == SSID_RIGHT_PARENTHESIS) {
						state = STA_OKAY;
						goto okay;
					} else if(token.id == SSID_COMMA)
						state = STA_PARAMETER;
					else if(token.id == SSID_TRIDOT) {
						state = STA_TRIDOT;
					} else {
						gEx = "macro parameters must be comma-separated";
						goto error;
					}
					break;
		
				case STA_PARAMETER:
					if(token.id == SSID_TRIDOT) {
						state = STA_TRIDOT;
						continue;
					} else if(token.attr == CToken::TA_IDENT) {
						para_list.push_back(token.id);
						state = STA_SEPERATOR;
					} else {
						gEx = "parameter name missing";
						goto error;
					}
					break;

				case STA_TRIDOT:
					if(token.id != SSID_RIGHT_PARENTHESIS) {
						gEx = "missing ')' in macro parameter list";
						throw &gEx;
					}
					has_va_args = true;
					if(last_para == SSID_COMMA || last_para == SSID_LEFT_PARENTHESIS) {
						para_list.push_back(SSID_VA_ARGS);
						last_para = SSID_VA_ARGS;
					}
					goto okay;

				default:
					assert(0);
				}
				last_para = token.id;
			}

			if(state != STA_OKAY) {
				gEx = "missing ')' in macro parameter list";
				throw &gEx;
			}
		
		okay:
			xc = (XCHAR*) malloc(sizeof(XCHAR) * strlen(line) + 4);
			ma->id         = mid;
			ma->parsed     = xc;
			ma->nr_args    = para_list.size();
			ma->va_args    = has_va_args;

			skip_blanks(line);
			last_pos = line;
			sym_t prev_sid = SSID_INVALID;

			while(  ReadToken(tc, &line, &token, &gEx, false) ) {
				if(gEx.GetError() != NULL)
					throw (&gEx);
				
				if(token.id == SSID_DUAL_SHARP) {
					if(xc == ma->parsed) {
						gEx = "'##' cannot appear at either end of a macro expansion";
						goto error;
					} else if( IS_MA_PAR0(*(xc-1)) )
						*(xc-1) |= XF_MA_PAR2;
				}
				if(prev_sid == SSID_DUAL_SHARP) {
					XCHAR *yc = xc - 3;
					while( yc >= ma->parsed && (*yc == '\t' || *yc == ' ') )
						yc--;
					xc = yc + 1;
					assert(*xc == '#' || *xc == ' ' || *xc == '\t');
				}

				if( token.attr == CToken::TA_IDENT  ) {
					int magic = 0;
					int16_t para_ord;
					static const XCHAR xflags[3] = { XF_MA_PAR0, XF_MA_PAR1, XF_MA_PAR2 };

					if( has_va_args && (token.id == last_para || token.id == SSID_VA_ARGS) )
						para_ord = ma->nr_args - 1;
					else
						para_ord = find(token.id, para_list);
					if(prev_sid == SSID_SHARP) {
						if(para_ord < 0) {
							gEx = "'#' is not followed by a macro parameter";
							goto error;
						}
						magic = 1;
						xc--;
					} else if(prev_sid == SSID_DUAL_SHARP) {
						magic = 2;
					}
					if(para_ord < 0)
						goto do_cat;
					*xc++ = para_ord | xflags[magic];
				} else {
				do_cat:
					if(prev_sid == SSID_DUAL_SHARP) {
						skip_blanks(last_pos);
					}
					join(&xc, last_pos, line);
				}
				last_pos = line;
				prev_sid = token.id;
			} /*end while*/
			*xc = 0;
		} else {
			XCHAR *xc;

			xc = (XCHAR*) malloc(sizeof(XCHAR) * strlen(line) + 4);
			ma->id      = mid;
			ma->parsed  = xc;
			ma->nr_args = CMacro::OL_M;

			skip_blanks(line);
			while(1) {
				char c = *line;
				if( iseol(c) ) {
					*xc = '\0';
					break;
				}
				*xc = c;
				xc++, line++;
			}
		}
	}
//	dump(ma->parsed);
	return;

error:
	throw &gEx;
}