HRESULT CDXVADecoderMpeg2::DecodeFrame (BYTE* pDataIn, UINT nSize, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop)
{
	TRACE_MPEG2 ("CDXVADecoderMpeg2::DecodeFrame() : %d\n", nSize);

	AppendBuffer (pDataIn, nSize, rtStart, rtStop);
	HRESULT hr = S_OK;

	while (FindPicture (max (m_nMPEG2BufferPos-int(nSize)-4, 0), 0x00)) {
		if (m_MPEG2BufferTime[0].nBuffPos != INT_MIN && m_MPEG2BufferTime[0].nBuffPos < m_nMPEG2PicEnd) {
			rtStart = m_MPEG2BufferTime[0].rtStart;
			rtStop  = m_MPEG2BufferTime[0].rtStop;
		} else {
			rtStart = rtStop = INVALID_TIME;
		}

		hr = DecodeFrameInternal (m_pMPEG2Buffer, m_nMPEG2PicEnd, rtStart, rtStop);
		ShrinkBuffer();
	}

	return hr;
}
Esempio n. 2
0
USHORT NEAR delete_share(TCHAR * name)
{
    USHORT          err;                /* API return status */
    TCHAR FAR *      pBuffer;
    USHORT2ULONG    num_read;           /* num entries read by API */
    USHORT          num_prtq;           /* num entries read by API */
    USHORT2ULONG    i;
    USHORT          total_open = 0;
    USHORT          available;          /* num entries available */

    struct share_info_2 FAR * share_entry;
    struct connection_info_1 FAR * conn_entry;

//--< MSKK IsaoA 05/08/91 >----------------------------------------------------
    PRQINFO far * q_ptr;
    PRJINFO far * job_ptr;
    int     uses;
    unsigned short  num_jobs;
//--< MSKK Done >--------------------------------------------------------------

    /*
     * MAINTENANCE NOTE: While doing maintenance for bug fix 1800, it was
     * noticed that this function uses BigBuf, and so does the function
     * that calls this function (share_del()).  In the current implementation,
     * this is not a problem because of the api calling pattern.  However, the
     * slightest change could break this function, or share_del(), so beware!
     * Bug fix 1800 was directly ported from the MSKK code. The api calls in
     * this function and in share_del() are incredibly redundant, but I left it
     * as is rather than risking breaking it. - RobDu
     */

    if (err = MNetShareGetInfo(NULL,
                               name,
                               2,
                               (LPBYTE*)&pBuffer))
    {
	return err;
    }

    share_entry = (struct share_info_2 FAR *) pBuffer;

//--< MSKK IsaoA 05/08/91 >----------------------------------------------------
// not delete share during spooling
    uses = share_entry->shi2_current_uses;

#if defined(NTENV)
    share_entry->shi2_type &= ~STYPE_SPECIAL;
#endif
    if (share_entry->shi2_type == STYPE_PRINTQ)
    {

    //
    // The cast (USHORT2ULONG FAR *) is because all the Lan api's that are
    // called via the ApiEnumerator... function take pointers to DWORDs while
    // the DosPrint api take pointers to WORDs.  Since these are just being
    // passed thru the ApiEnum.. api as pointers, no harm is done.
    //

        if(err = ApiEnumerator((EnumType)DosPrintQEnum,
                               NULL,
                               2,
          (USHORT2ULONG FAR *) &num_prtq,
          (USHORT2ULONG FAR *) &available))
            ErrorExit (err);
        q_ptr = (PRQINFO far * ) BigBuf;
        while (num_prtq--)
        {
            job_ptr = (PRJINFO far *)(q_ptr + 1);
            num_jobs = q_ptr->cJobs;
            if(job_ptr->fsStatus & PRJ_QS_SPOOLING)
                ErrorExit (APE_ShareSpooling);
            q_ptr = (PRQINFO far *)(job_ptr + num_jobs);
        }
    }

    if (uses)
//  if (share_entry->shi2_current_uses)
//--< MSKK Done >--------------------------------------------------------------
    {
        NetApiBufferFree(pBuffer);
        if (err = MNetConnectionEnum(
                                     NULL,
                                     name,
                                     1,
                                     (LPBYTE*)&pBuffer,
                                     &num_read))
            ErrorExit (err);

        for (i = 0, conn_entry = (struct connection_info_1 FAR *) pBuffer;
            i < num_read; i++, conn_entry++)
            total_open += (USHORT)conn_entry->coni1_num_opens;
        ShrinkBuffer();

        if (total_open)
        {
            InfoPrintInsTxt(APE_ShareOpens, name);

            if (!YorN(APE_ProceedWOp, 0))
                NetcmdExit(2);
        }
    }

    if (err = MNetShareDel(NULL, name, 0))
        ErrorExit(err);

    InfoPrintInsTxt(APE_DelSuccess, name);
    return NERR_Success;
    NetApiBufferFree(pBuffer);
}
Esempio n. 3
0
/***
 *  share_del()
 *      Delete a share
 *
 *  Args:
 *      name - share to delete
 *
 *  Returns:
 *      nothing - success
 *      exit(1) - command completed with errors
 *      exit(2) - command failed
 */
