Example #1
0
/*
 * v_dtoh --
 *	Move all but the current screen to the hidden queue.
 */
static void
v_dtoh(SCR *sp)
{
	GS *gp;
	SCR *tsp;
	WIN *wp;
	int hidden;

	/* Move all screens to the hidden queue, tossing screen maps. */
	for (hidden = 0, gp = sp->gp, wp = sp->wp;
	    (tsp = wp->scrq.cqh_first) != (void *)&wp->scrq; ++hidden) {
		if (_HMAP(tsp) != NULL) {
			free(_HMAP(tsp));
			_HMAP(tsp) = NULL;
		}
		CIRCLEQ_REMOVE(&wp->scrq, tsp, q);
		CIRCLEQ_INSERT_TAIL(&gp->hq, tsp, q);
		/* XXXX Change if hidden screens per window */
		tsp->wp = 0;
		gp->scr_discard(tsp, NULL);
	}

	/* Move current screen back to the display queue. */
	CIRCLEQ_REMOVE(&gp->hq, sp, q);
	CIRCLEQ_INSERT_TAIL(&wp->scrq, sp, q);
	sp->wp = wp;

	if (hidden > 1)
		msgq(sp, M_INFO,
		    "319|%d screens backgrounded; use :display to list them",
		    hidden - 1);
}
Example #2
0
File: iod.c Project: Yomin/neobox
int rem_client(int pos, struct chain_socket *cs)
{
    int active = cs == client_list.cqh_first;
    DEBUG(int fd = cs->sock);
    DEBUG(pid_t pid = cs->pid);
    
    memmove(pfds+pos, pfds+pos+1, (client_count-1)*sizeof(struct pollfd));
    CIRCLEQ_REMOVE(&client_list, cs, chain);
    free(cs);
    client_count--;
    
    if(client_list.cqh_first != (void*)&client_list)
    {
        if(active)
        {
            if((cs = client_list_rotate_next(0))->hide)
                DEBUG(printf("Active client removed [%i] %i, switch invisible [%i] %i\n",
                    fd, pid, cs->sock, cs->pid));
            else
                DEBUG(printf("Active client removed [%i] %i, switch [%i] %i\n",
                    fd, pid, cs->sock, cs->pid));
            return 1;
        }
        else
        {
            DEBUG(printf("Client removed [%i] %i\n", fd, pid));
            return 0;
        }
    }
    else
    {
        DEBUG(printf("Active client removed [%i] %i, last\n", fd, pid));
        return 0;
    }
}
Example #3
0
File: log.c Project: odit/rv042
/* log a line to cur_connection's log */
static void
peerlog(const char *prefix, const char *m)
{
    if (cur_connection == NULL)
    {
	/* we can not log it in this case. Oh well. */
	return;
    }

    if (cur_connection->log_file == NULL)
    {
	open_peerlog(cur_connection);
    }

    /* despite our attempts above, we may not be able to open the file. */
    if (cur_connection->log_file != NULL)
    {
	char datebuf[32];
	time_t n;
	struct tm *t;

	time(&n);
	t = localtime(&n);

	strftime(datebuf, sizeof(datebuf), "%Y-%m-%d %T", t);
	fprintf(cur_connection->log_file, "%s %s%s\n", datebuf, prefix, m);

	/* now move it to the front of the list */
	CIRCLEQ_REMOVE(&perpeer_list, cur_connection, log_link);
	CIRCLEQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);
    }
}
Example #4
0
void
in6_pcbdetach(struct in6pcb *in6p)
{
	struct socket *so = in6p->in6p_socket;
	int s;

	if (in6p->in6p_af != AF_INET6)
		return;

#if defined(IPSEC) || defined(FAST_IPSEC)
	ipsec6_delete_pcbpolicy(in6p);
#endif /* IPSEC */
	so->so_pcb = 0;
	if (in6p->in6p_options)
		m_freem(in6p->in6p_options);
	if (in6p->in6p_outputopts != NULL) {
		ip6_clearpktopts(in6p->in6p_outputopts, -1);
		free(in6p->in6p_outputopts, M_IP6OPT);
	}
	rtcache_free(&in6p->in6p_route);
	ip6_freemoptions(in6p->in6p_moptions);
	s = splnet();
	in6_pcbstate(in6p, IN6P_ATTACHED);
	LIST_REMOVE(&in6p->in6p_head, inph_lhash);
	CIRCLEQ_REMOVE(&in6p->in6p_table->inpt_queue, &in6p->in6p_head,
	    inph_queue);
	pool_put(&in6pcb_pool, in6p);
	splx(s);
	sofree(so);				/* drops the socket's lock */
	mutex_enter(softnet_lock);		/* reacquire it */
}
Example #5
0
File: iod.c Project: Yomin/neobox
void free_clients()
{
    struct chain_socket *cs;
    while((cs = client_list.cqh_first) != (void*)&client_list)
    {
        CIRCLEQ_REMOVE(&client_list, cs, chain);
        free(cs);
    }
}
Example #6
0
File: exf.c Project: fishman/nvi
/*
 * file_add --
 *	Insert a file name into the FREF list, if it doesn't already
 *	appear in it.
 *
 * !!!
 * The "if it doesn't already appear" changes vi's semantics slightly.  If
 * you do a "vi foo bar", and then execute "next bar baz", the edit of bar
 * will reflect the line/column of the previous edit session.  Historic nvi
 * did not do this.  The change is a logical extension of the change where
 * vi now remembers the last location in any file that it has ever edited,
 * not just the previously edited file.
 *
 * PUBLIC: FREF *file_add __P((SCR *, char *));
 */
