Beispiel #1
0
/*
 * Internal version of lookup_dt() used by both lookup_dt() and
 * update_dt(); same semantics as lookup_dt() except that the `partial'
 * argument has been generalized into a `flags' field and the handle has
 * been turned into a FILE pointer.
 */
static int
find_dt(FILE *fp, uint_t flags, uint_t query, int count,
    const dt_rec_t *targetp, dt_rec_list_t **recordsp, uint_t *nrecordsp)
{
	int		retval = DSVC_SUCCESS;
	char 		*buf = NULL, *fields[DTF_MAX_FIELDS];
	uint_t		nrecords;
	dt_rec_t	*recordp;
	dt_rec_list_t	*records, *new_records;
	unsigned int	nfields;
	off_t		recoff;

	if (fseek(fp, 0, SEEK_SET) == -1)
		return (DSVC_INTERNAL);

	records = NULL;
	for (nrecords = 0; count < 0 || nrecords < count; ) {
		free(buf);

		if (flags & FIND_POSITION)
			recoff = ftello(fp);

		buf = read_entry(fp);
		if (buf == NULL) {
			if (!feof(fp))
				retval = DSVC_NO_MEMORY;
			break;
		}

		/*
		 * Skip pure comment lines; for now this just skips the
		 * header information at the top of the container.
		 */
		if (buf[0] == DTF_COMMENT_CHAR)
			continue;

		/*
		 * Parse out the entry into the dt_rec_t
		 */
		nfields = field_split(buf, DTF_MAX_FIELDS, fields, " \t");
		if (nfields < DTF_MAX_FIELDS)
			continue;

		/*
		 * See if we've got a match.  If so, allocate the new
		 * record, fill it in, and continue.
		 */
		if (DSVC_QISEQ(query, DT_QTYPE) &&
		    targetp->dt_type != fields[DTF_TYPE][0])
			continue;
		else if (DSVC_QISNEQ(query, DT_QTYPE) &&
		    targetp->dt_type == fields[DTF_TYPE][0])
			continue;

		if (DSVC_QISEQ(query, DT_QKEY) &&
		    strcmp(targetp->dt_key, fields[DTF_KEY]) != 0)
			continue;
		else if (DSVC_QISNEQ(query, DT_QKEY) &&
		    strcmp(targetp->dt_key, fields[DTF_KEY]) == 0)
			continue;

		/*
		 * Caller just wants a count of the number of matching
		 * records, not the records themselves; continue.
		 */
		if (recordsp == NULL) {
			nrecords++;
			continue;
		}

		/*
		 * Allocate record; if FIND_POSITION flag is set, then we
		 * need to allocate an extended (dt_recpos_t) record.
		 */
		if (flags & FIND_POSITION)
			recordp = malloc(sizeof (dt_recpos_t));
		else
			recordp = malloc(sizeof (dt_rec_t));

		if (recordp == NULL) {
			if ((flags & FIND_PARTIAL) == 0)
				retval = DSVC_NO_MEMORY;
			break;
		}

		/*
		 * Fill in record; if FIND_POSITION flag is set, then pass
		 * back additional location information.
		 */
		(void) strlcpy(recordp->dt_key, fields[DTF_KEY],
		    sizeof (recordp->dt_key));
		recordp->dt_sig = 1;
		recordp->dt_type = fields[DTF_TYPE][0];
		recordp->dt_value = strdup(fields[DTF_VALUE]);
		if (recordp->dt_value == NULL) {
			free(recordp);
			if ((flags & FIND_PARTIAL) == 0)
				retval = DSVC_NO_MEMORY;
			break;
		}

		if (flags & FIND_POSITION) {
			((dt_recpos_t *)recordp)->dtp_off = recoff;
			((dt_recpos_t *)recordp)->dtp_size = ftello(fp) -
			    recoff;
		}

		/*
		 * Chuck the record on the list; up the counter.
		 */
		new_records = add_dtrec_to_list(recordp, records);
		if (new_records == NULL) {
			free_dtrec(recordp);
			if ((flags & FIND_PARTIAL) == 0)
				retval = DSVC_NO_MEMORY;
			break;
		}
		records = new_records;
		nrecords++;
	}

	free(buf);

	if (retval == DSVC_SUCCESS) {
		*nrecordsp = nrecords;
		if (recordsp != NULL)
			*recordsp = records;
		return (DSVC_SUCCESS);
	}

	if (records != NULL)
		free_dtrec_list(records);

	return (retval);
}
Beispiel #2
0
/*
 * Compares the fields in fields[] agains the fields in target `targetp',
 * using `query' to decide what fields to compare.  Returns B_TRUE if `dnp'
 * matches `targetp', B_FALSE if not.  On success, `dnp' is completely
 * filled in.
 */
