예제 #1
1
파일: error.c 프로젝트: BluePanM/code
void
dkc_compile_error(int line_number, CompileError id, ...)
{
    va_list     ap;
    VWString    message;

    self_check();
    va_start(ap, id);

    dkc_vwstr_clear(&message);
    format_message(line_number,
                   &dkc_error_message_format[id],
                   &message, ap);
    fprintf(stderr, "%3d:", line_number);
    dvm_print_wcs_ln(stderr, message.string);
    va_end(ap);

    exit(1);
}
예제 #2
0
size_t unit_map::erase(const map_location &loc) {
	self_check();
	unit *u = extract(loc);
	if (!u) return 0;
	delete u;
	return 1;
}
예제 #3
0
unit_map::umap_retval_pair_t unit_map::replace(const map_location& l, unit_ptr p)
{
	self_check();
	p->set_location(l);
	erase(l);
	return insert(p);
}
예제 #4
0
std::pair<unit_map::unit_iterator, bool> unit_map::add(const map_location &l, const unit &u) {
	self_check();
	unit_ptr p = unit_ptr (new unit(u)); //TODO: should this instead take a shared pointer to a unit, rather than make a copy?
	p->set_location(l);
	std::pair<unit_map::unit_iterator, bool> res( insert(p) );
	if(res.second == false) { p.reset(); }
	return res;
}
예제 #5
0
std::pair<unit_map::unit_iterator, bool> unit_map::add(const map_location &l, const unit &u) {
	self_check();
	unit *p = new unit(u);
	p->set_location(l);
	std::pair<unit_map::unit_iterator, bool> res( insert(p) );
	if(res.second == false) { delete p; }
	return res;
}
예제 #6
0
std::pair<unit_map::unit_iterator, bool> unit_map::replace(const map_location &l, const unit &u) {
	self_check();
	//when 'l' is the reference to map_location that is part
	//of that unit iterator which is to be deleted by erase,
	// 'l' is invalidated by erase, too. Thus, 'add(l,u)' fails.
	// So, we need to make a copy of that map_location.
	map_location loc = l;
	erase(loc);
	return add(loc, u);
}
예제 #7
0
unit_map::umap::iterator unit_map::begin_core() const
{
	self_check();

	umap::iterator i = umap_.begin();
	while(i != umap_.end() && (!i->second.unit)) {
		++i;
	}

	return i;
}
예제 #8
0
unit_map::unit_iterator unit_map::find(std::size_t id)
{
	self_check();

	umap::iterator i(umap_.find(id));
	if((i != umap_.end()) && !i->second.unit) {
		i = umap_.end();
	}

	return make_unit_iterator<umap::iterator>(i);
}
예제 #9
0
std::size_t unit_map::erase(const map_location& loc)
{
	self_check();

	unit_ptr u = extract(loc);
	if(!u) {
		return 0;
	}

	u.reset();
	return 1;
}
예제 #10
0
unit_map::umap_retval_pair_t unit_map::move(const map_location& src, const map_location& dst)
{
	self_check();
	DBG_NG << "Unit map: Moving unit from " << src << " to " << dst << "\n";

	// Find the unit at the src location
	lmap::iterator i = lmap_.find(src);
	if(i == lmap_.end()) {
		return std::make_pair(make_unit_iterator(i), false);
	}

	umap::iterator uit(i->second);

	if(src == dst) {
		return std::make_pair(make_unit_iterator(uit), true);
	}

	// Fail if there is no unit to move.
	unit_ptr p = uit->second.unit;
	if(!p) {
		return std::make_pair(make_unit_iterator(uit), false);
	}

	p->set_location(dst);

	lmap_.erase(i);

	std::pair<lmap::iterator, bool> res = lmap_.emplace(dst, uit);

	// Fail and don't move if the destination is already occupied.
	if(res.second == false) {
		p->set_location(src);
		lmap_.emplace(src, uit);
		return std::make_pair(make_unit_iterator(uit), false);
	}

	self_check();

	return std::make_pair(make_unit_iterator(uit), true);
}
예제 #11
0
unit_map::umap_retval_pair_t unit_map::add(const map_location& l, const unit& u)
{
	self_check();

	 // TODO: should this take a shared pointer to a unit rather than make a copy?
	unit_ptr p = u.clone();
	p->set_location(l);

	unit_map::umap_retval_pair_t res(insert(p));
	if(res.second == false) {
		p.reset();
	}

	return res;
}
예제 #12
0
파일: radix_sort.c 프로젝트: dnlzz/hw6
int main(int argc,char **argv) {

  long int del_sec,del_msec;
  // struct timeval tv_s,tv_e;
  int group = 4;

  if (argc>1) n = atoi(argv[1]);
  else n = NELM;
  printf("n=%d\n",n);
  init_lst(lst,n);
  // print_lst(lst,n);

  // gettimeofday(&tv_s, NULL); 
  // selection_sort(lst,n);
  //  merge_sort(lst,tmp,n);

  int *src, * dest;

  src = lst;
  dest = tmp;

  // printf("%x  :  %x\n", src, lst);
  // printf("%x  :  %x\n", dest, tmp);

  //   printf("%x  :  %x\n", src, &lst);
  // printf("%x  :  %x\n", dest, &tmp);

  for (int iii = 0; iii < 32; iii += group) {
    int_radix_sort(src, dest, n, iii);
    
    int *temp;
    temp = src;
    src = dest;
    dest = temp;

  }

  //  float_radix_sort(lst,tmp,n);
  // gettimeofday(&tv_e, NULL); 

  /****
    PRINT elapsed time in sec and milli secs
  ****/

  // print_lst(lst,n);
  self_check(lst, n);
  return 0;
}
예제 #13
0
파일: error.c 프로젝트: BluePanM/code
void
crb_runtime_error(int line_number, RuntimeError id, ...)
{
    va_list     ap;
    VString     message;

    self_check();
    va_start(ap, id);
    clear_v_string(&message);
    format_message(&crb_runtime_error_message_format[id],
                   &message, ap);
    fprintf(stderr, "%3d:%s\n", line_number, message.string);
    va_end(ap);

    exit(1);
}
예제 #14
0
파일: error.c 프로젝트: BluePanM/code
void
crb_compile_error(CompileError id, ...)
{
    va_list     ap;
    VString     message;
    int         line_number;

    self_check();
    va_start(ap, id);
    line_number = crb_get_current_interpreter()->current_line_number;
    clear_v_string(&message);
    format_message(&crb_compile_error_message_format[id],
                   &message, ap);
    fprintf(stderr, "%3d:%s\n", line_number, message.string);
    va_end(ap);

    exit(1);
}
예제 #15
0
파일: error.c 프로젝트: 3man/devlang
void
crb_runtime_error(int line_number, RuntimeError id, ...)
{
    va_list     ap;
    VString     message;

    self_check();
    va_start(ap, id);
    crb_vstr_clear(&message);
    format_message(line_number,
                   &crb_runtime_error_message_format[id],
                   &message, ap);
    fprintf(stderr, "%3d:", line_number);
    CRB_print_wcs_ln(stderr, message.string);
    va_end(ap);

    exit(1);
}
int main(int argc, char **argv) {
	if (!self_check()) {
		printf("Self-check failed\n");
		return 1;
	}
	printf("Self-check passed\n");
	
	// Benchmark speed
	uint64_t state[8] = {};
	uint64_t block[16] = {};
	const int N = 3000000;
	clock_t start_time = clock();
	int i;
	for (i = 0; i < N; i++)
		sha512_compress(state, (uint8_t *)block);  // Type-punning
	printf("Speed: %.1f MiB/s\n", (double)N * sizeof(block) / (clock() - start_time) * CLOCKS_PER_SEC / 1048576);
	
	return 0;
}
예제 #17
0
/* Look for self-reference in assignment to newly declared variable */
void self_check(node_ptr dnode, node_ptr enode)
{
  int i;
  node_ptr vnode = dnode;
  if (!enode)
    return;
  /* First find variable node (in case of array) */
  while (vnode && vnode->ntype != E_LVAR && vnode->ntype != E_LAVAR)
    vnode = vnode->children[0];
  if (!vnode) {
    fprintf(ERRFILE, "Error (self_check).  No declared variable found\n");
    exit(1);
  }
  if ((enode->ntype == E_LVAR || enode->ntype == E_AVAR || enode->ntype == E_LAVAR) &&
      !strcmp(enode->name, vnode->name))
    yyserror("Invalid reference to newly-declared variable '%s'", vnode->name);
  for (i = 0; i < enode->degree; i++)
    self_check(vnode, enode->children[i]);
}
예제 #18
0
int main(void) {
	// Self-check
	if (!self_check()) {
		printf("Self-check failed\n");
		return EXIT_FAILURE;
	}
	printf("Self-check passed\n");
	
	// Benchmark speed
	uint32_t state[STATE_LEN] = {0};
	uint8_t block[BLOCK_LEN] = {0};
	const long ITERS = 3000000;
	clock_t start_time = clock();
	for (long i = 0; i < ITERS; i++)
		sha256_compress(state, block);
	printf("Speed: %.1f MB/s\n", (double)ITERS * (sizeof(block) / sizeof(block[0]))
		/ (clock() - start_time) * CLOCKS_PER_SEC / 1000000);
	
	return EXIT_SUCCESS;
}
예제 #19
0
파일: error.c 프로젝트: 3man/devlang
void
dvm_error(DVM_Executable *exe, Function *func, int pc, RuntimeError id, ...)
{
    va_list     ap;
    VString     message;
    int         line_number;

    self_check();
    va_start(ap, id);

    dvm_vstr_clear(&message);
    format_message(&dvm_error_message_format[id],
                   &message, ap);

    if (pc != NO_LINE_NUMBER_PC) {
        line_number = conv_pc_to_line_number(exe, func, pc);
        fprintf(stderr, "%3d:", line_number);
    }
    dvm_print_wcs_ln(stderr, message.string);
    va_end(ap);

    exit(1);
}
예제 #20
0
/* ARGSUSED */
void
sm_mon_svc(mon *monp, sm_stat_res *resp)
{
	mon_id *monidp;
	monidp = &monp->mon_id;

	rw_rdlock(&thr_rwlock);
	if (debug) {
		(void) printf("proc sm_mon: mon_name = %s, id = %d\n",
		    monidp->mon_name, * ((int *)monp->priv));
		pr_mon(monp->mon_id.mon_name);
	}

	/* only monitor other hosts */
	if (self_check(monp->mon_id.mon_name) == 0) {
		/* store monitor request into monitor_q */
		insert_mon(monp);
	}

	pr_mon(monp->mon_id.mon_name);
	resp->res_stat = stat_succ;
	resp->state = local_state;
	rw_unlock(&thr_rwlock);
}
예제 #21
0
unit_map::t_ilist::iterator unit_map::begin_core() const {
	self_check();
	t_ilist::iterator i = ilist_.begin();
	while (i != the_end_ && (i->unit == NULL)) { ++i; }
	return i;
}
예제 #22
0
unit_map::unit_iterator unit_map::find(const map_location &loc) {
	self_check();
	return make_unit_iterator<t_lmap::iterator>(lmap_.find(loc) ); }