FREF *
file_add(SCR *sp, char *name)
{
    GS *gp;
    FREF *frp, *tfrp;

    /*
     * Return it if it already exists.  Note that we test against the
     * user's name, whatever that happens to be, including if it's a
     * temporary file.
     *
     * If the user added a file but was unable to initialize it, there
     * can be file list entries where the name field is NULL.  Discard
     * them the next time we see them.
     */
    gp = sp->gp;
    if (name != NULL)
        for (frp = gp->frefq.cqh_first;
                frp != (FREF *)&gp->frefq; frp = frp->q.cqe_next) {
            if (frp->name == NULL) {
                tfrp = frp->q.cqe_next;
                CIRCLEQ_REMOVE(&gp->frefq, frp, q);
                if (frp->name != NULL)
                    free(frp->name);
                free(frp);
                frp = tfrp;
                continue;
            }
            if (!strcmp(frp->name, name))
                return (frp);
        }

    /* Allocate and initialize the FREF structure. */
    CALLOC(sp, frp, FREF *, 1, sizeof(FREF));
    if (frp == NULL)
        return (NULL);

    /*
     * If no file name specified, or if the file name is a request
     * for something temporary, file_init() will allocate the file
     * name.  Temporary files are always ignored.
     */
    if (name != NULL && strcmp(name, TEMPORARY_FILE_STRING) &&
            (frp->name = strdup(name)) == NULL) {
        free(frp);
        msgq(sp, M_SYSERR, NULL);
        return (NULL);
    }

    /* Append into the chain of file names. */
    CIRCLEQ_INSERT_TAIL(&gp->frefq, frp, q);

    return (frp);
}
Example #7
0
static void perpeer_logclose(struct connection *c)
{
	/* only free/close things if we had used them! */
	if (c->log_file != NULL) {
		passert(perpeer_count > 0);

		CIRCLEQ_REMOVE(&perpeer_list, c, log_link);
		perpeer_count--;
		fclose(c->log_file);
		c->log_file = NULL;
	}
}
Example #8
0
/*
 * Close specified map.
 */