VOID share_del(TCHAR * name)
{
    USHORT                  err;                /* API return status */
    USHORT2ULONG            err2;               /* API return status */
    TCHAR FAR *              pEnumBuffer;
    USHORT                  last_err;
    USHORT2ULONG            err_cnt = 0;
    USHORT2ULONG            num_read;           /* num entries read by API */
    USHORT2ULONG            i;
    ULONG                   LongType;
    USHORT2ULONG            type;
    int                     found;
    TCHAR                    share[NNLEN+1];

    struct share_info_2 FAR * share_entry;
#ifndef NTENV
    PRQINFO FAR *           print_entry;
    USHORT2ULONG            available;          /* num entries available */
    TCHAR FAR *              pGetInfoBuffer;
#endif

    /*
     * MAINTENANCE NOTE: While doing maintenance for bug fix 1800, it was
     * noticed that this function uses BigBuf, and so does the function
     * delete_share() which is called by this function.  In the current
     * implementation this is not a problem, because of the api calling
     * pattern. However, the slightest change could break this function, or
     * delete_share(), so beware!  Bug fix 1800 was directly ported from
     * the MSKK code. The api calls in this function and in share_del() are
     * incredibly redundant, but I left it as is rather than risk breaking
     * it. - RobDu
     */

    err = delete_share(name);  /* check for Open files, and delete share */

    switch (err)
    {
    case NERR_Success:
        return;

    case NERR_NetNameNotFound:
        /*
         * the name was not found, so we try deleting the sticky entry
         * in registry.
         */
        err = MNetShareDelSticky(NULL, name, 0) ;
        if (err == NERR_Success)
        {
            InfoPrintInsTxt(APE_DelStickySuccess, name);
            return ;
        }
        else if (err == NERR_NetNameNotFound)
            break;
        else
            ErrorExit(err);

    default:
        ErrorExit(err);
    }

/***
 *  Only get here if "share" that user asked us to delete was
 *  NOT a share name.  Could be a disk path, or a com or lpt
 *  device
 */
    if (err2 = I_MNetPathType(NULL, name, &LongType, 0L))
        ErrorExit((USHORT) err2);

    if (LongType == ITYPE_PATH_ABSD)
        type = STYPE_DISKTREE;
    else
    {
        if ((LongType & ITYPE_DEVICE) == 0)
            ErrorExit( NERR_NetNameNotFound);
        else
        {
            if (err = MNetShareCheck(NULL, name, &type))
                ErrorExit(err);
        }
    }

    found = FALSE;

    switch (type)
    {
    case STYPE_DISKTREE:
        if (err = MNetShareEnum(NULL,
                                2,
                                (LPBYTE*)&pEnumBuffer,
                                &num_read))
            ErrorExit(err);

        for (i = 0, share_entry = (struct share_info_2 FAR *) pEnumBuffer;
             i < num_read; i++, share_entry++)
        {
            if (! stricmpf(share_entry->shi2_path, name))
            {
                found = TRUE;
                _tcscpy(share, share_entry->shi2_netname);
                ShrinkBuffer();

                if (err = delete_share(share))
                {
                    last_err = err;
                    err_cnt++;
                    InfoPrintInsTxt(APE_ShareErrDeleting, share);
                }
            }
        }
        NetApiBufferFree(pEnumBuffer);

        break;

    //
    // NT does not support Net Share of a printer/comm port via the net cmd
    //

#ifndef NTENV

    case STYPE_PRINTQ:
        if (err = ApiEnumerator(DosPrintQEnum,
                                NULL,
                                1,
                                &num_read,
                                &available))
            ErrorExit(err);

        for (i = 0, print_entry = (struct PRINTQ FAR *) BigBuf;
            i < num_read; i++, print_entry++)
        {
            if (IsMember(name, print_entry->pszDestinations))
            {
                _tcscpy(share, print_entry->szName);
                if (MNetShareGetInfo(NULL,
                                     share,
                                     0,
                                     &pGetInfoBuffer))
                    continue;

                NetApiBufferFree(pGetInfoBuffer);
                ShrinkBuffer();
                found = TRUE;
                if (err = delete_share(share))
                {
                    last_err = err;
                    err_cnt++;
                    InfoPrintInsTxt(APE_ShareErrDeleting, share);
                }
            }
        }
        NetApiBufferFree(pEnumBuffer);
        break;


    case STYPE_DEVICE:
        if (err = MNetCharDevQEnum(NULL,
                                   NULL,
                                   1,
                                   &pEnumBuffer,
                                   &num_read))
            ErrorExit(err);

        for (i = 0, char_entry = (struct chardevQ_info_1 FAR *)
             pEnumBuffer;
             i < num_read; i++, char_entry++)
        {
            if (IsMember(name, char_entry->cq1_devs))
            {
                found = TRUE;
                _tcscpy(share, char_entry->cq1_dev);
                ShrinkBuffer();
                if (err = delete_share(share))
                {
                    last_err = err;
                    err_cnt++;
                    InfoPrintInsTxt(APE_ShareErrDeleting, share);
                }
            }
        }
        NetApiBufferFree(pEnumBuffer);
        break;

#endif /* not NTENV */

    default:
        ErrorExit(ERROR_INVALID_PARAMETER) ;

    } /* switch */


/***
 *  Bye, bye
 */

    if ((err_cnt) && (err_cnt == num_read))
        ErrorExit(last_err);
    else if (err_cnt)
    {
        InfoPrint(APE_CmdComplWErrors);
        NetcmdExit(1);
    }
    else if (! found)
        ErrorExit(APE_ShareNotFound);

    InfoPrintInsTxt(APE_DelSuccess, name);
}
/*
 * Form update packets.
 * Returns the size of the resulting packet if no error
 * On error,
 *	returns -1 if error in reading a word/number in rdata
 *		   portion for update packets
 *		-2 if length of buffer passed is insufficient
 *		-3 if zone section is not the first section in
 *		   the linked list, or section order has a problem
 *		-4 on a number overflow
 *		-5 unknown operation or no records
 */
