Exemplo n.º 1
0
sar_bool sar_checkNodeContainChar_c(sarNode_p checkNode, char checkChar, sar_nodeClass nodeClass) {
	if (nodeClass == SAR_CHAR) {
		if (checkNode->pathChar == checkChar) {
			return SAR_TRUE;
		}
	}
	else if (nodeClass == SAR_DIGIT) {
   		if (isDIGIT(checkChar)) {
   			return SAR_TRUE;
   		}
	}
	else if (nodeClass == SAR_ALPHA_NUM) {
   		if (isALNUM(checkChar)) {
   			return SAR_TRUE;
   		}
	}
	else if (nodeClass == SAR_ALPHA) {
   		if (isALPHA(checkChar)) {
   			return SAR_TRUE;
   		}
	}
	else if (nodeClass == SAR_SPACE) {
   		if (isSPACE(checkChar)) {
   			return SAR_TRUE;
   		}
	}
	else if (nodeClass == SAR_DOT) {
		return SAR_TRUE;
	}

	return SAR_FALSE;
}
Exemplo n.º 2
0
/* maps to mod_mime_magic::apprentice */
static int
fmm_parse_magic_file(PerlFMM *state, char *file)
{
    int   ws_offset;
    int   lineno;
    int   errs;
/*    char  line[BUFSIZ + 1];*/
    PerlIO *fhandle;
    SV *err;
    SV *sv = sv_2mortal(newSV(BUFSIZ));
    SV *PL_rs_orig = newSVsv(PL_rs);
    char *line;

    fhandle = PerlIO_open(file, "r");
    if (! fhandle) {
        err = newSVpvf(
            "Failed to open %s: %s", file, strerror(errno));
        FMM_SET_ERROR(state, err);
        PerlIO_close(fhandle);
        return -1;
    }

    /*
     * Parse it line by line
     * $/ (slurp mode) is needed here
     */
    PL_rs = sv_2mortal(newSVpvn("\n", 1));
    for(lineno = 1; sv_gets(sv, fhandle, 0) != NULL; lineno++) {
        line = SvPV_nolen(sv);
        /* delete newline */
        if (line[0]) {
            line[strlen(line) - 1] = '\0';
        }

        /* skip leading whitespace */
        ws_offset = 0;
        while (line[ws_offset] && isSPACE(line[ws_offset])) {
            ws_offset++;
        }

        /* skip blank lines */
        if (line[ws_offset] == 0) {
            continue;
        }

        if (line[ws_offset] == '#') {
            continue;
        }

        if (fmm_parse_magic_line(state, line, lineno) != 0) {
            ++errs;
        }
    }
    PerlIO_close(fhandle);
    PL_rs = PL_rs_orig;

    return 1;
}
Exemplo n.º 3
0
/*
 * Quick and dirty octal conversion.
 *
 * Result is -1 if the field is invalid (all blank, or nonoctal).
 */
static long
from_oct(int digs, char *where)
{
    register long value;

    while (isSPACE(*where)) {   /* Skip spaces */
        where++;
        if (--digs <= 0)
            return -1;      /* All blank field */
    }
    value = 0;
    while (digs > 0 && isODIGIT(*where)) {  /* Scan til nonoctal */
        value = (value << 3) | (*where++ - '0');
        --digs;
    }

    if (digs > 0 && *where && !isSPACE(*where))
        return -1;      /* Ended on non-space/nul */

    return value;
}
Exemplo n.º 4
0
NETDB_DEFINE_CONTEXT
NETINET_DEFINE_CONTEXT
#endif

#ifdef I_SYSUIO
# include <sys/uio.h>
#endif

#ifndef AF_NBS
# undef PF_NBS
#endif

#ifndef AF_X25
# undef PF_X25
#endif

#ifndef INADDR_NONE
# define INADDR_NONE	0xffffffff
#endif /* INADDR_NONE */
#ifndef INADDR_BROADCAST
# define INADDR_BROADCAST	0xffffffff
#endif /* INADDR_BROADCAST */
#ifndef INADDR_LOOPBACK
# define INADDR_LOOPBACK         0x7F000001
#endif /* INADDR_LOOPBACK */

#ifndef HAS_INET_ATON