void
ypdb_close_map(struct opt_map *map)
{
	CIRCLEQ_REMOVE(&maps, map, mapsq);	/* remove from LRU circleq */
	LIST_REMOVE(map, mapsl);		/* remove from domain list */

#ifdef DEBUG
	syslog(LOG_DEBUG,
	    "ypdb_close_map: closing map %s in domain %s [db=%p]",
	    map->map, map->dom->domain, map->db);
#endif

	ypdb_close(map->db);			/* close DB */
	free(map->map);				/* free map name */
	free(map);				/* free map */
}
Example #9
0
/**
 * De-regsiter a thread and de-allocate all resources. This function
 * should be called when a thread exits.
 */
void rec_sched_deregister_thread(struct task** t_ptr)
{
	struct task* t = *t_ptr;
	pid_t tid = t->tid;
	struct tasklist_entry* entry = get_entry(tid);

	if (entry == current_entry) {
		current_entry = next_entry(entry);
		if (entry == current_entry) {
			assert(num_active_threads == 1);
			current_entry = NULL;
		}
	}

	/* We expect tasks to usually exit by a call to exit() or
	 * exit_group(), so it's not helpful to warn about that. */
	if (FIXEDSTACK_DEPTH(&t->pending_events) > 2
	    || !(t->ev->type == EV_SYSCALL
		 && (SYS_exit == t->ev->syscall.no
		     || SYS_exit_group == t->ev->syscall.no))) {
		log_warn("%d still has pending events.  From top down:",
			 t->tid);
		log_pending_events(t);
	}

	task_group_remove_and_unref(t);

	CIRCLEQ_REMOVE(&head, entry, entries);
	tid_to_entry[tid] = NULL;
	num_active_threads--;
	assert(num_active_threads >= 0);

	/* delete all counter data */
	cleanup_hpc(t);

	sys_close(t->child_mem_fd);
	close(t->desched_fd);

	detach_and_reap(t);

	/* finally, free the memory */
	sighandlers_unref(&t->sighandlers);
	sys_free((void**)entry);
	*t_ptr = NULL;
}
Example #10
0
File: log.c Project: mcr/Openswan
/* log a line to cur_connection's log */
static void
peerlog(const char *prefix, const char *m)
{
    if (cur_connection == NULL)
    {
	/* we can not log it in this case. Oh well. */
	return;
    }

    if (cur_connection->log_file == NULL)
    {
	open_peerlog(cur_connection);
    }

    /* despite our attempts above, we may not be able to open the file. */
    if (cur_connection->log_file != NULL)
    {
	fprintf(cur_connection->log_file, "%s %s%s\n", oswtimestr(), prefix, m);

	/* now move it to the front of the list */
	CIRCLEQ_REMOVE(&perpeer_list, cur_connection, log_link);
	CIRCLEQ_INSERT_HEAD(&perpeer_list, cur_connection, log_link);
    }
}
Example #11
0
/*
 * ex_txt --
 *	Get lines from the terminal for ex.
 *
 * PUBLIC: int ex_txt __P((SCR *, TEXTH *, ARG_CHAR_T, u_int32_t));
 */