예제 #23
0
unit_map::unit_iterator unit_map::find(size_t id) {
	self_check();
	t_umap::iterator i(umap_.find(id));
	if((i != umap_.end()) && i->second->unit==NULL){ i = umap_.end() ;}
	return make_unit_iterator<t_umap::iterator>( i ); }
예제 #24
0
/** Inserts the unit pointed to by @a p into the unit_map.

It needs to succeed on the insertion to the umap and to the lmap
otherwise all operations are reverted.
1. Insert a unit_pod into the list
2. Try insertion into the umap and remove the list item on failure
3. Try insertion in the lmap and remove the umap and the list item on failure

The one oddity is that to facilitate non-invalidating iterators the list
sometimes has NULL pointers which should be used when they correspond
to uids previously used.
 */
std::pair<unit_map::unit_iterator, bool> unit_map::insert(unit *p) {
	self_check();
	assert(p);

	size_t unit_id = p->underlying_id();
	const map_location &loc = p->get_location();

	if (!loc.valid()) {
		ERR_NG << "Trying to add " << p->name()
			<< " - " << p->id() << " at an invalid location; Discarding.\n";
		return std::make_pair(make_unit_iterator(the_end_), false);
	}

	unit_pod upod;
	upod.unit = p;
	upod.deleted_uid = unit_id;
	ilist_.push_front(upod);
	t_ilist::iterator lit(ilist_.begin());

	DBG_NG << "Adding unit " << p->underlying_id() << " - " << p->id()
		<< " to location: (" << loc << ")\n";

	std::pair<t_umap::iterator, bool> uinsert = umap_.insert(std::make_pair(unit_id, lit ));

	if (! uinsert.second) {
		//If the UID is empty reinsert the unit in the same list element
		if ( uinsert.first->second->unit == NULL) {
			ilist_.pop_front();
			lit = uinsert.first->second;
			lit->unit = p;
			assert(lit->ref_count != 0);
		} else {
			unit *q = uinsert.first->second->unit;
			ERR_NG << "Trying to add " << p->name()
				   << " - " << p->id() << " - " << p->underlying_id()
				   << " ("  << loc << ") over " << q->name()
				   << " - " << q->id() << " - " << q->underlying_id()
				   << " ("  << q->get_location()
				   << "). The new unit will be assigned underlying_id="
				   << (1 + n_unit::id_manager::instance().get_save_id())
				   << " to prevent duplicate id conflicts.\n";

			p->clone(false);
			uinsert = umap_.insert(std::make_pair(p->underlying_id(), lit ));
			int guard(0);
			while (!uinsert.second && (++guard < 1e6) ) {
				if(guard % 10 == 9){
					ERR_NG << "\n\nPlease Report this error to https://gna.org/bugs/index.php?18591 "
						"\nIn addition to the standard details of operating system and wesnoth version "
						"and how it happened, please answer the following questions "
						"\n 1. Were you playing mutli-player?"
						"\n 2. Did you start/restart/reload the game/scenario?"
						"\nThank you for your help in fixing this bug.\n";
				}
				p->clone(false);
				uinsert = umap_.insert(std::make_pair(p->underlying_id(), lit )); }
			if (!uinsert.second) {
				throw "One million collisions in unit_map"; }
		}
	}

	std::pair<t_lmap::iterator,bool> linsert = lmap_.insert(std::make_pair(loc, lit ));

	//Fail if the location is occupied
	if(! linsert.second) {
		if(lit->ref_count == 0) {
			//Undo a virgin insertion
			ilist_.pop_front();
			///@todo replace with quick_erase(i) when wesnoth supports  boost 1.42 min version
			umap_.erase(uinsert.first);
		} else {
			//undo a reinsertion
			uinsert.first->second->unit = NULL;
		}
		DBG_NG << "Trying to add " << p->name()
			   << " - " << p->id() << " at location ("<<loc <<"); Occupied  by "
			   <<(linsert.first->second)->unit->name()<< " - " << linsert.first->second->unit->id() <<"\n";

		return std::make_pair(make_unit_iterator(the_end_), false);
	}

	self_check();
	return std::make_pair( make_unit_iterator( lit ), true);
}
int main(void) {
	// Sanity test
	if (!self_check()) {
		fprintf(stderr, "Self-check failed\n");
		return EXIT_FAILURE;
	}
	benchmark();
	
	// Set up the SHA-512 processed blocks: Message (28 bytes), terminator and padding (96 bytes), length (16 bytes)
	uint8_t (*blocks)[16][NUM_CH][8] = calloc(num_threads * 16 * NUM_CH * 8, sizeof(uint8_t));
	if (blocks == NULL) {
		perror("calloc");
		return EXIT_FAILURE;
	}
	{
		struct timespec ts;
		clock_gettime(CLOCK_REALTIME, &ts);
		uint64_t time = ts.tv_sec * UINT64_C(1000000000) + ts.tv_nsec;
		
		for (int i = 0; i < num_threads; i++) {
			for (int ch = 0; ch < NUM_CH; ch++) {
				uint8_t (*blks)[NUM_CH][8] = blocks[i];
				uint64_t temp = time + i * NUM_CH + ch;
				for (int j = 0; j < MSG_LEN / 2; j++, temp /= 26)
					set_byte(blks, j, ch, 'a' + temp % 26);
				for (int j = 0; j < MSG_LEN / 2; j++)
					set_byte(blks, j + MSG_LEN / 2, ch, 'a');
				set_byte(blks, MSG_LEN, ch, 0x80);
				set_byte(blks, 126, ch, MSG_LEN >> 5);
				set_byte(blks, 127, ch, MSG_LEN << 3);
			}
		}
	}
	
	// Initialize initial lowest hash
	memset(global_lowest_hash, 0xFF, sizeof(global_lowest_hash));
	global_lowest_hash[0] >>= 24;  // Exclude trivial matches
	
	// Launch threads
	pthread_t *threads = calloc(num_threads, sizeof(pthread_t));
	if (threads == NULL) {
		perror("calloc");
		return EXIT_FAILURE;
	}
	for (int i = 0; i < num_threads; i++)
		pthread_create(&threads[i], NULL, worker, blocks[i]);
	
	// Print status until threads finish
	while (true) {
		pthread_mutex_lock(&mutex);
		if (finished_threads >= num_threads) {
			pthread_mutex_unlock(&mutex);
			break;
		}
		
		char message[MSG_LEN + 1];
		get_message(blocks[0], 0, message);  // Only print thread 0, channel 0
		fprintf(stderr, "\rHash trials: %.3f billion (%s)", total_iterations * NUM_CH / 1.0e9, message);
		fflush(stderr);
		prev_print_type = 1;
		
		pthread_mutex_unlock(&mutex);
		sleep(10);
	}
	fprintf(stderr, "\nSearch space exhausted\n");
	
	// Clean up
	for (int i = 0; i < num_threads; i++)
		pthread_join(threads[i], NULL);
	free(blocks);
	free(threads);
	return EXIT_SUCCESS;
}
예제 #26
0
/** Inserts the unit pointed to by @a p into the unit_map.

It needs to succeed on the insertion to the umap and to the lmap
otherwise all operations are reverted.
1. Construct a unit_pod
2. Try insertion into the umap
3. Try insertion in the lmap and remove the umap entry on failure

The one oddity is that to facilitate non-invalidating iterators the list
sometimes has NULL pointers which should be used when they correspond
to uids previously used.
 */
