Ejemplo n.º 1
0
int
test_base_bitset(const char* param) {
    rand_seed((uint32_t)time(NULL));

    // bit create 
    int size = param ? atoi(param) : rand() % 1024;
    bit_t* bit = bit_create(size);
    if (!bit) {
        fprintf(stderr, "bit create fail\n");
        return -1;
    }

    // bit set 
    int test_size = (size >> 1);
    for (int i = 0; i < test_size; ++ i) {
        bit_set(bit, i);
    }

    // bit is set 
    for (int i = 0; i < size; ++ i) {
        if (i < test_size && bit_isset(bit, i)) {
            fprintf(stderr, "bit-set error\n");
            bit_release(bit);
            return -1;
        }
        if (i >= test_size && bit_isset(bit, i) == 0) {
            fprintf(stderr, "bit-set error\n");
            bit_release(bit);
            return -1;
        }
    }

    // bit count
    if (bit_count(bit) != test_size) {
        fprintf(stderr, "bit-count = %d error\n", bit_count(bit));
        bit_release(bit);
        return -1;
    }

    // bit reset -> bit count
    for (int i = 0; i < test_size; ++ i) {
        bit_reset(bit, i);
    }
    if (bit_count(bit) != 0) {
        fprintf(stderr, "bit-count error\n");
        bit_release(bit);
        return -1;
    }

    bit_release(bit);
    return 0;
}
Ejemplo n.º 2
0
isc_boolean_t
dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) {
	dns_rdata_nsec_t nsecstruct;
	isc_result_t result;
	isc_boolean_t present;
	unsigned int i, len, window;

	REQUIRE(nsec != NULL);
	REQUIRE(nsec->type == dns_rdatatype_nsec);

	/* This should never fail */
	result = dns_rdata_tostruct(nsec, &nsecstruct, NULL);
	INSIST(result == ISC_R_SUCCESS);

	present = ISC_FALSE;
	for (i = 0; i < nsecstruct.len; i += len) {
		INSIST(i + 2 <= nsecstruct.len);
		window = nsecstruct.typebits[i];
		len = nsecstruct.typebits[i + 1];
		INSIST(len > 0 && len <= 32);
		i += 2;
		INSIST(i + len <= nsecstruct.len);
		if (window * 256 > type)
			break;
		if ((window + 1) * 256 <= type)
			continue;
		if (type < (window * 256) + len * 8)
			present = ISC_TF(bit_isset(&nsecstruct.typebits[i],
						   type % 256));
		break;
	}
	dns_rdata_freestruct(&nsec);
	return (present);
}
Ejemplo n.º 3
0
static int nextbit(bitmap_t map, int bit)
/* Return the next bit set in 'map' from 'bit' onwards, cyclic. */
{
	for (;;) {
		bit= (bit+1) & 63;
		if (bit_isset(map, bit)) break;
	}
	return bit;
}
Ejemplo n.º 4
0
void tab_parse(char *file, char *user)
/* Parse a crontab file and add its data to the tables.  Handle errors by
 * yourself.  Table is owned by 'user' if non-null.
 */
{
	crontab_t **atab, *tab;
	cronjob_t **ajob, *job;
	int fd;
	struct stat st;
	char *p, *q;
	size_t n;
	ssize_t r;
	int ok, wc;

	for (atab= &crontabs; (tab= *atab) != nil; atab= &tab->next) {
		if (strcmp(file, tab->file) == 0) break;
	}

	/* Try to open the file. */
	if ((fd= open(file, O_RDONLY)) < 0 || fstat(fd, &st) < 0) {
		if (errno != ENOENT) {
			log(LOG_ERR, "%s: %s\n", file, strerror(errno));
		}
		if (fd != -1) close(fd);
		return;
	}

	/* Forget it if the file is awfully big. */
	if (st.st_size > TAB_MAX) {
		log(LOG_ERR, "%s: %lu bytes is bigger than my %lu limit\n",
			file,
			(unsigned long) st.st_size,
			(unsigned long) TAB_MAX);
		return;
	}

	/* If the file is the same as before then don't bother. */
	if (tab != nil && st.st_mtime == tab->mtime) {
		close(fd);
		tab->current= 1;
		return;
	}

	/* Create a new table structure. */
	tab= allocate(sizeof(*tab));
	tab->file= allocate((strlen(file) + 1) * sizeof(tab->file[0]));
	strcpy(tab->file, file);
	tab->user= nil;
	if (user != nil) {
		tab->user= allocate((strlen(user) + 1) * sizeof(tab->user[0]));
		strcpy(tab->user, user);
	}
	tab->data= allocate((st.st_size + 1) * sizeof(tab->data[0]));
	tab->jobs= nil;
	tab->mtime= st.st_mtime;
	tab->current= 0;
	tab->next= *atab;
	*atab= tab;

	/* Pull a new table in core. */
	n= 0;
	while (n < st.st_size) {
		if ((r = read(fd, tab->data + n, st.st_size - n)) < 0) {
			log(LOG_CRIT, "%s: %s", file, strerror(errno));
			close(fd);
			return;
		}
		if (r == 0) break;
		n+= r;
	}
	close(fd);
	tab->data[n]= 0;
	if (strlen(tab->data) < n) {
		log(LOG_ERR, "%s contains a null character\n", file);
		return;
	}

	/* Parse the file. */
	ajob= &tab->jobs;
	p= tab->data;
	ok= 1;
	while (ok && *p != 0) {
		q= get_token(&p);
		if (*q == '#' || q == p) {
			/* Comment or empty. */
			while (*p != 0 && *p++ != '\n') {}
			continue;
		}

		/* One new job coming up. */
		*ajob= job= allocate(sizeof(*job));
		*(ajob= &job->next)= nil;
		job->tab= tab;

		if (!range_parse(file, q, job->min, 0, 59, &wc)) {
			ok= 0;
			break;
		}

		q= get_token(&p);
		if (!range_parse(file, q, job->hour, 0, 23, &wc)) {
			ok= 0;
			break;
		}

		q= get_token(&p);
		if (!range_parse(file, q, job->mday, 1, 31, &wc)) {
			ok= 0;
			break;
		}
		job->do_mday= !wc;

		q= get_token(&p);
		if (!range_parse(file, q, job->mon, 1, 12, &wc)) {
			ok= 0;
			break;
		}
		job->do_mday |= !wc;

		q= get_token(&p);
		if (!range_parse(file, q, job->wday, 0, 7, &wc)) {
			ok= 0;
			break;
		}
		job->do_wday= !wc;

		/* 7 is Sunday, but 0 is a common mistake because it is in the
		 * tm_wday range.  We allow and even prefer it internally.
		 */
		if (bit_isset(job->wday, 7)) {
			bit_clr(job->wday, 7);
			bit_set(job->wday, 0);
		}

		/* The month range is 1-12, but tm_mon likes 0-11. */
		job->mon[0] >>= 1;
		if (bit_isset(job->mon, 8)) bit_set(job->mon, 7);
		job->mon[1] >>= 1;

		/* Scan for options. */
		job->user= nil;
		while (q= get_token(&p), *q == '-') {
			q++;
			if (q[0] == '-' && q+1 == p) {
				/* -- */
				q= get_token(&p);
				break;
			}
			while (q < p) switch (*q++) {
			case 'u':
				if (q == p) q= get_token(&p);
				if (q == p) goto usage;
				memmove(q-1, q, p-q);	/* gross... */
				p[-1]= 0;
				job->user= q-1;
				q= p;
				break;
			default:
			usage:
				log(LOG_ERR,
			"%s: bad option -%c, good options are: -u username\n",
					file, q[-1]);
				ok= 0;
				goto endtab;
			}
		}

		/* A crontab owned by a user can only do things as that user. */
		if (tab->user != nil) job->user= tab->user;

		/* Inspect the first character of the command. */
		job->cmd= q;
		if (q == p || *q == '#') {
			/* Rest of the line is empty, i.e. the commands are on
			 * the following lines indented by one tab.
			 */
			while (*p != 0 && *p++ != '\n') {}
			if (*p++ != '\t') {
				log(LOG_ERR, "%s: contains an empty command\n",
					file);
				ok= 0;
				goto endtab;
			}
			while (*p != 0) {
				if ((*q = *p++) == '\n') {
					if (*p != '\t') break;
					p++;
				}
				q++;
			}
		} else {
			/* The command is on this line.  Alas we must now be
			 * backwards compatible and change %'s to newlines.
			 */
			p= q;
			while (*p != 0) {
				if ((*q = *p++) == '\n') break;
				if (*q == '%') *q= '\n';
				q++;
			}
		}
		*q= 0;
		job->rtime= now;
		job->late= 0;		/* It is on time. */
		job->atjob= 0;		/* True cron job. */
		job->pid= IDLE_PID;	/* Not running yet. */
		tab_reschedule(job);	/* Compute next time to run. */
	}
  endtab:

	if (ok) tab->current= 1;
}
Ejemplo n.º 5
0
void tab_reschedule(cronjob_t *job)
/* Reschedule one job.  Compute the next time to run the job in job->rtime.
 */
{
	struct tm prevtm, nexttm, tmptm;
	time_t nodst_rtime, dst_rtime;

	/* AT jobs are only run once. */
	if (job->atjob) { job->rtime= NEVER; return; }

	/* Was the job scheduled late last time? */
	if (job->late) job->rtime= now;

	prevtm= *localtime(&job->rtime);
	prevtm.tm_sec= 0;

	nexttm= prevtm;
	nexttm.tm_min++;	/* Minimal increment */

	for (;;)
	{
		if (nexttm.tm_min > 59)
		{
			nexttm.tm_min= 0;
			nexttm.tm_hour++;
		}
		if (nexttm.tm_hour > 23)
		{
			nexttm.tm_min= 0;
			nexttm.tm_hour= 0;
			nexttm.tm_mday++;
		}
		if (nexttm.tm_mday > 31)
		{
			nexttm.tm_hour= nexttm.tm_min= 0;
			nexttm.tm_mday= 1;
			nexttm.tm_mon++;
		}
		if (nexttm.tm_mon >= 12)
		{
			nexttm.tm_hour= nexttm.tm_min= 0;
			nexttm.tm_mday= 1;
			nexttm.tm_mon= 0;
			nexttm.tm_year++;
		}

		/* Verify tm_year. A crontab entry cannot restrict tm_year
		 * directly. However, certain dates (such as Feb, 29th) do
		 * not occur every year. We limit the difference between
		 * nexttm.tm_year and prevtm.tm_year to detect impossible dates
		 * (e.g, Feb, 31st). In theory every date occurs within a
		 * period of 4 years. However, some years at the end of a 
		 * century are not leap years (e.g, the year 2100). An extra
		 * factor of 2 should be enough.
		 */
		if (nexttm.tm_year-prevtm.tm_year > 2*4)
		{
			job->rtime= NEVER;
			return;			/* Impossible combination */
		}

		if (!job->do_wday)
		{
			/* Verify the mon and mday fields. If do_wday and
			 * do_mday are both true we have to merge both
			 * schedules. This is done after the call to mktime.
			 */
			if (!bit_isset(job->mon, nexttm.tm_mon))
			{
				/* Clear other fields */
				nexttm.tm_mday= 1;
				nexttm.tm_hour= nexttm.tm_min= 0;

				nexttm.tm_mon++;
				continue;
			}

			/* Verify mday */
			if (!bit_isset(job->mday, nexttm.tm_mday))
			{
				/* Clear other fields */
				nexttm.tm_hour= nexttm.tm_min= 0;

				nexttm.tm_mday++;
				continue;
			}
		}

		/* Verify hour */
		if (!bit_isset(job->hour, nexttm.tm_hour))
		{
			/* Clear tm_min field */
			nexttm.tm_min= 0;

			nexttm.tm_hour++;
			continue;
		}

		/* Verify min */
		if (!bit_isset(job->min, nexttm.tm_min))
		{
			nexttm.tm_min++;
			continue;
		}

		/* Verify that we don't have any problem with DST. Try
		 * tm_isdst=0 first. */
		tmptm= nexttm;
		tmptm.tm_isdst= 0;
#if 0
		fprintf(stderr, 
	"tab_reschedule: trying %04d-%02d-%02d %02d:%02d:%02d isdst=0\n",
				1900+nexttm.tm_year, nexttm.tm_mon+1,
				nexttm.tm_mday, nexttm.tm_hour,
				nexttm.tm_min, nexttm.tm_sec);
#endif
		nodst_rtime= job->rtime= mktime(&tmptm);
		if (job->rtime == -1) {
			/* This should not happen. */
			log(LOG_ERR,
			"mktime failed for %04d-%02d-%02d %02d:%02d:%02d",
				1900+nexttm.tm_year, nexttm.tm_mon+1,
				nexttm.tm_mday, nexttm.tm_hour,
				nexttm.tm_min, nexttm.tm_sec);
			job->rtime= NEVER;
			return;	
		}
		if (tmptm.tm_hour != nexttm.tm_hour ||
			tmptm.tm_min != nexttm.tm_min)
		{
			assert(tmptm.tm_isdst);
			tmptm= nexttm;
			tmptm.tm_isdst= 1;
#if 0
			fprintf(stderr, 
	"tab_reschedule: trying %04d-%02d-%02d %02d:%02d:%02d isdst=1\n",
				1900+nexttm.tm_year, nexttm.tm_mon+1,
				nexttm.tm_mday, nexttm.tm_hour,
				nexttm.tm_min, nexttm.tm_sec);
#endif
			dst_rtime= job->rtime= mktime(&tmptm);
			if (job->rtime == -1) {
				/* This should not happen. */
				log(LOG_ERR,
			"mktime failed for %04d-%02d-%02d %02d:%02d:%02d\n",
					1900+nexttm.tm_year, nexttm.tm_mon+1,
					nexttm.tm_mday, nexttm.tm_hour,
					nexttm.tm_min, nexttm.tm_sec);
				job->rtime= NEVER;
				return;	
			}
			if (tmptm.tm_hour != nexttm.tm_hour ||
				tmptm.tm_min != nexttm.tm_min)
			{
				assert(!tmptm.tm_isdst);
				/* We have a problem. This time neither
				 * exists with DST nor without DST.
				 * Use the latest time, which should be
				 * nodst_rtime.
				 */
				assert(nodst_rtime > dst_rtime);
				job->rtime= nodst_rtime;
#if 0
				fprintf(stderr,
			"During DST trans. %04d-%02d-%02d %02d:%02d:%02d\n",
					1900+nexttm.tm_year, nexttm.tm_mon+1,
					nexttm.tm_mday, nexttm.tm_hour,
					nexttm.tm_min, nexttm.tm_sec);
#endif
			}
		}

		/* Verify this the combination (tm_year, tm_mon, tm_mday). */
		if (tmptm.tm_mday != nexttm.tm_mday ||
			tmptm.tm_mon != nexttm.tm_mon ||
			tmptm.tm_year != nexttm.tm_year)
		{
			/* Wrong day */
#if 0
			fprintf(stderr, "Wrong day\n");
#endif
			nexttm.tm_hour= nexttm.tm_min= 0;
			nexttm.tm_mday++;
			continue;
		}

		/* Check tm_wday */
		if (job->do_wday && bit_isset(job->wday, tmptm.tm_wday))
		{
			/* OK, wday matched */
			break;
		}

		/* Check tm_mday */
		if (job->do_mday && bit_isset(job->mon, tmptm.tm_mon) &&
			bit_isset(job->mday, tmptm.tm_mday))
		{
			/* OK, mon and mday matched */
			break;
		}

		if (!job->do_wday && !job->do_mday)
		{
			/* No need to match wday and mday */
			break;
		}

		/* Wrong day */
#if 0
		fprintf(stderr, "Wrong mon+mday or wday\n");
#endif
		nexttm.tm_hour= nexttm.tm_min= 0;
		nexttm.tm_mday++;
	}
#if 0
	fprintf(stderr, "Using %04d-%02d-%02d %02d:%02d:%02d \n",
		1900+nexttm.tm_year, nexttm.tm_mon+1, nexttm.tm_mday,
		nexttm.tm_hour, nexttm.tm_min, nexttm.tm_sec);
	tmptm= *localtime(&job->rtime);
	fprintf(stderr, "Act. %04d-%02d-%02d %02d:%02d:%02d isdst=%d\n",
		1900+tmptm.tm_year, tmptm.tm_mon+1, tmptm.tm_mday,
		tmptm.tm_hour, tmptm.tm_min, tmptm.tm_sec,
		tmptm.tm_isdst);
#endif


	/* Is job issuing lagging behind with the progress of time? */
	job->late= (job->rtime < now);

  	/* The result is in job->rtime. */
  	if (job->rtime < next) next= job->rtime;
}
Ejemplo n.º 6
0
isc_result_t
dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
		    dns_dbnode_t *node, dns_name_t *target,
		    unsigned char *buffer, dns_rdata_t *rdata)
{
	isc_result_t result;
	dns_rdataset_t rdataset;
	isc_region_t r;
	unsigned int i, window;
	int octet;

	unsigned char *nsec_bits, *bm;
	unsigned int max_type;
	dns_rdatasetiter_t *rdsiter;

	memset(buffer, 0, DNS_NSEC_BUFFERSIZE);
	dns_name_toregion(target, &r);
	memcpy(buffer, r.base, r.length);
	r.base = buffer;
	/*
	 * Use the end of the space for a raw bitmap leaving enough
	 * space for the window identifiers and length octets.
	 */
	bm = r.base + r.length + 512;
	nsec_bits = r.base + r.length;
	set_bit(bm, dns_rdatatype_rrsig, 1);
	set_bit(bm, dns_rdatatype_nsec, 1);
	max_type = dns_rdatatype_nsec;
	dns_rdataset_init(&rdataset);
	rdsiter = NULL;
	result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
	if (result != ISC_R_SUCCESS)
		return (result);
	for (result = dns_rdatasetiter_first(rdsiter);
	     result == ISC_R_SUCCESS;
	     result = dns_rdatasetiter_next(rdsiter))
	{
		dns_rdatasetiter_current(rdsiter, &rdataset);
		if (rdataset.type != dns_rdatatype_nsec &&
		    rdataset.type != dns_rdatatype_nsec3 &&
		    rdataset.type != dns_rdatatype_rrsig) {
			if (rdataset.type > max_type)
				max_type = rdataset.type;
			set_bit(bm, rdataset.type, 1);
		}
		dns_rdataset_disassociate(&rdataset);
	}

	/*
	 * At zone cuts, deny the existence of glue in the parent zone.
	 */
	if (bit_isset(bm, dns_rdatatype_ns) &&
	    ! bit_isset(bm, dns_rdatatype_soa)) {
		for (i = 0; i <= max_type; i++) {
			if (bit_isset(bm, i) &&
			    ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
				set_bit(bm, i, 0);
		}
	}

	dns_rdatasetiter_destroy(&rdsiter);
	if (result != ISC_R_NOMORE)
		return (result);

	for (window = 0; window < 256; window++) {
		if (window * 256 > max_type)
			break;
		for (octet = 31; octet >= 0; octet--)
			if (bm[window * 32 + octet] != 0)
				break;
		if (octet < 0)
			continue;
		nsec_bits[0] = window;
		nsec_bits[1] = octet + 1;
		/*
		 * Note: potential overlapping move.
		 */
		memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
		nsec_bits += 3 + octet;
	}
	r.length = nsec_bits - r.base;
	INSIST(r.length <= DNS_NSEC_BUFFERSIZE);
	dns_rdata_fromregion(rdata,
			     dns_db_class(db),
			     dns_rdatatype_nsec,
			     &r);

	return (ISC_R_SUCCESS);
}
Ejemplo n.º 7
0
isc_result_t
dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
		     dns_dbnode_t *node, unsigned int hashalg,
		     unsigned int flags, unsigned int iterations,
		     const unsigned char *salt, size_t salt_length,
		     const unsigned char *nexthash, size_t hash_length,
		     unsigned char *buffer, dns_rdata_t *rdata)
{
	isc_result_t result;
	dns_rdataset_t rdataset;
	isc_region_t r;
	unsigned int i, window;
	int octet;
	isc_boolean_t found;
	isc_boolean_t found_ns;
	isc_boolean_t need_rrsig;

	unsigned char *nsec_bits, *bm;
	unsigned int max_type;
	dns_rdatasetiter_t *rdsiter;
	unsigned char *p;

	REQUIRE(salt_length < 256U);
	REQUIRE(hash_length < 256U);
	REQUIRE(flags <= 0xffU);
	REQUIRE(hashalg <= 0xffU);
	REQUIRE(iterations <= 0xffffU);

	switch (hashalg) {
	case dns_hash_sha1:
		REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
		break;
	}

	memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);

	p = buffer;

	*p++ = hashalg;
	*p++ = flags;

	*p++ = iterations >> 8;
	*p++ = iterations;

	*p++ = salt_length;
	memcpy(p, salt, salt_length);
	p += salt_length;

	*p++ = hash_length;
	memcpy(p, nexthash, hash_length);
	p += hash_length;

	r.length = p - buffer;
	r.base = buffer;

	/*
	 * Use the end of the space for a raw bitmap leaving enough
	 * space for the window identifiers and length octets.
	 */
	bm = r.base + r.length + 512;
	nsec_bits = r.base + r.length;
	max_type = 0;
	if (node == NULL)
		goto collapse_bitmap;
	dns_rdataset_init(&rdataset);
	rdsiter = NULL;
	result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
	if (result != ISC_R_SUCCESS)
		return (result);
	found = found_ns = need_rrsig = ISC_FALSE;
	for (result = dns_rdatasetiter_first(rdsiter);
	     result == ISC_R_SUCCESS;
	     result = dns_rdatasetiter_next(rdsiter))
	{
		dns_rdatasetiter_current(rdsiter, &rdataset);
		if (rdataset.type != dns_rdatatype_nsec &&
		    rdataset.type != dns_rdatatype_nsec3 &&
		    rdataset.type != dns_rdatatype_rrsig) {
			if (rdataset.type > max_type)
				max_type = rdataset.type;
			set_bit(bm, rdataset.type, 1);
			/*
			 * Work out if we need to set the RRSIG bit for
			 * this node.  We set the RRSIG bit if either of
			 * the following conditions are met:
			 * 1) We have a SOA or DS then we need to set
			 *    the RRSIG bit as both always will be signed.
			 * 2) We set the RRSIG bit if we don't have
			 *    a NS record but do have other data.
			 */
			if (rdataset.type == dns_rdatatype_soa ||
			    rdataset.type == dns_rdatatype_ds)
				need_rrsig = ISC_TRUE;
			else if (rdataset.type == dns_rdatatype_ns)
				found_ns = ISC_TRUE;
			else
				found = ISC_TRUE;
		}
		dns_rdataset_disassociate(&rdataset);
	}
	if ((found && !found_ns) || need_rrsig) {
		if (dns_rdatatype_rrsig > max_type)
			max_type = dns_rdatatype_rrsig;
		set_bit(bm, dns_rdatatype_rrsig, 1);
	}

	/*
	 * At zone cuts, deny the existence of glue in the parent zone.
	 */
	if (bit_isset(bm, dns_rdatatype_ns) &&
	    ! bit_isset(bm, dns_rdatatype_soa)) {
		for (i = 0; i <= max_type; i++) {
			if (bit_isset(bm, i) &&
			    ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
				set_bit(bm, i, 0);
		}
	}

	dns_rdatasetiter_destroy(&rdsiter);
	if (result != ISC_R_NOMORE)
		return (result);

 collapse_bitmap:
	for (window = 0; window < 256; window++) {
		if (window * 256 > max_type)
			break;
		for (octet = 31; octet >= 0; octet--)
			if (bm[window * 32 + octet] != 0)
				break;
		if (octet < 0)
			continue;
		nsec_bits[0] = window;
		nsec_bits[1] = octet + 1;
		/*
		 * Note: potentially overlapping move.
		 */
		memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
		nsec_bits += 3 + octet;
	}
	r.length = nsec_bits - r.base;
	INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
	dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);

	return (ISC_R_SUCCESS);
}
Ejemplo n.º 8
0
static int hash_dir(const char *dirname)
{
	struct bucket_info *bi, *nextbi;
	struct entry_info *ei, *nextei;
	struct dirent *de;
	struct stat st;
	unsigned char idmask[MAX_COLLISIONS / 8];
	int i, n, nextid, buflen, ret = -1;
	const char *pathsep;
	char *buf;
	DIR *d;

	if (access(dirname, R_OK|W_OK|X_OK) != 0) {
		fprintf(stderr,
			"ERROR: Access denied '%s'\n",
			dirname);
		return -1;
	}

	buflen = strlen(dirname);
	pathsep = (buflen && dirname[buflen-1] == '/') ? "" : "/";
	buflen += NAME_MAX + 2;
	buf = malloc(buflen);
	if (buf == NULL)
		goto err;

	if (do_verbose) printf("Doing %s\n", dirname);
	d = opendir(dirname);
	if (!d) goto err;

	while ((de = readdir(d)) != NULL) {
		if (snprintf(buf, buflen, "%s%s%s", dirname, pathsep, de->d_name) >= buflen)
			continue;
		if (lstat(buf, &st) < 0)
			continue;
		if (S_ISLNK(st.st_mode) && handle_symlink(de->d_name, buf) == 0)
			continue;
		handle_certificate(de->d_name, buf);
	}
	closedir(d);

	for (i = 0; i < countof(hash_table); i++) {
		for (bi = hash_table[i]; bi; bi = nextbi) {
			nextbi = bi->next;
			DEBUG("Type %d, hash %08x, num entries %d:\n", bi->type, bi->hash, bi->num_needed);

			nextid = 0;
			memset(idmask, 0, (bi->num_needed+7)/8);
			for (ei = bi->first_entry; ei; ei = ei->next)
				if (ei->old_id < bi->num_needed)
					bit_set(idmask, ei->old_id);

			for (ei = bi->first_entry; ei; ei = nextei) {
				nextei = ei->next;
				DEBUG("\t(old_id %d, need_symlink %d) Cert %s\n",
					ei->old_id, ei->need_symlink,
					ei->filename);

				if (ei->old_id < bi->num_needed) {
					/* Link exists, and is used as-is */
					snprintf(buf, buflen, "%08x.%s%d", bi->hash, symlink_extensions[bi->type], ei->old_id);
					if (do_verbose) printf("link %s -> %s\n", ei->filename, buf);
				} else if (ei->need_symlink) {
					/* New link needed (it may replace something) */
					while (bit_isset(idmask, nextid))
						nextid++;

					snprintf(buf, buflen, "%s%s%n%08x.%s%d",
						 dirname, pathsep, &n, bi->hash,
						 symlink_extensions[bi->type],
						 nextid);
					if (do_verbose) printf("link %s -> %s\n", ei->filename, &buf[n]);
					unlink(buf);
					symlink(ei->filename, buf);
				} else if (do_remove_links) {
					/* Link to be deleted */
					snprintf(buf, buflen, "%s%s%n%08x.%s%d",
						 dirname, pathsep, &n, bi->hash,
						 symlink_extensions[bi->type],
						 ei->old_id);
					if (do_verbose) printf("unlink %s\n", &buf[n]);
					unlink(buf);
				}
				free(ei->filename);
				free(ei);
			}
			free(bi);
		}
		hash_table[i] = NULL;
	}

	ret = 0;
err:
	free(buf);
	return ret;
}
Ejemplo n.º 9
0
int str_match(const char *str, const char *format) {

    const char *s   = str;
    const char *fmt = format;
    unsigned int flag = 0;
    int width = 0;

    bit_t bit;
    char c;
    const char *s0;

    while (*fmt) {
        if (*fmt == '%') {
            fmt++;

            while (*fmt >= '0' && *fmt <= '9') 
                width = width * 10 + *fmt++ - '0';

            switch(*fmt) {
                case 'd':
                    if (width) {
                        while (*s && isdigit(*s) && width-- > 0)
                            s++;
                    } else {
                        while (*s && isdigit(*s))
                            s++;
                    }
                    fmt++;
                    break;

                case '[':
                    fmt++;
                    bit_zero(&bit);

                    if (*fmt == '^') {
                        fmt++;
                        flag |= STATUS_CARET;
                    }

                    while (*fmt && *fmt != ']') {
                        if (fmt[1] == '-') {
                            for (c = *fmt; c < fmt[2]; c++) {
                                bit_set(&bit, c);
                            }
                            if (c == fmt[2])
                                fmt += 2;
                        } else {
                            bit_set(&bit, *fmt);
                            fmt++;
                        }
                    }

                    if (flag & STATUS_CARET) {
                        bit_rev(&bit);
                        /* clear STATUS_CARET */
                        flag &= ~STATUS_CARET;
                    }

                    if (width) {
                        while (*s && bit_isset(&bit, *s) && width-- > 0) {
                            s++;
                        }
                    } else {
                        while (*s && bit_isset(&bit, *s)) {
                            s++;
                        }
                    }

                    if (*fmt == ']')
                        fmt++;
                    break;

                case 'f':

                    if (width) {
                        while (*s && isdigit(*s) && width > 0)
                            s++, width--;

                        if (*s == '.' && width > 0)
                            s++, width--;

                        while (*s && isdigit(*s) && width > 0)
                            s++, width--;
                    } else {
                        while (*s && isdigit(*s))
                            s++;

                        if (*s == '.')
                            s++;

                        while (*s && isdigit(*s))
                            s++;
                    }

                    fmt++;
                    break;

                case '{':
                    fmt++;

                    flag &= ~STATUS_OR;
                    while(*fmt && *fmt != '|' && *fmt != '}') {
                        s0 = s;

                        /* match */
                        while (*fmt && *fmt != '|' && *fmt != '}' && (*s0 == *fmt))
                            s0++, fmt++;

                        /* match ok*/
                        if (*fmt == '|' || *fmt == '}') {
                            flag |= STATUS_OR;
                            while (*fmt && *fmt != '}')
                                fmt++;
                            s = s0;
                        } else {
                            /* match no*/
                            while (*fmt && *fmt != '|' && *fmt != '}')
                                fmt++;
                            if (*fmt == '|' || *fmt == '}')
                                fmt++;
                        }
                    }

                    if (!(flag & STATUS_OR))
                        return 0;

                    if (*fmt == '}')
                        fmt++;
                    break;

                default:
                    fmt++;
                    break;
            }

            width = 0;
        } else {

            /*printf("%d:%d:%c:%c\n", *fmt, *s, *fmt, *s);*/
            if (!*fmt && !*s)
                return 1;

            if (*fmt != *s) {
                /* %?*/
                if (*fmt && fmt[1] == '%' && fmt[2] == '?') {
                    fmt++;
                    continue;
                }
                else
                    return 0;
            }

            fmt++;
            s++;
        }
    }

    return !*fmt && !*s;
}