int
ex_txt(SCR *sp, TEXTH *tiqh, ARG_CHAR_T prompt, u_int32_t flags)
{
	EVENT ev;
	GS *gp;
	TEXT ait, *ntp, *tp;
	carat_t carat_st;
	size_t cnt;
	int rval;

	rval = 0;

	/*
	 * Get a TEXT structure with some initial buffer space, reusing the
	 * last one if it's big enough.  (All TEXT bookkeeping fields default
	 * to 0 -- text_init() handles this.)
	 */
	if (tiqh->cqh_first != (void *)tiqh) {
		tp = tiqh->cqh_first;
		if (tp->q.cqe_next != (void *)tiqh || tp->lb_len < 32) {
			text_lfree(tiqh);
			goto newtp;
		}
		tp->len = 0;
	} else {
newtp:		if ((tp = text_init(sp, NULL, 0, 32)) == NULL)
			goto err;
		CIRCLEQ_INSERT_HEAD(tiqh, tp, q);
	}

	/* Set the starting line number. */
	tp->lno = sp->lno + 1;

	/*
	 * If it's a terminal, set up autoindent, put out the prompt, and
	 * set it up so we know we were suspended.  Otherwise, turn off
	 * the autoindent flag, as that requires less special casing below.
	 *
	 * XXX
	 * Historic practice is that ^Z suspended command mode (but, because
	 * it ran in cooked mode, it was unaffected by the autowrite option.)
	 * On restart, any "current" input was discarded, whether in insert
	 * mode or not, and ex was in command mode.  This code matches historic
	 * practice, but not 'cause it's easier.
	 */
	gp = sp->gp;
	if (F_ISSET(gp, G_SCRIPTED))
		LF_CLR(TXT_AUTOINDENT);
	else {
		if (LF_ISSET(TXT_AUTOINDENT)) {
			LF_SET(TXT_EOFCHAR);
			if (v_txt_auto(sp, sp->lno, NULL, 0, tp))
				goto err;
		}
		txt_prompt(sp, tp, prompt, flags);
	}

	for (carat_st = C_NOTSET;;) {
		if (v_event_get(sp, &ev, 0, 0))
			goto err;

		/* Deal with all non-character events. */
		switch (ev.e_event) {
		case E_CHARACTER:
			break;
		case E_ERR:
			goto err;
		case E_REPAINT:
		case E_WRESIZE:
			continue;
		case E_EOF:
			rval = 1;
			/* FALLTHROUGH */
		case E_INTERRUPT:
			/*
			 * Handle EOF/SIGINT events by discarding partially
			 * entered text and returning.  EOF returns failure,
			 * E_INTERRUPT returns success.
			 */
			goto notlast;
		default:
			v_event_err(sp, &ev);
			goto notlast;
		}

		/*
		 * Deal with character events.
		 *
		 * Check to see if the character fits into the input buffer.
		 * (Use tp->len, ignore overwrite and non-printable chars.)
		 */
		BINC_GOTOW(sp, tp->lb, tp->lb_len, tp->len + 1);

		switch (ev.e_value) {
		case K_CR:
			/*
			 * !!!
			 * Historically, <carriage-return>'s in the command
			 * weren't special, so the ex parser would return an
			 * unknown command error message.  However, if they
			 * terminated the command if they were in a map.  I'm
			 * pretty sure this still isn't right, but it handles
			 * what I've seen so far.
			 */
			if (!FL_ISSET(ev.e_flags, CH_MAPPED))
				goto ins_ch;
			/* FALLTHROUGH */
		case K_NL:
			/*
			 * '\' can escape <carriage-return>/<newline>.  We
			 * don't discard the backslash because we need it
			 * to get the <newline> through the ex parser.
			 */
			if (LF_ISSET(TXT_BACKSLASH) &&
			    tp->len != 0 && tp->lb[tp->len - 1] == '\\')
				goto ins_ch;

			/*
			 * CR returns from the ex command line.
			 *
			 * XXX
			 * Terminate with a nul, needed by filter.
			 */
			if (LF_ISSET(TXT_CR)) {
				tp->lb[tp->len] = '\0';
				goto done;
			}

			/*
			 * '.' may terminate text input mode; free the current
			 * TEXT.
			 */
			if (LF_ISSET(TXT_DOTTERM) && tp->len == tp->ai + 1 &&
			    tp->lb[tp->len - 1] == '.') {
notlast:			CIRCLEQ_REMOVE(tiqh, tp, q);
				text_free(tp);
				goto done;
			}

			/* Set up bookkeeping for the new line. */
			if ((ntp = text_init(sp, NULL, 0, 32)) == NULL)
				goto err;
			ntp->lno = tp->lno + 1;

			/*
			 * Reset the autoindent line value.  0^D keeps the ai
			 * line from changing, ^D changes the level, even if
			 * there were no characters in the old line.  Note, if
			 * using the current tp structure, use the cursor as
			 * the length, the autoindent characters may have been
			 * erased.
			 */
			if (LF_ISSET(TXT_AUTOINDENT)) {
				if (carat_st == C_NOCHANGE) {
					if (v_txt_auto(sp,
					    OOBLNO, &ait, ait.ai, ntp))
						goto err;
					free(ait.lb);
				} else
					if (v_txt_auto(sp,
					    OOBLNO, tp, tp->len, ntp))
						goto err;
				carat_st = C_NOTSET;
			}
			txt_prompt(sp, ntp, prompt, flags);

			/*
			 * Swap old and new TEXT's, and insert the new TEXT
			 * into the queue.
			 */
			tp = ntp;
			CIRCLEQ_INSERT_TAIL(tiqh, tp, q);
			break;
		case K_CARAT:			/* Delete autoindent chars. */
			if (tp->len <= tp->ai && LF_ISSET(TXT_AUTOINDENT))
				carat_st = C_CARATSET;
			goto ins_ch;
		case K_ZERO:			/* Delete autoindent chars. */
			if (tp->len <= tp->ai && LF_ISSET(TXT_AUTOINDENT))
				carat_st = C_ZEROSET;
			goto ins_ch;
		case K_CNTRLD:			/* Delete autoindent char. */
			/*
			 * !!!
			 * Historically, the ^D command took (but then ignored)
			 * a count.  For simplicity, we don't return it unless
			 * it's the first character entered.  The check for len
			 * equal to 0 is okay, TXT_AUTOINDENT won't be set.
			 */
			if (LF_ISSET(TXT_CNTRLD)) {
				for (cnt = 0; cnt < tp->len; ++cnt)
					if (!isblank(tp->lb[cnt]))
						break;
				if (cnt == tp->len) {
					tp->len = 1;
					tp->lb[0] = ev.e_c;
					tp->lb[1] = '\0';

					/*
					 * Put out a line separator, in case
					 * the command fails.
					 */
					(void)putchar('\n');
					goto done;
				}
			}

			/*
			 * POSIX 1003.1b-1993, paragraph 7.1.1.9, states that
			 * the EOF characters are discarded if there are other
			 * characters to process in the line, i.e. if the EOF
			 * is not the first character in the line.  For this
			 * reason, historic ex discarded the EOF characters,
			 * even if occurring in the middle of the input line.
			 * We match that historic practice.
			 *
			 * !!!
			 * The test for discarding in the middle of the line is
			 * done in the switch, because the CARAT forms are N+1,
			 * not N.
			 *
			 * !!!
			 * There's considerable magic to make the terminal code
			 * return the EOF character at all.  See that code for
			 * details.
			 */
			if (!LF_ISSET(TXT_AUTOINDENT) || tp->len == 0)
				continue;
			switch (carat_st) {
			case C_CARATSET:		/* ^^D */
				if (tp->len > tp->ai + 1)
					continue;

				/* Save the ai string for later. */
				ait.lb = NULL;
				ait.lb_len = 0;
				BINC_GOTOW(sp, ait.lb, ait.lb_len, tp->ai);
				MEMCPYW(ait.lb, tp->lb, tp->ai);
				ait.ai = ait.len = tp->ai;

				carat_st = C_NOCHANGE;
				goto leftmargin;
			case C_ZEROSET:			/* 0^D */
				if (tp->len > tp->ai + 1)
					continue;

				carat_st = C_NOTSET;
leftmargin:			(void)gp->scr_ex_adjust(sp, EX_TERM_CE);
				tp->ai = tp->len = 0;
				break;
			case C_NOTSET:			/* ^D */
				if (tp->len > tp->ai)
					continue;

				if (txt_dent(sp, tp))
					goto err;
				break;
			default:
				abort();
			}

			/* Clear and redisplay the line. */
			(void)gp->scr_ex_adjust(sp, EX_TERM_CE);
			txt_prompt(sp, tp, prompt, flags);
			break;
		default:
			/*
			 * See the TXT_BEAUTIFY comment in vi/v_txt_ev.c.
			 *
			 * Silently eliminate any iscntrl() character that was
			 * not already handled specially, except for <tab> and
			 * <ff>.
			 */
ins_ch:			if (LF_ISSET(TXT_BEAUTIFY) && ISCNTRL(ev.e_c) &&
			    ev.e_value != K_FORMFEED && ev.e_value != K_TAB)
				break;

			tp->lb[tp->len++] = ev.e_c;
			break;
		}
	}
	/* NOTREACHED */

done:	return (rval);

err:	
alloc_err:
	return (1);
}
Example #12
0
/*
 * ypdb_open_db
 */