/*
 * Check whether "cp" is a valid ascii representation
 * of an Internet address and convert to a binary address.
 * Returns 1 if the address is valid, 0 if not.
 * This replaces inet_addr, the return value from which
 * cannot distinguish between failure and a local broadcast address.
 */
static int
my_inet_aton(register const char *cp, struct in_addr *addr)
{
    dTHX;
    register U32 val;
    register int base;
    register char c;
    int nparts;
    const char *s;
    unsigned int parts[4];
    register unsigned int *pp = parts;

    if (!cp || !*cp)
        return 0;
    for (;;) {
        /*
         * Collect number up to ``.''.
         * Values are specified as for C:
         * 0x=hex, 0=octal, other=decimal.
         */
        val = 0;
        base = 10;
        if (*cp == '0') {
            if (*++cp == 'x' || *cp == 'X')
                base = 16, cp++;
            else
                base = 8;
        }
        while ((c = *cp) != '\0') {
            if (isDIGIT(c)) {
                val = (val * base) + (c - '0');
                cp++;
                continue;
            }
            if (base == 16 && (s=strchr(PL_hexdigit,c))) {
                val = (val << 4) +
                      ((s - PL_hexdigit) & 15);
                cp++;
                continue;
            }
            break;
        }
        if (*cp == '.') {
            /*
             * Internet format:
             *	a.b.c.d
             *	a.b.c	(with c treated as 16-bits)
             *	a.b	(with b treated as 24 bits)
             */
            if (pp >= parts + 3 || val > 0xff)
                return 0;
            *pp++ = val, cp++;
        } else
            break;
    }
    /*
     * Check for trailing characters.
     */
    if (*cp && !isSPACE(*cp))
        return 0;
    /*
     * Concoct the address according to
     * the number of parts specified.
     */
    nparts = pp - parts + 1;	/* force to an int for switch() */
    switch (nparts) {

    case 1:				/* a -- 32 bits */
        break;

    case 2:				/* a.b -- 8.24 bits */
        if (val > 0xffffff)
            return 0;
        val |= parts[0] << 24;
        break;

    case 3:				/* a.b.c -- 8.8.16 bits */
        if (val > 0xffff)
            return 0;
        val |= (parts[0] << 24) | (parts[1] << 16);
        break;

    case 4:				/* a.b.c.d -- 8.8.8.8 bits */
        if (val > 0xff)
            return 0;
        val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
        break;
    }
    addr->s_addr = htonl(val);
    return 1;
}
Exemplo n.º 5
0
STATIC char *
S_skipspace(pTHX_ register char *s, int incline)
{
    if (PL_lex_formbrack && PL_lex_brackets <= PL_lex_formbrack) {
	while (s < PL_bufend && SPACE_OR_TAB(*s))
	    s++;
	return s;
    }
    for (;;) {
	STRLEN prevlen;
	SSize_t oldprevlen, oldoldprevlen;
	SSize_t oldloplen = 0, oldunilen = 0;
	while (s < PL_bufend && isSPACE(*s)) {
	    if (*s++ == '\n' && ((incline == 2) || (PL_in_eval && !PL_rsfp && !incline)))
		incline(s);
	}

	/* comment */
	if (s < PL_bufend && *s == '#') {
	    while (s < PL_bufend && *s != '\n')
		s++;
	    if (s < PL_bufend) {
		s++;
		if (PL_in_eval && !PL_rsfp && !incline) {
		    incline(s);
		    continue;
		}
	    }
	}

	/* also skip leading whitespace on the beginning of a line before deciding
	 * whether or not to recharge the linestr. --rafl
	 */
	while (s < PL_bufend && isSPACE(*s)) {
		if (*s++ == '\n' && PL_in_eval && !PL_rsfp && !incline)
			incline(s);
	}

	/* only continue to recharge the buffer if we're at the end
	 * of the buffer, we're not reading from a source filter, and
	 * we're in normal lexing mode
	 */
	if (s < PL_bufend || !PL_rsfp || PL_lex_inwhat ||
		PL_lex_state == LEX_FORMLINE)
	    return s;

	/* try to recharge the buffer */
	if ((s = filter_gets(PL_linestr, PL_rsfp,
			     (prevlen = SvCUR(PL_linestr)))) == Nullch)
	{
	    /* end of file.  Add on the -p or -n magic */
	    if (PL_minus_p) {
		sv_setpv(PL_linestr,
			 ";}continue{print or die qq(-p destination: $!\\n);}");
		PL_minus_n = PL_minus_p = 0;
	    }
	    else if (PL_minus_n) {
		sv_setpvn(PL_linestr, ";}", 2);
		PL_minus_n = 0;
	    }
	    else
		sv_setpvn(PL_linestr,";", 1);

	    /* reset variables for next time we lex */
	    PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = s = PL_linestart
		= SvPVX(PL_linestr);
	    PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
	    PL_last_lop = PL_last_uni = Nullch;

	    /* In perl versions previous to p4-rawid: //depot/perl@32954 -P
	     * preprocessors were supported here. We don't support -P at all, even
	     * on perls that support it, and use the following chunk from blead
	     * perl. (rafl)
	     */

	    /* Close the filehandle.  Could be from
	     * STDIN, or a regular file.  If we were reading code from
	     * STDIN (because the commandline held no -e or filename)
	     * then we don't close it, we reset it so the code can
	     * read from STDIN too.
	     */

	    if ((PerlIO*)PL_rsfp == PerlIO_stdin())
		PerlIO_clearerr(PL_rsfp);
	    else
		(void)PerlIO_close(PL_rsfp);
	    PL_rsfp = Nullfp;
	    return s;
	}

	/* not at end of file, so we only read another line */
	/* make corresponding updates to old pointers, for yyerror() */
	oldprevlen = PL_oldbufptr - PL_bufend;
	oldoldprevlen = PL_oldoldbufptr - PL_bufend;
	if (PL_last_uni)
	    oldunilen = PL_last_uni - PL_bufend;
	if (PL_last_lop)
	    oldloplen = PL_last_lop - PL_bufend;
	PL_linestart = PL_bufptr = s + prevlen;
	PL_bufend = s + SvCUR(PL_linestr);
	s = PL_bufptr;
	PL_oldbufptr = s + oldprevlen;
	PL_oldoldbufptr = s + oldoldprevlen;
	if (PL_last_uni)
	    PL_last_uni = s + oldunilen;
	if (PL_last_lop)
	    PL_last_lop = s + oldloplen;
	if (!incline)
		incline(s);

	/* debugger active and we're not compiling the debugger code,
	 * so store the line into the debugger's array of lines
	 */
	if (PERLDB_LINE && PL_curstash != PL_debstash) {
	    AV *fileav = CopFILEAV(PL_curcop);
	    if (fileav) {
		SV * const sv = NEWSV(85,0);
		sv_upgrade(sv, SVt_PVMG);
		sv_setpvn(sv,PL_bufptr,PL_bufend-PL_bufptr);
		(void)SvIOK_on(sv);
		SvIV_set(sv, 0);
		av_store(fileav,(I32)CopLINE(PL_curcop),sv);
	    }
	}
    }
}
Exemplo n.º 6
0
sar_bool sar_lookPathPos_c(sarNode_p currNode, const char * checkStr, long startPos, long currPos, long len, sar_bool negative) {
	sar_bool matched = SAR_FALSE;

	int callPos = 0;
    while(currNode->callFunc[callPos] != (SV*)NULL) {
    	matched = SAR_TRUE;
    	sar_runCallFunc_c(currNode->callFunc[callPos], startPos, currPos);
        ++callPos;
    }

    if (currPos >= len) {
    	return matched;
    }

    char checkChar = checkStr[currPos];

    sarNode_p plusNode = currNode->plusNode;
    if (plusNode != (sarNode_p)NULL) {
    	if (negative) {
        	int pathCharNum = 0;
        	for (pathCharNum=0; pathCharNum < plusNode->charNumber; ++pathCharNum) {
        		if (checkChar != plusNode->sarPathChars[pathCharNum]) {
    				sarNode_p nextPlusNode = plusNode->sarNodes[pathCharNum];
    				sar_bool plusNodesMatched = sar_matchPlusNode_c(nextPlusNode, checkStr, startPos, currPos, len, SAR_CHAR, negative);
    				matched = matched || plusNodesMatched;
        		}
        	}

	    	if (plusNode->digitNode != (sarNode_p)NULL) {
	    		if (! isDIGIT(checkChar)) {
	        		sarNode_p nextPlusNode = plusNode->digitNode;
	        		sar_bool plusNodesMatched = sar_matchPlusNode_c(nextPlusNode, checkStr, startPos, currPos, len, SAR_DIGIT, negative);
	        		matched = matched || plusNodesMatched;
	    		}
	    	}

    	}
    	else {
    		int existListPlusNodePos = sar_searchChar_c(plusNode->sarPathChars, plusNode->charNumber, checkChar);
			if (existListPlusNodePos >= 0) {
				sarNode_p nextPlusNode = plusNode->sarNodes[existListPlusNodePos];
				sar_bool plusNodesMatched = sar_matchPlusNode_c(nextPlusNode, checkStr, startPos, currPos, len, SAR_CHAR, negative);
				matched = matched || plusNodesMatched;
			}

	    	if (plusNode->dotNode != (sarNode_p)NULL) {
	       		sarNode_p nextPlusNode = plusNode->dotNode;
	       		sar_bool plusNodesMatched = sar_matchPlusNode_c(nextPlusNode, checkStr, startPos, currPos, len, SAR_DOT, negative);
	       		matched = matched || plusNodesMatched;
	    	}
	    	if (plusNode->digitNode != (sarNode_p)NULL) {
	    		if (isDIGIT(checkChar)) {
	        		sarNode_p nextPlusNode = plusNode->digitNode;
	        		sar_bool plusNodesMatched = sar_matchPlusNode_c(nextPlusNode, checkStr, startPos, currPos, len, SAR_DIGIT, negative);
	        		matched = matched || plusNodesMatched;
	    		}
	    	}
	    	if (plusNode->alphaNumNode != (sarNode_p)NULL) {
	    		if (isALNUM(checkChar)) {
	        		sarNode_p nextPlusNode = plusNode->alphaNumNode;
	        		sar_bool plusNodesMatched = sar_matchPlusNode_c(nextPlusNode, checkStr, startPos, currPos, len, SAR_ALPHA_NUM, negative);
	        		matched = matched || plusNodesMatched;
	    		}
	    	}
	    	if (plusNode->alphaNode != (sarNode_p)NULL) {
	    		if (isALPHA(checkChar)) {
	        		sarNode_p nextPlusNode = plusNode->alphaNode;
	        		sar_bool plusNodesMatched = sar_matchPlusNode_c(nextPlusNode, checkStr, startPos, currPos, len, SAR_ALPHA, negative);
	        		matched = matched || plusNodesMatched;
	    		}
	    	}
	    	if (plusNode->spaceNode != (sarNode_p)NULL) {
	    		if (isSPACE(checkChar)) {
	        		sarNode_p nextPlusNode = plusNode->spaceNode;
	        		sar_bool plusNodesMatched = sar_matchPlusNode_c(nextPlusNode, checkStr, startPos, currPos, len, SAR_SPACE, negative);
	        		matched = matched || plusNodesMatched;
	    		}
	    	}

    	}
    }

    if (negative) {
    	int pathCharNum = 0;
    	for (pathCharNum=0; pathCharNum < currNode->charNumber; ++pathCharNum) {
    		if (checkChar != currNode->sarPathChars[pathCharNum]) {
    			sar_bool nodesMatched = sar_lookPathPos_c(currNode->sarNodes[pathCharNum], checkStr, startPos, currPos + 1, len, SAR_FALSE);
    			matched = matched || nodesMatched;
    		}
    	}

		if (currNode->spaceNode != (sarNode_p)NULL) {
			if (! isSPACE(checkChar)) {
				sar_bool nodesMatched = sar_lookPathPos_c(currNode->spaceNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
				matched = matched || nodesMatched;
			}
		}
		if (currNode->digitNode != (sarNode_p)NULL) {
			if (! isDIGIT(checkChar)) {
				sar_bool nodesMatched = sar_lookPathPos_c(currNode->digitNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
				matched = matched || nodesMatched;
			}
		}
		if (currNode->alphaNumNode != (sarNode_p)NULL) {
			if (! isALNUM(checkChar)) {
				sar_bool nodesMatched = sar_lookPathPos_c(currNode->alphaNumNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
				matched = matched || nodesMatched;
			}
		}
		if (currNode->alphaNode != (sarNode_p)NULL) {
			if (! isALPHA(checkChar)) {
				sar_bool nodesMatched = sar_lookPathPos_c(currNode->alphaNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
				matched = matched || nodesMatched;
			}
		}

    }
    else {
		int existListNodePos = sar_searchChar_c(currNode->sarPathChars, currNode->charNumber, checkChar);
		if (existListNodePos >= 0) {
			sar_bool nodesMatched = sar_lookPathPos_c(currNode->sarNodes[existListNodePos], checkStr, startPos, currPos + 1, len, SAR_FALSE);
			matched = matched || nodesMatched;
		}

		if (currNode->negativeNode != (sarNode_p)NULL) {
			sar_bool nodesMatched = sar_lookPathPos_c(currNode->negativeNode, checkStr, startPos, currPos, len, SAR_TRUE);
			matched = matched || nodesMatched;
		}

		if (currNode->dotNode != (sarNode_p)NULL) {
			sar_bool nodesMatched = sar_lookPathPos_c(currNode->dotNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
			matched = matched || nodesMatched;
		}
		if (currNode->spaceNode != (sarNode_p)NULL) {
			if (isSPACE(checkChar)) {
				sar_bool nodesMatched = sar_lookPathPos_c(currNode->spaceNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
				matched = matched || nodesMatched;
			}
		}
		if (currNode->digitNode != (sarNode_p)NULL) {
			if (isDIGIT(checkChar)) {
				sar_bool nodesMatched = sar_lookPathPos_c(currNode->digitNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
				matched = matched || nodesMatched;
			}
		}
		if (currNode->alphaNumNode != (sarNode_p)NULL) {
			if (isALNUM(checkChar)) {
				sar_bool nodesMatched = sar_lookPathPos_c(currNode->alphaNumNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
				matched = matched || nodesMatched;
			}
		}
		if (currNode->alphaNode != (sarNode_p)NULL) {
			if (isALPHA(checkChar)) {
				sar_bool nodesMatched = sar_lookPathPos_c(currNode->alphaNode, checkStr, startPos, currPos + 1, len, SAR_FALSE);
				matched = matched || nodesMatched;
			}
		}

    }

    return matched;
}
Exemplo n.º 7
0
/* maps to mod_mime_magic::parse */
static int
fmm_parse_magic_line(PerlFMM *state, char *l, int lineno)
{
    char    *t;
    char    *s;
    fmmagic *m;
    SV *err;

    Newz(1234, m, 1, fmmagic);
    m->next       = NULL;
    m->flag       = 0;
    m->cont_level = 0;
    m->lineno     = lineno;

    if (! state->magic || !state->last) {
        state->magic = state->last = m;
    } else {
        state->last->next = m;
        state->last        = m;
    }
        
    while (*l == '>') {
        l++; /* step over */
        m->cont_level++;
    }

    if (m->cont_level  != 0 && *l == '(') {
        l++; /* step over */
        m->flag |= INDIR;
    }

    /* get offset, then skip over it */
    m->offset = (int) strtol(l, &t, 0);
    if (l == t) {
        err = newSVpvf("Invalid offset in mime magic file, line %d: %s", lineno, l);
        goto error;
    }

    l = t;

    if (m->flag & INDIR) {
        m->in.type = LONG;
        m->in.offset = 0;
        /* read [.lbs][+=]nnnnn) */
        if (*l == '.') {
            switch (*++l) {
                case 'l':
                    m->in.type = LONG;
                    break;
                case 's':
                    m->in.type = SHORT;
                    break;
                case 'b':
                    m->in.type = BYTE;
                    break;
                default:
                    err = newSVpvf(
                        "Invalid indirect offset type in mime magic file, line %d: %c", lineno, *l);
                    goto error;
            }
            l++;
        }
        s = l;
        if (*l == '+' || *l == '-') {
            l++;
        }
        if (isdigit((unsigned char) *l)) {
            m->in.offset = strtol(l, &t, 0);
            if (*s == '-') {
                m->in.offset = -(m->in.offset);
            }
        } else {
            t = l;
        }
        if (*t++ != ')') {
            err = newSVpvf(
                "Missing ')' in indirect offset in mime magic file, line %d", lineno);
            goto error;
        }
        l = t;
    } 

    while (isdigit((unsigned char) *l)) {
        ++l;
    }
    EATAB(l);

#define NBYTE           4
#define NSHORT          5
#define NLONG           4
#define NSTRING         6
#define NDATE           4
#define NBESHORT        7
#define NBELONG         6
#define NBEDATE         6
#define NLESHORT        7
#define NLELONG         6
#define NLEDATE         6

    if (*l == 'u') {
    ++l;
    m->flag |= UNSIGNED;
    }

    /* get type, skip it */
    if (strncmp(l, "byte", NBYTE) == 0) {
        m->type = BYTE;
        l += NBYTE;
    }
    else if (strncmp(l, "short", NSHORT) == 0) {
        m->type = SHORT;
        l += NSHORT;
    }
    else if (strncmp(l, "long", NLONG) == 0) {
        m->type = LONG;
        l += NLONG;
    }
    else if (strncmp(l, "string", NSTRING) == 0) {
        m->type = STRING;
        l += NSTRING;
    }
    else if (strncmp(l, "date", NDATE) == 0) {
        m->type = DATE;
        l += NDATE;
    }
    else if (strncmp(l, "beshort", NBESHORT) == 0) {
        m->type = BESHORT;
        l += NBESHORT;
    }
    else if (strncmp(l, "belong", NBELONG) == 0) {
        m->type = BELONG;
        l += NBELONG;
    }
    else if (strncmp(l, "bedate", NBEDATE) == 0) {
        m->type = BEDATE;
        l += NBEDATE;
    }
    else if (strncmp(l, "leshort", NLESHORT) == 0) {
        m->type = LESHORT;
        l += NLESHORT;
    }
    else if (strncmp(l, "lelong", NLELONG) == 0) {
        m->type = LELONG;
        l += NLELONG;
    }
    else if (strncmp(l, "ledate", NLEDATE) == 0) {
        m->type = LEDATE;
        l += NLEDATE;
    }
    else {
        err = newSVpvf("Invalid type in mime magic file, line %d: %s", lineno, l);
        goto error;
    }
    /* New-style anding: "0 byte&0x80 =0x80 dynamically linked" */
    if (*l == '&') {
        ++l;
        m->mask = fmm_signextend(state, m, strtol(l, &l, 0));
    }
    else {
        m->mask = ~0L;
    }
    EATAB(l);

    switch (*l) {
    case '>':
    case '<':
    /* Old-style anding: "0 byte &0x80 dynamically linked" */
    case '&':
    case '^':
    case '=':
        m->reln = *l;
        ++l;
        break;
    case '!':
        if (m->type != STRING) {
            m->reln = *l;
            ++l;
            break;
        }
        /* FALL THROUGH */
    default:
        if (*l == 'x' && isSPACE(l[1])) {
            m->reln = *l;
            ++l;
            goto GetDesc;   /* Bill The Cat */
        }
        m->reln = '=';
        break;
    }
    EATAB(l);
    
    if (fmm_getvalue(state, m, &l))
        return -1;

    /*
     * now get last part - the description
     */
GetDesc:
    EATAB(l);
    if (l[0] == '\b') {
        ++l;
        m->nospflag = 1;
    }
    else if ((l[0] == '\\') && (l[1] == 'b')) {
        ++l;
        ++l;
        m->nospflag = 1;
    }
    else {
        m->nospflag = 0;
    }
    strncpy(m->desc, l, sizeof(m->desc) - 1);
    m->desc[sizeof(m->desc) - 1] = '\0';

    return 0;

 error:
    FMM_SET_ERROR(state, err);
    croak(SvPV_nolen(err));
}
Exemplo n.º 8
0
/*
 * Convert a string containing C character escapes.  Stop at an unescaped
 * space or tab. Copy the converted version to "p", returning its length in
 * *slen. Return updated scan pointer as function result.
 */
static char *
fmm_getstr(PerlFMM *state, register char *s, register char *p, int plen, int *slen)
{
    char *origs = s, *origp = p;
    char *pmax = p + plen - 1;
    register int c;
    register int val;
    SV *err;

    while ((c = *s++) != '\0') {
    if (isSPACE(c))
        break;
    if (p >= pmax) {
        err = newSVpvf(
            "fmm_getstr: string too long: %s", origs);
        FMM_SET_ERROR(state, err);
        break;
    }
    if (c == '\\') {
        switch (c = *s++) {

        case '\0':
        goto out;

        default:
        *p++ = (char) c;
        break;

        case 'n':
        *p++ = '\n';
        break;

        case 'r':
        *p++ = '\r';
        break;

        case 'b':
        *p++ = '\b';
        break;

        case 't':
        *p++ = '\t';
        break;

        
        case 'f':
        *p++ = '\f';
        break;
        
        case 'v':
        *p++ = '\v';
        break;
        
        /* \ and up to 3 octal digits */
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7': 
        val = c - '0'; 
        c = *s++;   /* try for 2 */
        if (c >= '0' && c <= '7') { 
            val = (val << 3) | (c - '0');
            c = *s++;   /* try for 3 */
            if (c >= '0' && c <= '7')
            val = (val << 3) | (c - '0');
            else
            --s;
        }
        else
            --s;
        *p++ = (char) val;
        break;
        
        /* \x and up to 3 hex digits */
        case 'x':
        val = 'x';  /* Default if no digits */
        c = fmm_hextoint(*s++); /* Get next char */
        if (c >= 0) {
            val = c;
            c = fmm_hextoint(*s++);
            if (c >= 0) { 
            val = (val << 4) + c;
            c = fmm_hextoint(*s++);
            if (c >= 0) {
                val = (val << 4) + c;
            }
            else
                --s;
            }
            else
            --s;
        }
        else
            --s;
        *p++ = (char) val;
        break;
        }
    }
    else
        *p++ = (char) c;
    }
  out:
    *p = '\0';
    *slen = p - origp;
    return s;
}
Exemplo n.º 9
0
static int
fmm_ascmagic(unsigned char *buf, size_t nbytes, char **mime_type)
{
    int has_escapes = 0;
    unsigned char *s;
    char nbuf[HOWMANY + 1]; /* one extra for terminating '\0' */
    char *token;
    register struct names *p;
    int small_nbytes;
    char *strtok_state;
    unsigned char *tp;

    /* these are easy, do them first */

    /*
     * for troff, look for . + letter + letter or .\"; this must be done to
     * disambiguate tar archives' ./file and other trash from real troff
     * input.
     */
    if (*buf == '.') {
        tp = buf + 1;
        while (isSPACE(*tp))
            ++tp;       /* skip leading whitespace */
        if ((isALNUM(*tp) || *tp == '\\') && (isALNUM(*(tp + 1)) || *tp == '"')) {
            strcpy(*mime_type, "application/x-troff");
            return 0;
        }
    }

    if ((*buf == 'c' || *buf == 'C') && isSPACE(*(buf + 1))) {
        /* Fortran */
        strcpy(*mime_type, "text/plain");
        return 0;
    }

    /* look for tokens from names.h - this is expensive!, so we'll limit
     * ourselves to only SMALL_HOWMANY bytes */
    small_nbytes = (nbytes > SMALL_HOWMANY) ? SMALL_HOWMANY : nbytes;

    /* make a copy of the buffer here because strtok() will destroy it */
    s = (unsigned char *) memcpy(nbuf, buf, small_nbytes);
    s[small_nbytes] = '\0';
    has_escapes = (memchr(s, '\033', small_nbytes) != NULL);
    while ((token = strtok_r((char *) s, " \t\n\r\f", &strtok_state)) != NULL) {
        s = NULL;       /* make strtok() keep on tokin' */
        for (p = names; p < names + NNAMES; p++) {
            if (strEQ(p->name, token)) {
                strcpy(*mime_type, types[p->type]);
                if (has_escapes)
                    strcat(*mime_type, " (with escape sequences)");
                return 0;
            }
        }
    }

    int is_tarball = is_tar(buf, nbytes);
    if ( is_tarball == 1 || is_tarball == 2 ) {
        /* 1: V7 tar archive */
        /* 2: POSIX tar archive */
        strcpy(*mime_type, "application/x-tar");
        return 0;
    }

    /* all else fails, but it is ascii... */
    strcpy(*mime_type, "text/plain");
    return 0;
}