int
res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
	ns_updrec *rrecp_start = rrecp_in;
	HEADER *hp;
	u_char *cp, *sp1, *sp2, *startp, *endp;
	int n, i, soanum, multiline;
	ns_updrec *rrecp;
	struct in_addr ina;
        char buf2[MAXDNAME];
	int section, numrrs = 0, counts[ns_s_max];
	u_int16_t rtype, rclass;
	u_int32_t n1, rttl;
	u_char *dnptrs[20], **dpp, **lastdnptr;

	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
		h_errno = NETDB_INTERNAL;
		return (-1);
	}

	/*
	 * Initialize header fields.
	 */
	if ((buf == NULL) || (buflen < HFIXEDSZ))
		return (-1);
	memset(buf, 0, HFIXEDSZ);
	hp = (HEADER *) buf;
	hp->id = htons(++_res.id);
	hp->opcode = ns_o_update;
	hp->rcode = NOERROR;
	sp1 = buf + 2*INT16SZ;  /* save pointer to zocount */
	cp = buf + HFIXEDSZ;
	buflen -= HFIXEDSZ;
	dpp = dnptrs;
	*dpp++ = buf;
	*dpp++ = NULL;
	lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];

	if (rrecp_start == NULL)
		return (-5);
	else if (rrecp_start->r_section != S_ZONE)
		return (-3);

	memset(counts, 0, sizeof counts);
	for (rrecp = rrecp_start; rrecp; rrecp = rrecp->r_grpnext) {
		numrrs++;
                section = rrecp->r_section;
		if (section < 0 || section >= ns_s_max)
			return (-1);
		counts[section]++;
		for (i = section + 1; i < ns_s_max; i++)
			if (counts[i])
				return (-3);
		rtype = rrecp->r_type;
		rclass = rrecp->r_class;
		rttl = rrecp->r_ttl;
		/* overload class and type */
		if (section == S_PREREQ) {
			rttl = 0;
			switch (rrecp->r_opcode) {
			case YXDOMAIN:
				rclass = C_ANY;
				rtype = T_ANY;
				rrecp->r_size = 0;
				break;
			case NXDOMAIN:
				rclass = C_NONE;
				rtype = T_ANY;
				rrecp->r_size = 0;
				break;
			case NXRRSET:
				rclass = C_NONE;
				rrecp->r_size = 0;
				break;
			case YXRRSET:
				if (rrecp->r_size == 0)
					rclass = C_ANY;
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		} else if (section == S_UPDATE) {
			switch (rrecp->r_opcode) {
			case DELETE:
				rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
				break;
			case ADD:
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		}

		/*
		 * XXX	appending default domain to owner name is omitted,
		 *	fqdn must be provided
		 */
		if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
				 lastdnptr)) < 0)
			return (-1);
		cp += n;
		ShrinkBuffer(n + 2*INT16SZ);
		PUTSHORT(rtype, cp);
		PUTSHORT(rclass, cp);
		if (section == S_ZONE) {
			if (numrrs != 1 || rrecp->r_type != T_SOA)
				return (-3);
			continue;
		}
		ShrinkBuffer(INT32SZ + INT16SZ);
		PUTLONG(rttl, cp);
		sp2 = cp;  /* save pointer to length byte */
		cp += INT16SZ;
		if (rrecp->r_size == 0) {
			if (section == S_UPDATE && rclass != C_ANY)
				return (-1);
			else {
				PUTSHORT(0, sp2);
				continue;
			}
		}
		startp = rrecp->r_data;
		endp = startp + rrecp->r_size - 1;
		/* XXX this should be done centrally. */
		switch (rrecp->r_type) {
		case T_A:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(INT32SZ);
			PUTLONG(n1, cp);
			break;
		case T_CNAME:
		case T_MB:
		case T_MG:
		case T_MR:
		case T_NS:
		case T_PTR:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_MINFO:
		case T_SOA:
		case T_RP:
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
				return (-1);
				n = dn_comp(buf2, cp, buflen,
					    dnptrs, lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			if (rrecp->r_type == T_SOA) {
				ShrinkBuffer(5 * INT32SZ);
				while (isspace(*startp) || !*startp)
					startp++;
				if (*startp == '(') {
					multiline = 1;
					startp++;
				} else
					multiline = 0;
				/* serial, refresh, retry, expire, minimum */
				for (i = 0; i < 5; i++) {
					soanum = getnum_str(&startp, endp);
					if (soanum < 0)
						return (-1);
					PUTLONG(soanum, cp);
				}
				if (multiline) {
					while (isspace(*startp) || !*startp)
						startp++;
					if (*startp != ')')
						return (-1);
				}
			}
			break;
		case T_MX:
		case T_AFSDB:
		case T_RT:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			PUTSHORT(n, cp);
			ShrinkBuffer(INT16SZ);
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_PX:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			PUTSHORT(n, cp);
			ShrinkBuffer(INT16SZ);
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				n = dn_comp(buf2, cp, buflen, dnptrs,
					    lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			break;
		case T_WKS:
		case T_HINFO:
		case T_TXT:
		case T_X25:
		case T_ISDN:
		case T_NSAP:
		case T_LOC:
			/* XXX - more fine tuning needed here */
			ShrinkBuffer(rrecp->r_size);
			memcpy(cp, rrecp->r_data, rrecp->r_size);
			cp += rrecp->r_size;
			break;
		default:
			return (-1);
		} /*switch*/
		n = (u_int16_t)((cp - sp2) - INT16SZ);
		PUTSHORT(n, sp2);
	} /*for*/
		
	hp->qdcount = htons(counts[0]);
	hp->ancount = htons(counts[1]);
	hp->nscount = htons(counts[2]);
	hp->arcount = htons(counts[3]);
	return (cp - buf);
}
Esempio n. 5
0
/*%
 * Form update packets.
 * Returns the size of the resulting packet if no error
 *
 * On error,
 *	returns 
 *\li              -1 if error in reading a word/number in rdata
 *		   portion for update packets
 *\li		-2 if length of buffer passed is insufficient
 *\li		-3 if zone section is not the first section in
 *		   the linked list, or section order has a problem
 *\li		-4 on a number overflow
 *\li		-5 unknown operation or no records
 */