std::pair<unit_map::unit_iterator, bool> unit_map::insert(unit_ptr p) {
	self_check();
	assert(p);

	size_t unit_id = p->underlying_id();
	const map_location &loc = p->get_location();

	if (!loc.valid()) {
		ERR_NG << "Trying to add " << p->name()
			<< " - " << p->id() << " at an invalid location; Discarding.\n";
		return std::make_pair(make_unit_iterator(umap_.end()), false);
	}

	unit_pod upod;
	upod.unit = p ;

	DBG_NG << "Adding unit " << p->underlying_id() << " - " << p->id()
		<< " to location: (" << loc << ")\n";

	std::pair<t_umap::iterator, bool> uinsert = umap_.insert(std::make_pair(unit_id, upod ));

	if (! uinsert.second) {
		//If the pod is empty reinsert the unit in the same list element
		if (!uinsert.first->second.unit) {
			unit_pod &opod = uinsert.first->second;
			opod.unit = p ;
			assert(opod.ref_count != 0);
		} else {
			unit_ptr q = uinsert.first->second.unit;
			ERR_NG << "Trying to add " << p->name()
				   << " - " << p->id() << " - " << p->underlying_id()
				   << " ("  << loc << ") over " << q->name()
				   << " - " << q->id() << " - " << q->underlying_id()
				   << " ("  << q->get_location()
				   << ").";

			p->clone(false);
			ERR_NG << "The new unit was assigned underlying_id="
				   << p->underlying_id()
				   << " to prevent duplicate id conflicts.\n";

			uinsert = umap_.insert(std::make_pair(p->underlying_id(), upod ));
			int guard(0);
			while (!uinsert.second && (++guard < 1e6) ) {
				if(guard % 10 == 9){
					ERR_NG << "\n\nPlease Report this error to https://gna.org/bugs/index.php?18591 "
						"\nIn addition to the standard details of operating system and wesnoth version "
						"and how it happened, please answer the following questions "
						"\n 1. Were you playing multi-player?"
						"\n 2. Did you start/restart/reload the game/scenario?"
						"\nThank you for your help in fixing this bug.\n";
				}
				p->clone(false);
				uinsert = umap_.insert(std::make_pair(p->underlying_id(), upod )); }
			if (!uinsert.second) {
				throw game::error("One million collisions in unit_map"); }
		}
	}

	std::pair<t_lmap::iterator,bool> linsert = lmap_.insert(std::make_pair(loc, uinsert.first ));

	//Fail if the location is occupied
	if(! linsert.second) {
		if(upod.ref_count == 0) {
			//Undo a virgin insertion
			umap_.erase(uinsert.first);
		} else {
			//undo a reinsertion
			uinsert.first->second.unit.reset();
		}
		DBG_NG << "Trying to add " << p->name()
			   << " - " << p->id() << " at location ("<<loc <<"); Occupied  by "
			   <<(linsert.first->second->second).unit->name()<< " - " << linsert.first->second->second.unit->id() <<"\n";

		return std::make_pair(make_unit_iterator(umap_.end()), false);
	}

	self_check();
	return std::make_pair( make_unit_iterator( uinsert.first ), true);
}
예제 #27
0
파일: automount.c 프로젝트: RomiPierre/osx
int
main(int argc, char *argv[])
{
	long timeout_val;
	int c;
	int flushcache = 0;
	int unmount_automounted = 0;	// Unmount automounted mounts
	struct autodir *dir, *d;
	char real_mntpnt[PATH_MAX];
	struct stat stbuf;
	char *master_map = "auto_master";
	int null;
	struct statfs *mntp;
	int count = 0;
	char *stack[STACKSIZ];
	char **stkptr;
	char *defval;
	int fd;
	int flags, altflags;
	struct staticmap *static_ent;

	/*
	 * Read in the values from config file first before we check
	 * commandline options so the options override the file.
	 */
	if ((defopen(AUTOFSADMIN)) == 0) {
		if ((defval = defread("AUTOMOUNT_TIMEOUT=")) != NULL) {
			errno = 0;
			timeout_val = strtol(defval, (char **)NULL, 10);
			if (errno == 0 && timeout_val > 0 &&
			    timeout_val <= INT_MAX)
				mount_timeout = (int)timeout_val;
		}
		if ((defval = defread("AUTOMOUNT_VERBOSE=")) != NULL) {
			if (strncasecmp("true", defval, 4) == 0)
				verbose = TRUE;
			else
				verbose = FALSE;
		}
		if ((defval = defread("AUTOMOUNTD_TRACE=")) != NULL) {
			/*
			 * Turn on tracing here too if the automountd
			 * is set up to do it - since automount calls
			 * many of the common library functions.
			 */
			errno = 0;
			trace = (int)strtol(defval, (char **)NULL, 10);
			if (errno != 0)
				trace = 0;
		}

		/* close defaults file */
		defopen(NULL);
	}

	while ((c = getopt(argc, argv, "mM:D:f:t:vcu?")) != EOF) {
		switch (c) {
		case 'm':
			pr_msg("Warning: -m option not supported");
			break;
		case 'M':
			pr_msg("Warning: -M option not supported");
			break;
		case 'D':
			pr_msg("Warning: -D option not supported");
			break;
		case 'f':
			pr_msg("Error: -f option no longer supported");
			usage();
			break;
		case 't':
			if (strchr(optarg, '=')) {
				pr_msg("Error: invalid value for -t");
				usage();
			}
			mount_timeout = atoi(optarg);
			break;
		case 'v':
			verbose++;
			break;
		case 'c':
			flushcache++;
			break;
		case 'u':
			unmount_automounted++;
			break;
		default:
			usage();
			break;
		}
	}

	if (optind < argc) {
		pr_msg("%s: command line mountpoints/maps "
			"no longer supported",
			argv[optind]);
		usage();
	}

	/*
	 * Get an array of current system mounts
	 */
	num_current_mounts = getmntinfo(&current_mounts, MNT_NOWAIT);
	if (num_current_mounts == 0) {
		pr_msg("Couldn't get current mounts: %m");
		exit(1);
	}

	autofs_control_fd = open("/dev/" AUTOFS_CONTROL_DEVICE, O_RDONLY);
	if (autofs_control_fd == -1 && errno == ENOENT) {
		/*
		 * Oops, we probably don't have the autofs kext
		 * loaded.
		 */
		FTS *fts;
		static char *const paths[] = { "/Network", NULL };
		FTSENT *ftsent;
		int error;

		/*
		 * This means there can't be any autofs mounts yet, so
		 * this is the first time we're being run since a reboot.
		 * Clean out any stuff left in /Network from the reboot.
		 */
		fts = fts_open(paths, FTS_NOCHDIR|FTS_PHYSICAL|FTS_XDEV,
		    NULL);
		if (fts != NULL) {
			while ((ftsent = fts_read(fts)) != NULL) {
				/*
				 * We only remove directories - if
				 * there are files, we assume they're
				 * there for a purpose.
				 *
				 * We remove directories after we've
				 * removed their children, so we want
				 * to process directories visited in
				 * post-order.
				 *
				 * We don't remove /Network itself.
				 */
				if (ftsent->fts_info == FTS_DP &&
				    ftsent->fts_level > FTS_ROOTLEVEL)
					rmdir(ftsent->fts_accpath);
			}
			fts_close(fts);
		}

		/*
		 * Now load it.
		 */
		error = load_autofs();
		if (error != 0) {
			pr_msg("can't load autofs kext");
			exit(1);
		}

		/*
		 * Try the open again.
		 */
		autofs_control_fd = open("/dev/" AUTOFS_CONTROL_DEVICE,
		    O_RDONLY);
	}
	if (autofs_control_fd == -1) {
		if (errno == EBUSY)
			pr_msg("Another automount is running");
		else
			pr_msg("Couldn't open %s: %m", "/dev/" AUTOFS_CONTROL_DEVICE);
		exit(1);
	}

	/*
	 * Update the mount timeout.
	 */
	if (ioctl(autofs_control_fd, AUTOFS_SET_MOUNT_TO, &mount_timeout) == -1)
		pr_msg("AUTOFS_SET_MOUNT_TO failed: %m");

	/*
	 * Attempt to unmount any non-busy triggered mounts; this includes
	 * not only autofs mounts, but, for example SMB Dfs mounts.
	 *
	 * This is done before sleep, and after a network change, to
	 * try to get rid of as many network mounts as we can; each
	 * unmounted network mount is a network mount on which we
	 * can't hang.
	 */
	if (unmount_automounted) {
		if (verbose)
			pr_msg("Unmounting triggered mounts");
		if (ioctl(autofs_control_fd, AUTOFS_UNMOUNT_TRIGGERED, 0) == -1)
			pr_msg("AUTOFS_UNMOUNT_TRIGGERED failed: %m");
		exit(0);
	}

	if (flushcache) {
		/*
		 * Notify the automounter that it should flush its caches,
		 * as we might be on a different network with different maps.
		 */
		if (ioctl(autofs_control_fd, AUTOFS_NOTIFYCHANGE, 0) == -1)
			pr_msg("AUTOFS_NOTIFYCHANGE failed: %m");
	}

	(void) umask(0);
	ns_setup(stack, &stkptr);

	(void) loadmaster_map(master_map, "", stack, &stkptr);

	/*
	 * Mount the daemon at its mount points.
	 */
	for (dir = dir_head; dir; dir = dir->dir_next) {

		if (realpath(dir->dir_name, real_mntpnt) == NULL) {
			/*
			 * We couldn't get the real path for this,
			 * perhaps because it doesn't exist.
			 * If it's not because it doesn't exist, just
			 * give up on this entry.  Otherwise, just null
			 * out the real path - we'll try creating the
			 * directory later, and will set dir_realpath
			 * then, if that succeeds.
			 */
			if (errno != ENOENT) {
				pr_msg("%s: Can't convert to real path: %m",
				    dir->dir_name);
				continue;
			}
			dir->dir_realpath = NULL;
		} else {
			dir->dir_realpath = strdup(real_mntpnt);
			if (dir->dir_realpath == NULL) {
				pr_msg("Couldn't allocate real path: %m");
				exit(1);
			}
		}

		/*
		 * Skip null entries
		 */
		if (strcmp(dir->dir_map, "-null") == 0)
			continue;

		/*
		 * Skip null'ed entries
		 */
		null = 0;
		for (d = dir->dir_prev; d; d = d->dir_prev) {
			if (paths_match(dir, d))
				null = 1;
		}
		if (null)
			continue;

		/*
		 * If this is -fstab, and there are no fstab "net" entries,
		 * skip this map if our directory search path doesn't
		 * include Active Directory.  We don't want /Network/Servers
		 * (or wherever it shows up) to exist if this system isn't
		 * using AD (AD supplies fstab entries on the fly, so they
		 * might not exist right now) and we don't have any fstab
		 * entries.
		 */
		if (strcmp(dir->dir_map, "-fstab") == 0) {
			if (!have_ad() && !havefstabkeys()) {
				/*
				 * We're not using AD, and fstab is
				 * inaccessible or devoid of "net" entries.
				 */
				free(dir->dir_map);
				dir->dir_map = strdup("-null");
				continue;
			}
			endfsent();
		}

		/*
		 * If this is -fstab or -static, and there's another entry
		 * that's supposed to mount something on the same directory
		 * and isn't "-fstab" or "-static", ignore this; we might
		 * have a server that's supplying real automounter maps for
		 * the benefit of OS X systems with autofs and also supplying
		 * fstab entries for the benefit of older OS X systems, and
		 * we want to mount the real automounter map, not the -fstab
		 * or -static map, in that case.
		 */
		if (strcmp(dir->dir_map, "-fstab") == 0 ||
		    strcmp(dir->dir_map, "-static") == 0) {
			for (d = dir_head; d; d = d->dir_next) {
				if (paths_match(dir, d) &&
				    strcmp(d->dir_map, "-fstab") != 0 &&
				    strcmp(d->dir_map, "-static") != 0) {
					pr_msg("%s: ignoring redundant %s map",
					    dir->dir_name, dir->dir_map);
					break;
				}
			}
			if (d != NULL) {
				continue;
			}
		}

		/*
		 * Parse the mount options and get additional flags to pass
		 * to mount() (standard mount options) and autofs mount
		 * options.
		 *
		 * XXX - we ignore flags on an update; if they're different
		 * from the current flags for that mount, we'd need to do a
		 * remount.
		 */
		if (!parse_mntopts(dir->dir_opts, &flags, &altflags)) {
			/*
			 * Failed.
			 */
			continue;
		}

		/*
		 * If this is -static, check whether the entry refers
		 * to this host; if so, make the appropriate symlink
		 * exist at the "mount point" path.
		 */
		if (strcmp(dir->dir_map, "-static") == 0) {
			static_ent = get_staticmap_entry(dir->dir_name);
			if (static_ent == NULL) {
				/*
				 * Whiskey tango foxtrot?  There should
				 * be an entry here.  Log an error and
				 * ignore this mount.
				 */
				pr_msg("can't find fstab entry for %s",
				    dir->dir_name);
				continue;
			}
			if (host_is_us(static_ent->host, strlen(static_ent->host)) ||
			    self_check(static_ent->host)) {
				/*
				 * Yup, this is us.
				 * Try to make the appropriate symlink.
				 */
				make_symlink(static_ent->localpath,
				    dir->dir_name);
				release_staticmap_entry(static_ent);
				continue;
			}
			release_staticmap_entry(static_ent);
		}

		/*
		 * Check whether there's already an entry
		 * in the mnttab for this mountpoint.
		 */
		if (dir->dir_realpath != NULL &&
		    (mntp = find_mount(dir->dir_realpath)) != NULL) {
			struct autofs_update_args au;

			/*
			 * If it's not an autofs mount - don't
			 * mount over it.
			 */
			if (strcmp(mntp->f_fstypename, MNTTYPE_AUTOFS) != 0) {
				pr_msg("%s: already mounted on %s",
					mntp->f_mntfromname, dir->dir_realpath);
				continue;
			}

			/*
			 * This is already mounted, so just update it.
			 * We don't bother to check whether any options are
			 * changing, as we'd have to make a trip into the
			 * kernel to get the current options to check them,
			 * so we might as well just make a trip to do the
			 * update.
			 */
			au.fsid		= mntp->f_fsid;
			au.opts		= dir->dir_opts;
			au.map		= dir->dir_map;
			au.mntflags	= altflags;
			au.direct 	= dir->dir_direct;
			au.node_type	= dir->dir_direct ? NT_TRIGGER : 0;

			if (ioctl(autofs_control_fd, AUTOFS_UPDATE_OPTIONS,
			    &au) < 0) {
				pr_msg("update %s: %m", dir->dir_realpath);
				continue;
			}
			if (verbose)
				pr_msg("%s updated", dir->dir_realpath);
		} else {
			struct autofs_args ai;
			int st_flags = 0;

			/*
			 * This trigger isn't already mounted; either
			 * the path doesn't exist at all, or it
			 * exists but nothing is mounted on it.
			 *
			 * Create a mount point if necessary
			 * If the path refers to an existing symbolic
			 * link, refuse to mount on it.  This avoids
			 * future problems.  (We don't use dir->dir_realpath
			 * because that's never a symbolic link.)
			 */
			if (lstat(dir->dir_name, &stbuf) == 0) {
				if ((stbuf.st_mode & S_IFMT) != S_IFDIR) {
					pr_msg("%s: Not a directory", dir->dir_name);
					continue;
				}
				st_flags = stbuf.st_flags;

				/*
				 * Either realpath() succeeded or it
				 * failed with ENOENT; otherwise, we
				 * would have quit before getting here.
				 *
				 * If it failed, report an error, as
				 * the problem isn't that "dir->dir_name"
				 * doesn't exist, the problem is that,
				 * somehow, we got ENOENT even though
				 * it exists.
				 */
				if (dir->dir_realpath == NULL) {
					errno = ENOENT;
					pr_msg("%s: Can't convert to real path: %m",
					    dir->dir_name);
					continue;
				}
			} else {
				/*
				 * Mountpoint doesn't exist.
				 *
				 * Create it unless it's under /Volumes.
				 * At boot time it's possible the volume
				 * containing the mountpoint hasn't mounted yet.
				 */
				if (strncmp(dir->dir_name, "/Volumes/", 9) == 0) {
					pr_msg("%s: mountpoint unavailable", dir->dir_name);
					continue;
				}

				if (mkdir_r(dir->dir_name)) {
					pr_msg("%s: %m", dir->dir_name);
					continue;
				}

				/*
				 * realpath() presumably didn't succeed,
				 * as dir->dir_name couldn't be statted.
				 * Call it again, to get the real path
				 * corresponding to the newly-created
				 * mount point.
				 */
				if (realpath(dir->dir_name, real_mntpnt) == NULL) {
					/*
					 * Failed.
					 */
					pr_msg("%s: Can't convert to real path: %m",
					    dir->dir_name);
					continue;
				}
				dir->dir_realpath = strdup(real_mntpnt);
				if (dir->dir_realpath == NULL) {
					pr_msg("Couldn't allocate real path for %s: %m",
					    dir->dir_name);
					continue;
				}
			}

			/*
			 * If the "hidefromfinder" option is set for
			 * this autofs mountpoint then also set the
			 * UF_HIDDEN bit on the directory so it'll still
			 * be invisible to the Finder even if not mounted on.
			 */
			if (altflags & AUTOFS_MNT_HIDEFROMFINDER)
				st_flags |= UF_HIDDEN;
			else
				st_flags &= ~UF_HIDDEN;
			if (chflags(dir->dir_name, st_flags) < 0)
				pr_msg("%s: can't set hidden", dir->dir_name);

			/*
			 * Mount it.  Use the real path (symlink-free),
			 * for reasons mentioned above.
			 */
			ai.version	= AUTOFS_ARGSVERSION;
			ai.path 	= dir->dir_realpath;
			ai.opts		= dir->dir_opts;
			ai.map		= dir->dir_map;
			ai.subdir	= "";
			ai.direct 	= dir->dir_direct;
			if (dir->dir_direct)
				ai.key = dir->dir_name;
			else
				ai.key = "";
			ai.mntflags	= altflags;
			ai.mount_type	= MOUNT_TYPE_MAP;	/* top-level autofs mount */
			ai.node_type	= dir->dir_direct ? NT_TRIGGER : 0;

			if (mount(MNTTYPE_AUTOFS, dir->dir_realpath,
			    MNT_DONTBROWSE | MNT_AUTOMOUNTED | flags,
			    &ai) < 0) {
				pr_msg("mount %s: %m", dir->dir_realpath);
				continue;
			}
			if (verbose)
				pr_msg("%s mounted", dir->dir_realpath);
		}

		count++;
	}

	if (verbose && count == 0)
		pr_msg("no mounts");

	/*
	 * Now compare the /etc/mnttab with the master
	 * map.  Any autofs mounts in the /etc/mnttab
	 * that are not in the master map must be
	 * unmounted
	 *
	 * XXX - if there are no autofs mounts left, should we
	 * unload autofs, or arrange that it be unloaded?
	 */
	do_unmounts();

	/*
	 * Let PremountHomeDirectoryWithAuthentication() know that we're
	 * done.
	 */
	fd = open("/var/run/automount.initialized", O_CREAT|O_WRONLY, 0600);
	close(fd);

	return (0);
}