DBM *
ypdb_open_db(const char *domain, const char *map, u_int *status,
	     struct opt_map **map_info)
{
	static const char *domain_key = YP_INTERDOMAIN_KEY;
	static const char *secure_key = YP_SECURE_KEY;
	char map_path[MAXPATHLEN];
	struct stat finfo;
	struct opt_domain *d = NULL;
	struct opt_map *m = NULL;
	DBM *db;
	datum k, v;

	*status = YP_TRUE;	/* defaults to true */

	/*
	 * check for illegal domain and map names
	 */
	if (_yp_invalid_domain(domain)) {
		*status = YP_NODOM;
		return (NULL);
	}
	if (_yp_invalid_map(map)) {
		*status = YP_NOMAP;
		return (NULL);
	}

	/*
	 * check for domain, file.
	 */
	(void)snprintf(map_path, sizeof(map_path), "%s/%s", YP_DB_PATH, domain);
	if (stat(map_path, &finfo) < 0 || !S_ISDIR(finfo.st_mode)) {
#ifdef DEBUG
		syslog(LOG_DEBUG,
		    "ypdb_open_db: no domain %s (map=%s)", domain, map);
#endif
		*status = YP_NODOM;
	} else {
		(void)snprintf(map_path, sizeof(map_path), "%s/%s/%s%s",
		    YP_DB_PATH, domain, map, YPDB_SUFFIX);
		if (stat(map_path, &finfo) < 0) {
#ifdef DEBUG
			syslog(LOG_DEBUG,
			    "ypdb_open_db: no map %s (domain=%s)", map,
			    domain);
#endif
			*status = YP_NOMAP;
		}
	}