int
res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) {
	ns_updrec *rrecp_start = rrecp_in;
	HEADER *hp;
	u_char *cp, *sp2, *startp, *endp;
	int n, i, soanum, multiline;
	ns_updrec *rrecp;
	struct in_addr ina;
	struct in6_addr in6a;
        char buf2[MAXDNAME];
	u_char buf3[MAXDNAME];
	int section, numrrs = 0, counts[ns_s_max];
	u_int16_t rtype, rclass;
	u_int32_t n1, rttl;
	u_char *dnptrs[20], **dpp, **lastdnptr;
	int siglen, keylen, certlen;

	/*
	 * Initialize header fields.
	 */
	if ((buf == NULL) || (buflen < HFIXEDSZ))
		return (-1);
	memset(buf, 0, HFIXEDSZ);
	hp = (HEADER *) buf;
	hp->id = htons(++statp->id);
	hp->opcode = ns_o_update;
	hp->rcode = NOERROR;
	cp = buf + HFIXEDSZ;
	buflen -= HFIXEDSZ;
	dpp = dnptrs;
	*dpp++ = buf;
	*dpp++ = NULL;
	lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];

	if (rrecp_start == NULL)
		return (-5);
	else if (rrecp_start->r_section != S_ZONE)
		return (-3);

	memset(counts, 0, sizeof counts);
	for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) {
		numrrs++;
                section = rrecp->r_section;
		if (section < 0 || section >= ns_s_max)
			return (-1);
		counts[section]++;
		for (i = section + 1; i < ns_s_max; i++)
			if (counts[i])
				return (-3);
		rtype = rrecp->r_type;
		rclass = rrecp->r_class;
		rttl = rrecp->r_ttl;
		/* overload class and type */
		if (section == S_PREREQ) {
			rttl = 0;
			switch (rrecp->r_opcode) {
			case YXDOMAIN:
				rclass = C_ANY;
				rtype = T_ANY;
				rrecp->r_size = 0;
				break;
			case NXDOMAIN:
				rclass = C_NONE;
				rtype = T_ANY;
				rrecp->r_size = 0;
				break;
			case NXRRSET:
				rclass = C_NONE;
				rrecp->r_size = 0;
				break;
			case YXRRSET:
				if (rrecp->r_size == 0)
					rclass = C_ANY;
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		} else if (section == S_UPDATE) {
			switch (rrecp->r_opcode) {
			case DELETE:
				rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
				break;
			case ADD:
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		}

		/*
		 * XXX	appending default domain to owner name is omitted,
		 *	fqdn must be provided
		 */
		if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
				 lastdnptr)) < 0)
			return (-1);
		cp += n;
		ShrinkBuffer(n + 2*INT16SZ);
		PUTSHORT(rtype, cp);
		PUTSHORT(rclass, cp);
		if (section == S_ZONE) {
			if (numrrs != 1 || rrecp->r_type != T_SOA)
				return (-3);
			continue;
		}
		ShrinkBuffer(INT32SZ + INT16SZ);
		PUTLONG(rttl, cp);
		sp2 = cp;  /*%< save pointer to length byte */
		cp += INT16SZ;
		if (rrecp->r_size == 0) {
			if (section == S_UPDATE && rclass != C_ANY)
				return (-1);
			else {
				PUTSHORT(0, sp2);
				continue;
			}
		}
		startp = rrecp->r_data;
		endp = startp + rrecp->r_size - 1;
		/* XXX this should be done centrally. */
		switch (rrecp->r_type) {
		case T_A:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(INT32SZ);
			PUTLONG(n1, cp);
			break;
		case T_CNAME:
		case T_MB:
		case T_MG:
		case T_MR:
		case T_NS:
		case T_PTR:
		case ns_t_dname:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_MINFO:
		case T_SOA:
		case T_RP:
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
				return (-1);
				n = dn_comp(buf2, cp, buflen,
					    dnptrs, lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			if (rrecp->r_type == T_SOA) {
				ShrinkBuffer(5 * INT32SZ);
				while (isspace(*startp) || !*startp)
					startp++;
				if (*startp == '(') {
					multiline = 1;
					startp++;
				} else
					multiline = 0;
				/* serial, refresh, retry, expire, minimum */
				for (i = 0; i < 5; i++) {
					soanum = getnum_str(&startp, endp);
					if (soanum < 0)
						return (-1);
					PUTLONG(soanum, cp);
				}
				if (multiline) {
					while (isspace(*startp) || !*startp)
						startp++;
					if (*startp != ')')
						return (-1);
				}
			}
			break;
		case T_MX:
		case T_AFSDB:
		case T_RT:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_SRV:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case T_PX:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			PUTSHORT(n, cp);
			ShrinkBuffer(INT16SZ);
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				n = dn_comp(buf2, cp, buflen, dnptrs,
					    lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			break;
		case T_WKS: {
			char bm[MAXPORT/8];
			unsigned int maxbm = 0;

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(INT32SZ);
			PUTLONG(n1, cp);

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if ((i = res_protocolnumber(buf2)) < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = i & 0xff;
			 
			for (i = 0; i < MAXPORT/8 ; i++)
				bm[i] = 0;

			while (getword_str(buf2, sizeof buf2, &startp, endp)) {
				if ((n = res_servicenumber(buf2)) <= 0)
					return (-1);

				if (n < MAXPORT) {
					bm[n/8] |= (0x80>>(n%8));
					if ((unsigned)n > maxbm)
						maxbm = n;
				} else
					return (-1);
			}
			maxbm = maxbm/8 + 1;
			ShrinkBuffer(maxbm);
			memcpy(cp, bm, maxbm);
			cp += maxbm;
			break;
		}
		case T_HINFO:
			for (i = 0; i < 2; i++) {
				if ((n = getstr_str(buf2, sizeof buf2,
						&startp, endp)) < 0)
					return (-1);
				if (n > 255)
					return (-1);
				ShrinkBuffer(n+1);
				*cp++ = n;
				memcpy(cp, buf2, n);
				cp += n;
			}
			break;
		case T_TXT:
			for (;;) {
				if ((n = getstr_str(buf2, sizeof buf2,
						&startp, endp)) < 0) {
					if (cp != (sp2 + INT16SZ))
						break;
					return (-1);
				}
				if (n > 255)
					return (-1);
				ShrinkBuffer(n+1);
				*cp++ = n;
				memcpy(cp, buf2, n);
				cp += n;
			}
			break;
		case T_X25:
			/* RFC1183 */
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				return (-1);
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			break;
		case T_ISDN:
			/* RFC1183 */
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				return (-1);
			if ((n > 255) || (n == 0))
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				n = 0;
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			break;
		case T_NSAP:
			if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) {
				ShrinkBuffer(n);
				memcpy(cp, buf2, n);
				cp += n;
			} else {
				return (-1);
			}
			break;
		case T_LOC:
			if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) {
				ShrinkBuffer(n);
				memcpy(cp, buf2, n);
				cp += n;
			} else
				return (-1);
			break;
		case ns_t_sig:
		    {
			int sig_type, success, dateerror;
			u_int32_t exptime, timesigned;

			/* type */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			sig_type = sym_ston(__p_type_syms, buf2, &success);
			if (!success || sig_type == ns_t_any)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(sig_type, cp);
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* labels */
			n = getnum_str(&startp, endp);
			if (n <= 0 || n > 255)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* ottl  & expire */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			exptime = ns_datetosecs(buf2, &dateerror);
			if (!dateerror) {
				ShrinkBuffer(INT32SZ);
				PUTLONG(rttl, cp);
			}
			else {
				char *ulendp;
				u_int32_t ottl;

				errno = 0;
				ottl = strtoul(buf2, &ulendp, 10);
				if (errno != 0 ||
				    (ulendp != NULL && *ulendp != '\0'))
					return (-1);
				ShrinkBuffer(INT32SZ);
				PUTLONG(ottl, cp);
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				exptime = ns_datetosecs(buf2, &dateerror);
				if (dateerror)
					return (-1);
			}
			/* expire */
			ShrinkBuffer(INT32SZ);
			PUTLONG(exptime, cp);
			/* timesigned */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			timesigned = ns_datetosecs(buf2, &dateerror);
			if (!dateerror) {
				ShrinkBuffer(INT32SZ);
				PUTLONG(timesigned, cp);
			}
			else
				return (-1);
			/* footprint */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* signer name */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			/* sig */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			siglen = b64_pton(buf2, buf3, sizeof(buf3));
			if (siglen < 0)
				return (-1);
			ShrinkBuffer(siglen);
			memcpy(cp, buf3, siglen);
			cp += siglen;
			break;
		    }
		case ns_t_key:
			/* flags */
			n = gethexnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* proto */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* key */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			keylen = b64_pton(buf2, buf3, sizeof(buf3));
			if (keylen < 0)
				return (-1);
			ShrinkBuffer(keylen);
			memcpy(cp, buf3, keylen);
			cp += keylen;
			break;
		case ns_t_nxt:
		    {
			int success, nxt_type;
			u_char data[32];
			int maxtype;

			/* next name */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			maxtype = 0;
			memset(data, 0, sizeof data);
			for (;;) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					break;
				nxt_type = sym_ston(__p_type_syms, buf2,
						    &success);
				if (!success || !ns_t_rr_p(nxt_type))
					return (-1);
				NS_NXT_BIT_SET(nxt_type, data);
				if (nxt_type > maxtype)
					maxtype = nxt_type;
			}
			n = maxtype/NS_NXT_BITS+1;
			ShrinkBuffer(n);
			memcpy(cp, data, n);
			cp += n;
			break;
		    }
		case ns_t_cert:
			/* type */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* key tag */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* cert */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			certlen = b64_pton(buf2, buf3, sizeof(buf3));
			if (certlen < 0)
				return (-1);
			ShrinkBuffer(certlen);
			memcpy(cp, buf3, certlen);
			cp += certlen;
			break;
		case ns_t_aaaa:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (inet_pton(AF_INET6, buf2, &in6a) <= 0)
				return (-1);
			ShrinkBuffer(NS_IN6ADDRSZ);
			memcpy(cp, &in6a, NS_IN6ADDRSZ);
			cp += NS_IN6ADDRSZ;
			break;
		case ns_t_naptr:
			/* Order Preference Flags Service Replacement Regexp */
			/* Order */
			n = getnum_str(&startp, endp);
			if (n < 0 || n > 65535)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* Preference */
			n = getnum_str(&startp, endp);
			if (n < 0 || n > 65535)
				return (-1);
			ShrinkBuffer(INT16SZ);
			PUTSHORT(n, cp);
			/* Flags */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Service Classes */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Pattern */
			if ((n = getstr_str(buf2, sizeof buf2,
					&startp, endp)) < 0) {
				return (-1);
			}
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			/* Replacement */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, NULL, NULL);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		default:
			return (-1);
		} /*switch*/
