Example #1
0
/*
 * Free a list of dt_rec_t's
 */
void
free_dtrec_list(dt_rec_list_t *dtlp)
{
	dt_rec_list_t *next;

	for (; dtlp != NULL; dtlp = next) {
		free_dtrec(dtlp->dtl_rec);
		next = dtlp->dtl_next;
		free(dtlp);
	}
}
Example #2
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);
}