	/*
	 * check for preloaded domain, map
	 */
	for (d = doms.lh_first; d != NULL; d = d->domsl.le_next)
		if (strcmp(domain, d->domain) == 0)
			break;

	if (d)
		for (m = d->dmaps.lh_first; m != NULL; m = m->mapsl.le_next)
			if (strcmp(map, m->map) == 0)
				break;

	/*
	 * map found open?
	 */
	if (m) {
#ifdef DEBUG
		syslog(LOG_DEBUG,
		    "ypdb_open_db: cached open: domain=%s, map=%s, db=%p,",
		    domain, map, m->db);
		syslog(LOG_DEBUG,
		    "\tdbdev %d new %d; dbino %d new %d; dbmtime %ld new %ld",
		    m->dbdev, finfo.st_dev, m->dbino, finfo.st_ino,
		    (long) m->dbmtime, (long) finfo.st_mtime);
#endif
		/*
		 * if status != YP_TRUE, then this cached database is now
		 * non-existent
		 */
		if (*status != YP_TRUE) {
#ifdef DEBUG
			syslog(LOG_DEBUG,
			    "ypdb_open_db: cached db is now unavailable - "
			    "closing: status %s",
			    yperr_string(ypprot_err(*status)));
#endif
			ypdb_close_map(m);
			return (NULL);
		}

		/*
		 * is this the same db?
		 */
		if (finfo.st_dev == m->dbdev && finfo.st_ino == m->dbino &&
		    finfo.st_mtime == m->dbmtime) {
			CIRCLEQ_REMOVE(&maps, m, mapsq); /* adjust LRU queue */
			CIRCLEQ_INSERT_HEAD(&maps, m, mapsq);
			if (map_info)
				*map_info = m;
			return (m->db);
		} else {
#ifdef DEBUG
			syslog(LOG_DEBUG,
			    "ypdb_open_db: db changed; closing");
#endif
			ypdb_close_map(m);
			m = NULL;
		}
	}