static boolean_t
record_match(char *fields[], dn_rec_t *dnp, const dn_rec_t *targetp,
    uint_t query)
{
	unsigned int	qflags[] = { DN_QFDYNAMIC, DN_QFAUTOMATIC, DN_QFMANUAL,
				    DN_QFUNUSABLE, DN_QFBOOTP_ONLY };
	unsigned int	flags[]  = { DN_FDYNAMIC, DN_FAUTOMATIC, DN_FMANUAL,
				    DN_FUNUSABLE, DN_FBOOTP_ONLY };
	unsigned int	i;
	uint_t		dn_cid_len;

	dnp->dn_cip.s_addr = ntohl(inet_addr(fields[DNF_CIP]));
	if (DSVC_QISEQ(query, DN_QCIP) &&
	    dnp->dn_cip.s_addr != targetp->dn_cip.s_addr)
		return (B_FALSE);
	if (DSVC_QISNEQ(query, DN_QCIP) &&
	    dnp->dn_cip.s_addr == targetp->dn_cip.s_addr)
		return (B_FALSE);

	dnp->dn_lease = atoi(fields[DNF_LEASE]);
	if (DSVC_QISEQ(query, DN_QLEASE) && targetp->dn_lease != dnp->dn_lease)
		return (B_FALSE);
	if (DSVC_QISNEQ(query, DN_QLEASE) && targetp->dn_lease == dnp->dn_lease)
		return (B_FALSE);

	/*
	 * We use dn_cid_len since dnp->dn_cid_len is of type uchar_t but
	 * hexascii_to_octet() expects an uint_t *
	 */
	dn_cid_len = DN_MAX_CID_LEN;
	if (hexascii_to_octet(fields[DNF_CID], strlen(fields[DNF_CID]),
	    dnp->dn_cid, &dn_cid_len) != 0)
		return (B_FALSE);

	dnp->dn_cid_len = dn_cid_len;
	if (DSVC_QISEQ(query, DN_QCID) &&
	    (dnp->dn_cid_len != targetp->dn_cid_len ||
	    (memcmp(dnp->dn_cid, targetp->dn_cid, dnp->dn_cid_len) != 0)))
		return (B_FALSE);
	if (DSVC_QISNEQ(query, DN_QCID) &&
	    (dnp->dn_cid_len == targetp->dn_cid_len &&
	    (memcmp(dnp->dn_cid, targetp->dn_cid, dnp->dn_cid_len) == 0)))
		return (B_FALSE);

	dnp->dn_sip.s_addr = ntohl(inet_addr(fields[DNF_SIP]));
	if (DSVC_QISEQ(query, DN_QSIP) &&
	    dnp->dn_sip.s_addr != targetp->dn_sip.s_addr)
		return (B_FALSE);
	if (DSVC_QISNEQ(query, DN_QSIP) &&
	    dnp->dn_sip.s_addr == targetp->dn_sip.s_addr)
		return (B_FALSE);

	unescape('|', fields[DNF_MACRO], dnp->dn_macro, sizeof (dnp->dn_macro));
	if (DSVC_QISEQ(query, DN_QMACRO) &&
	    strcmp(targetp->dn_macro, dnp->dn_macro) != 0)
		return (B_FALSE);
	if (DSVC_QISNEQ(query, DN_QMACRO) &&
	    strcmp(targetp->dn_macro, dnp->dn_macro) == 0)
		return (B_FALSE);

	dnp->dn_flags = atoi(fields[DNF_FLAGS]);
	for (i = 0; i < sizeof (qflags) / sizeof (unsigned int); i++) {
		if (DSVC_QISEQ(query, qflags[i]) &&
		    (dnp->dn_flags & flags[i]) !=
		    (targetp->dn_flags & flags[i]))
			return (B_FALSE);
		if (DSVC_QISNEQ(query, qflags[i]) &&
		    (dnp->dn_flags & flags[i]) ==
		    (targetp->dn_flags & flags[i]))
			return (B_FALSE);
	}

	dnp->dn_sig = atoll(fields[DNF_SIG]);
	unescape('|', fields[DNF_COMMENT], dnp->dn_comment,
	    sizeof (dnp->dn_comment));

	return (B_TRUE);
}