Esempio n. 6
0
/*
 * Form update packets.
 * Returns the size of the resulting packet if no error
 * On error,
 *	returns -1 if error in reading a word/number in rdata
 *		   portion for update packets
 *		-2 if length of buffer passed is insufficient
 *		-3 if zone section is not the first section in
 *		   the linked list, or section order has a problem
 *		-4 on a number overflow
 *		-5 unknown operation or no records
 */
int
res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) {
	ns_updrec *rrecp_start = rrecp_in;
	HEADER *hp;
	u_char *cp, *sp1, *sp2, *startp, *endp;
	int n, i, soanum, multiline;
	ns_updrec *rrecp;
	struct in_addr ina;
	struct in6_addr in6a;
        char buf2[NS_MAXDNAME];
	u_char buf3[NS_MAXDNAME];
	int section, numrrs = 0, counts[ns_s_max];
	u_int16_t rtype, rclass;
	u_int32_t n1, rttl;
	u_char *dnptrs[20], **dpp, **lastdnptr;
	int siglen, keylen, certlen;

	/*
	 * Initialize header fields.
	 */
	if ((buf == NULL) || (buflen < NS_HFIXEDSZ))
		return (-1);
	memset(buf, 0, NS_HFIXEDSZ);
	hp = (HEADER *) buf;
#ifdef __APPLE__
	hp->id = res_randomid();
#else
	hp->id = htons(++statp->id);
#endif
	hp->opcode = ns_o_update;
	hp->rcode = ns_r_noerror;
	sp1 = buf + 2*NS_INT16SZ;  /* save pointer to zocount */
	cp = buf + NS_HFIXEDSZ;
	buflen -= NS_HFIXEDSZ;
	dpp = dnptrs;
	*dpp++ = buf;
	*dpp++ = NULL;
	lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];

	if (rrecp_start == NULL)
		return (-5);
	else if (rrecp_start->r_section != ns_s_zn)
		return (-3);

	memset(counts, 0, sizeof counts);
	for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) {
		numrrs++;
                section = rrecp->r_section;
		if (section < 0 || section >= ns_s_max)
			return (-1);
		counts[section]++;
		for (i = section + 1; i < ns_s_max; i++)
			if (counts[i])
				return (-3);
		rtype = rrecp->r_type;
		rclass = rrecp->r_class;
		rttl = rrecp->r_ttl;
		/* overload class and type */
		if (section == ns_s_pr) {
			rttl = 0;
			switch (rrecp->r_opcode) {
			case ns_r_yxdomain:
				rclass = ns_c_any;
				rtype = ns_t_any;
				rrecp->r_size = 0;
				break;
			case ns_r_nxdomain:
				rclass = ns_c_none;
				rtype = ns_t_any;
				rrecp->r_size = 0;
				break;
			case ns_r_nxrrset:
				rclass = ns_c_none;
				rrecp->r_size = 0;
				break;
			case ns_r_yxrrset:
				if (rrecp->r_size == 0)
					rclass = ns_c_any;
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		} else if (section == ns_s_ud) {
			switch (rrecp->r_opcode) {
			case ns_uop_delete:
				rclass = rrecp->r_size == 0 ? ns_c_any : ns_c_none;
				break;
			case ns_uop_add:
				break;
			default:
				fprintf(stderr,
					"res_mkupdate: incorrect opcode: %d\n",
					rrecp->r_opcode);
				fflush(stderr);
				return (-1);
			}
		}

		/*
		 * XXX	appending default domain to owner name is omitted,
		 *	fqdn must be provided
		 */
		if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
				 lastdnptr)) < 0)
			return (-1);
		cp += n;
		ShrinkBuffer(n + 2*NS_INT16SZ);
		NS_PUT16(rtype, cp);
		NS_PUT16(rclass, cp);
		if (section == ns_s_zn) {
			if (numrrs != 1 || rrecp->r_type != ns_t_soa)
				return (-3);
			continue;
		}
		ShrinkBuffer(NS_INT32SZ + NS_INT16SZ);
		NS_PUT32(rttl, cp);
		sp2 = cp;  /* save pointer to length byte */
		cp += NS_INT16SZ;
		if (rrecp->r_size == 0) {
			if (section == ns_s_ud && rclass != ns_c_any)
				return (-1);
			else {
				NS_PUT16(0, sp2);
				continue;
			}
		}
		startp = rrecp->r_data;
		endp = startp + rrecp->r_size - 1;
		/* XXX this should be done centrally. */
		switch (rrecp->r_type) {
		case ns_t_a:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(NS_INT32SZ);
			NS_PUT32(n1, cp);
			break;
		case ns_t_cname:
		case ns_t_mb:
		case ns_t_mg:
		case ns_t_mr:
		case ns_t_ns:
		case ns_t_ptr:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case ns_t_minfo:
		case ns_t_soa:
		case ns_t_rp:
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
				return (-1);
				n = dn_comp(buf2, cp, buflen,
					    dnptrs, lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			if (rrecp->r_type == ns_t_soa) {
				ShrinkBuffer(5 * NS_INT32SZ);
				while (isspace(*startp) || !*startp)
					startp++;
				if (*startp == '(') {
					multiline = 1;
					startp++;
				} else
					multiline = 0;
				/* serial, refresh, retry, expire, minimum */
				for (i = 0; i < 5; i++) {
					soanum = getnum_str(&startp, endp);
					if (soanum < 0)
						return (-1);
					NS_PUT32(soanum, cp);
				}
				if (multiline) {
					while (isspace(*startp) || !*startp)
						startp++;
					if (*startp != ')')
						return (-1);
				}
			}
			break;
		case ns_t_mx:
		case ns_t_afsdb:
		case ns_t_rt:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(n, cp);
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case ns_t_srv:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(n, cp);

			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(n, cp);

			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(n, cp);

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			break;
		case ns_t_px:
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			NS_PUT16(n, cp);
			ShrinkBuffer(NS_INT16SZ);
			for (i = 0; i < 2; i++) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				n = dn_comp(buf2, cp, buflen, dnptrs,
					    lastdnptr);
				if (n < 0)
					return (-1);
				cp += n;
				ShrinkBuffer(n);
			}
			break;
		case ns_t_wks: {
			char bm[MAXPORT/8];
			unsigned int maxbm = 0;

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (!inet_aton(buf2, &ina))
				return (-1);
			n1 = ntohl(ina.s_addr);
			ShrinkBuffer(NS_INT32SZ);
			NS_PUT32(n1, cp);

			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if ((i = res_protocolnumber(buf2)) < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = i & 0xff;
			 
			for (i = 0; i < MAXPORT/8 ; i++)
				bm[i] = 0;

			while (getword_str(buf2, sizeof buf2, &startp, endp)) {
				if ((n1 = res_servicenumber(buf2)) <= 0)
					return (-1);

				if (n1 < MAXPORT) {
					bm[n1/8] |= (0x80>>(n1%8));
					if (n1 > maxbm)
						maxbm = n1;
				} else
					return (-1);
			}
			maxbm = maxbm/8 + 1;
			ShrinkBuffer(maxbm);
			memcpy(cp, bm, maxbm);
			cp += maxbm;
			break;
		}
		case ns_t_hinfo:
			for (i = 0; i < 2; i++) {
				if ((n = getstr_str(buf2, sizeof buf2,
						&startp, endp)) < 0)
					return (-1);
				if (n > 255)
					return (-1);
				ShrinkBuffer(n+1);
				*cp++ = n;
				memcpy(cp, buf2, n);
				cp += n;
			}
			break;
		case ns_t_txt:
			while (1) {
				if ((n = getstr_str(buf2, sizeof buf2,
						&startp, endp)) < 0) {
					if (cp != (sp2 + NS_INT16SZ))
						break;
					return (-1);
				}
				if (n > 255)
					return (-1);
				ShrinkBuffer(n+1);
				*cp++ = n;
				memcpy(cp, buf2, n);
				cp += n;
			}
			break;
		case ns_t_x25:
			/* RFC 1183 */
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				return (-1);
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			break;
		case ns_t_isdn:
			/* RFC 1183 */
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				return (-1);
			if ((n > 255) || (n == 0))
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			if ((n = getstr_str(buf2, sizeof buf2, &startp,
					 endp)) < 0)
				n = 0;
			if (n > 255)
				return (-1);
			ShrinkBuffer(n+1);
			*cp++ = n;
			memcpy(cp, buf2, n);
			cp += n;
			break;
		case ns_t_nsap:
			if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) {
				ShrinkBuffer(n);
				memcpy(cp, buf2, n);
				cp += n;
			} else {
				return (-1);
			}
			break;
		case ns_t_loc:
			if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) {
				ShrinkBuffer(n);
				memcpy(cp, buf2, n);
				cp += n;
			} else
				return (-1);
			break;
		case ns_t_sig:
		    {
			int sig_type, success, dateerror;
			u_int32_t exptime, timesigned;

			/* type */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			sig_type = sym_ston(__p_type_syms, buf2, &success);
			if (!success || sig_type == ns_t_any)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(sig_type, cp);
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* labels */
			n = getnum_str(&startp, endp);
			if (n <= 0 || n > 255)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* ottl  & expire */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			exptime = ns_datetosecs(buf2, &dateerror);
			if (!dateerror) {
				ShrinkBuffer(NS_INT32SZ);
				NS_PUT32(rttl, cp);
			}
			else {
				char *ulendp;
				u_int32_t ottl;

				ottl = strtoul(buf2, &ulendp, 10);
				if (ulendp != NULL && *ulendp != '\0')
					return (-1);
				ShrinkBuffer(NS_INT32SZ);
				NS_PUT32(ottl, cp);
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					return (-1);
				exptime = ns_datetosecs(buf2, &dateerror);
				if (dateerror)
					return (-1);
			}
			/* expire */
			ShrinkBuffer(NS_INT32SZ);
			NS_PUT32(exptime, cp);
			/* timesigned */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			timesigned = ns_datetosecs(buf2, &dateerror);
			if (!dateerror) {
				ShrinkBuffer(NS_INT32SZ);
				NS_PUT32(timesigned, cp);
			}
			else
				return (-1);
			/* footprint */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(n, cp);
			/* signer name */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			/* sig */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			siglen = b64_pton(buf2, buf3, sizeof(buf3));
			if (siglen < 0)
				return (-1);
			ShrinkBuffer(siglen);
			memcpy(cp, buf3, siglen);
			cp += siglen;
			break;
		    }
		case ns_t_key:
			/* flags */
			n = gethexnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(n, cp);
			/* proto */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* key */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			keylen = b64_pton(buf2, buf3, sizeof(buf3));
			if (keylen < 0)
				return (-1);
			ShrinkBuffer(keylen);
			memcpy(cp, buf3, keylen);
			cp += keylen;
			break;
		case ns_t_nxt:
		    {
			int success, nxt_type;
			u_char data[32];
			int maxtype;

			/* next name */
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
			if (n < 0)
				return (-1);
			cp += n;
			ShrinkBuffer(n);
			maxtype = 0;
			memset(data, 0, sizeof data);
			while (1) {
				if (!getword_str(buf2, sizeof buf2, &startp,
						 endp))
					break;
				nxt_type = sym_ston(__p_type_syms, buf2,
						    &success);
				if (!success || !ns_t_rr_p(nxt_type))
					return (-1);
				NS_NXT_BIT_SET(nxt_type, data);
				if (nxt_type > maxtype)
					maxtype = nxt_type;
			}
			n = maxtype/NS_NXT_BITS+1;
			ShrinkBuffer(n);
			memcpy(cp, data, n);
			cp += n;
			break;
		    }
		case ns_t_cert:
			/* type */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(n, cp);
			/* key tag */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(NS_INT16SZ);
			NS_PUT16(n, cp);
			/* alg */
			n = getnum_str(&startp, endp);
			if (n < 0)
				return (-1);
			ShrinkBuffer(1);
			*cp++ = n;
			/* cert */
			if ((n = getword_str(buf2, sizeof buf2,
					     &startp, endp)) < 0)
				return (-1);
			certlen = b64_pton(buf2, buf3, sizeof(buf3));
			if (certlen < 0)
				return (-1);
			ShrinkBuffer(certlen);
			memcpy(cp, buf3, certlen);
			cp += certlen;
			break;
		case ns_t_aaaa:
			if (!getword_str(buf2, sizeof buf2, &startp, endp))
				return (-1);
			if (inet_pton(AF_INET6, buf2, &in6a) <= 0)
				return (-1);
			ShrinkBuffer(NS_IN6ADDRSZ);
			memcpy(cp, &in6a, NS_IN6ADDRSZ);
			cp += NS_IN6ADDRSZ;
			break;
		default:
			return (-1);
		} /*switch*/