	/*
	 * not cached and non-existent, return
	 */
	if (*status != YP_TRUE)	
		return (NULL);

	/*
	 * open map
	 */
	(void)snprintf(map_path, sizeof(map_path), "%s/%s/%s",
	    YP_DB_PATH, domain, map);
#ifdef OPTIMIZE_DB
retryopen:
#endif /* OPTIMIZE_DB */
	db = ypdb_open(map_path);
#ifdef OPTIMIZE_DB
	if (db == NULL) {
#ifdef DEBUG
		syslog(LOG_DEBUG,
		    "ypdb_open_db: errno %d (%s)", errno, strerror(errno));
#endif /* DEBUG */
		if ((errno == ENFILE) || (errno == EMFILE)) {
			ypdb_close_last();
			goto retryopen;
		}
	}
#endif /* OPTIMIZE_DB */

	*status = YP_NOMAP;	/* see note below */

	if (db == NULL) {
#ifdef DEBUG
		syslog(LOG_DEBUG,
		    "ypdb_open_db: ypdb_open FAILED: map %s (domain=%s)",
		    map, domain);
#endif
		return (NULL);
	}

	/*
	 * note: status now YP_NOMAP
	 */
	if (d == NULL) {	/* allocate new domain? */
		d = (struct opt_domain *) malloc(sizeof(*d));
		if (d)
			d->domain = strdup(domain);
		if (d == NULL || d->domain == NULL) {
			syslog(LOG_ERR,
			    "ypdb_open_db: MALLOC failed");
			ypdb_close(db);
			if (d)
				free(d);
			return (NULL);
		}
		LIST_INIT(&d->dmaps);
		LIST_INSERT_HEAD(&doms, d, domsl);
#ifdef DEBUG
		syslog(LOG_DEBUG,
		    "ypdb_open_db: NEW DOMAIN %s", domain);
#endif
	}

	/*
	 * m must be NULL since we couldn't find a map.  allocate new one
	 */
	m = (struct opt_map *) malloc(sizeof(*m));
	if (m)
		m->map = strdup(map);

	if (m == NULL || m->map == NULL) {
		if (m)
			free(m);
		syslog(LOG_ERR, "ypdb_open_db: MALLOC failed");
		ypdb_close(db);
		return (NULL);
	}
	m->db = db;
	m->dom = d;
	m->host_lookup = FALSE;
	m->dbdev = finfo.st_dev;
	m->dbino = finfo.st_ino;
	m->dbmtime = finfo.st_mtime;
	CIRCLEQ_INSERT_HEAD(&maps, m, mapsq);
	LIST_INSERT_HEAD(&d->dmaps, m, mapsl);
	if (strcmp(map, YP_HOSTNAME) == 0 || strcmp(map, YP_HOSTADDR) == 0) {
		if (!usedns) {
			k.dptr = domain_key;
			k.dsize = YP_INTERDOMAIN_LEN;
			v = ypdb_fetch(db, k);
			if (v.dptr)
				m->host_lookup = TRUE;
		} else
			m->host_lookup = TRUE;
	}

	m->secure = FALSE;
	k.dptr = secure_key;
	k.dsize = YP_SECURE_LEN;
	v = ypdb_fetch(db, k);
	if (v.dptr != NULL)
		m->secure = TRUE;

	*status = YP_TRUE;

	if (map_info)
		*map_info = m;

#ifdef DEBUG
	syslog(LOG_DEBUG,
	    "ypdb_open_db: NEW MAP domain=%s, map=%s, hl=%d, s=%d, db=%p",
	    domain, map, m->host_lookup, m->secure, m->db);
#endif

	return (m->db);
}
Example #13
0
File: exf.c Project: fishman/nvi
/*
 * file_end --
 *	Stop editing a file.
 *
 * PUBLIC: int file_end __P((SCR *, EXF *, int));
 */
int
file_end(SCR *sp, EXF *ep, int force)
{
    FREF *frp;

    /*
     * !!!
     * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER.
     * (If argument ep is NULL, use sp->ep.)
     *
     * If multiply referenced, just decrement the count and return.
     */
    if (ep == NULL)
        ep = sp->ep;
    CIRCLEQ_REMOVE(&ep->scrq, sp, eq);
    if (--ep->refcnt != 0)
        return (0);

    /*
     *
     * Clean up the FREF structure.
     *
     * Save the cursor location.
     *
     * XXX
     * It would be cleaner to do this somewhere else, but by the time
     * ex or vi knows that we're changing files it's already happened.
     */
    frp = sp->frp;
    frp->lno = sp->lno;
    frp->cno = sp->cno;
    F_SET(frp, FR_CURSORSET);

    /*
     * We may no longer need the temporary backing file, so clean it
     * up.  We don't need the FREF structure either, if the file was
     * never named, so lose it.
     *
     * !!!
     * Re: FR_DONTDELETE, see the comment above in file_init().
     */
    if (!F_ISSET(frp, FR_DONTDELETE) && frp->tname != NULL) {
        if (unlink(frp->tname))
            msgq_str(sp, M_SYSERR, frp->tname, "240|%s: remove");
        free(frp->tname);
        frp->tname = NULL;
        if (F_ISSET(frp, FR_TMPFILE)) {
            CIRCLEQ_REMOVE(&sp->gp->frefq, frp, q);
            if (frp->name != NULL)
                free(frp->name);
            free(frp);
        }
        sp->frp = NULL;
    }

    /*
     * Clean up the EXF structure.
     *
     * Close the db structure.
     */
    if (ep->db->close != NULL) {
        if ((sp->db_error = ep->db->close(ep->db, DB_NOSYNC)) != 0 &&
                !force) {
            msgq_str(sp, M_DBERR, frp->name, "241|%s: close");
            CIRCLEQ_INSERT_HEAD(&ep->scrq, sp, eq);
            ++ep->refcnt;
            return (1);
        }
        ep->db = NULL;
    }

    /* COMMITTED TO THE CLOSE.  THERE'S NO GOING BACK... */

    /* Stop logging. */
    (void)log_end(sp, ep);

    /* Free up any marks. */
    (void)mark_end(sp, ep);

    if (ep->env) {
        DB_ENV *env;

        ep->env->close(ep->env, 0);
        ep->env = 0;
        if ((sp->db_error = db_env_create(&env, 0)))
            msgq(sp, M_DBERR, "env_create");
        if ((sp->db_error = db_env_remove(env, ep->env_path, 0)))
            msgq(sp, M_DBERR, "env->remove");
        if (ep->env_path != NULL && rmdir(ep->env_path))
            msgq_str(sp, M_SYSERR, ep->env_path, "242|%s: remove");
    }

    /*
     * Delete recovery files, close the open descriptor, free recovery
     * memory.  See recover.c for a description of the protocol.
     *
     * XXX
     * Unlink backup file first, we can detect that the recovery file
     * doesn't reference anything when the user tries to recover it.
     * There's a race, here, obviously, but it's fairly small.
     */
    if (!F_ISSET(ep, F_RCV_NORM)) {
        if (ep->rcv_path != NULL && unlink(ep->rcv_path))
            msgq_str(sp, M_SYSERR, ep->rcv_path, "242|%s: remove");
        if (ep->rcv_mpath != NULL && unlink(ep->rcv_mpath))
            msgq_str(sp, M_SYSERR, ep->rcv_mpath, "243|%s: remove");
    }
    CIRCLEQ_REMOVE(&sp->gp->exfq, ep, q);
    if (ep->fd != -1)
        (void)close(ep->fd);
    if (ep->fcntl_fd != -1)
        (void)close(ep->fcntl_fd);
    if (ep->rcv_fd != -1)
        (void)close(ep->rcv_fd);
    if (ep->env_path != NULL)
        free(ep->env_path);
    if (ep->rcv_path != NULL)
        free(ep->rcv_path);
    if (ep->rcv_mpath != NULL)
        free(ep->rcv_mpath);

    free(ep);
    return (0);
}