Пример #1
0
void pluto_init_log(void)
{
	set_alloc_exit_log_func(exit_log);
	if (log_to_stderr)
		setbuf(stderr, NULL);

	if (pluto_log_file != NULL) {
		pluto_log_fp = fopen(pluto_log_file,
			log_append ? "a" : "w");
		if (pluto_log_fp == NULL) {
			fprintf(stderr,
				"Cannot open logfile '%s': %s\n",
				pluto_log_file, strerror(errno));
		} else {
			/*
			 * buffer by line:
			 * should be faster that no buffering
			 * and yet safe since each message is probably a line.
			 */
			setvbuf(pluto_log_fp, NULL, _IOLBF, 0);
		}
	}

	if (log_to_syslog)
		openlog("pluto", LOG_CONS | LOG_NDELAY | LOG_PID,
			LOG_AUTHPRIV);

	CIRCLEQ_INIT(&perpeer_list);
}
Пример #2
0
/*
 * ypdb_init: init the queues and lists
 */
void
ypdb_init(void)
{

	LIST_INIT(&doms);
	CIRCLEQ_INIT(&maps);
}
Пример #3
0
/*
 * ex_screen_copy --
 *	Copy ex screen.
 *
 * PUBLIC: int ex_screen_copy __P((SCR *, SCR *));
 */
int
ex_screen_copy(SCR *orig, SCR *sp)
{
	EX_PRIVATE *oexp, *nexp;

	/* Create the private ex structure. */
	CALLOC_RET(orig, nexp, EX_PRIVATE *, 1, sizeof(EX_PRIVATE));
	sp->ex_private = nexp;

	/* Initialize queues. */
	CIRCLEQ_INIT(&nexp->tq);
	TAILQ_INIT(&nexp->tagfq);
	LIST_INIT(&nexp->cscq);

	if (orig == NULL) {
	} else {
		oexp = EXP(orig);

		if (oexp->lastbcomm != NULL &&
		    (nexp->lastbcomm = v_wstrdup(sp, oexp->lastbcomm, 
				     STRLEN(oexp->lastbcomm))) == NULL) {
			msgq(sp, M_SYSERR, NULL);
			return(1);
		}
		if (ex_tag_copy(orig, sp))
			return (1);
	}
	return (0);
}
Пример #4
0
void
init_stmem()
{
	int s = splhigh ();
	struct mem_node *mem;

	stmem_total = st_pool_size - sizeof(*mem);
    
	mem = (struct mem_node *)st_pool_virt;
	mem->size = st_pool_size - sizeof(*mem);

	CIRCLEQ_INIT(&st_list);
	CIRCLEQ_INIT(&free_list);
    
	CIRCLEQ_INSERT_HEAD(&st_list, mem, link);
	CIRCLEQ_INSERT_HEAD(&free_list, mem, free_link);
	splx(s);
}
Пример #5
0
int main(int argc, const char *argv[])
{
#if 1
	CIRCLEQ_HEAD(circleq, _Data)	head = CIRCLEQ_HEAD_INITIALIZER(head);
#else
	CIRCLEQ_HEAD(circleq, _Data)	head;
	CIRCLEQ_INIT(&head);
#endif
	exit(EXIT_SUCCESS);
}
Пример #6
0
Файл: log.c Проект: odit/rv042
void
init_log(const char *program)
{
    if (log_to_stderr)
	setbuf(stderr, NULL);
    if (log_to_syslog)
	openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);

    CIRCLEQ_INIT(&perpeer_list);
}
Пример #7
0
Файл: log.c Проект: mcr/Openswan
void
pluto_init_log(void)
{
    set_exit_log_func(exit_log);
    if (log_to_stderr)
	setbuf(stderr, NULL);
    if (log_to_syslog)
	openlog("pluto", LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);

    CIRCLEQ_INIT(&perpeer_list);
}
Пример #8
0
void
in_pcbinit(struct inpcbtable *table, int bindhashsize, int connecthashsize)
{
	static ONCE_DECL(control);

	CIRCLEQ_INIT(&table->inpt_queue);
	table->inpt_porthashtbl = hashinit(bindhashsize, HASH_LIST, true,
	    &table->inpt_porthash);
	table->inpt_bindhashtbl = hashinit(bindhashsize, HASH_LIST, true,
	    &table->inpt_bindhash);
	table->inpt_connecthashtbl = hashinit(connecthashsize, HASH_LIST, true,
	    &table->inpt_connecthash);
	table->inpt_lastlow = IPPORT_RESERVEDMAX;
	table->inpt_lastport = (u_int16_t)anonportmax;

	RUN_ONCE(&control, inpcb_poolinit);
}
Пример #9
0
int
load_cve (char *path)
{

  FILE *f = fopen (path, "r");
  int i = 0, sz;
  char line[1024];
  if (!f)
    return 1;
  CIRCLEQ_INIT (&head);
  while (!feof (f))
    {
      fgets (line, 1024, f);
      if (strncmp (line, DELIMITER, 10) == 0)
	{
	  entry *en = malloc (sizeof (entry));
	  for (i = 0, sz = 0; i < 20 && !feof (f); i++)
	    {
	      fgets (line, 1024, f);
	      sz += strlen (line);
	      if (strncmp (line, DELIMITER, 10) == 0)
		{

		  CIRCLEQ_INSERT_HEAD (&head, en, entries);

		  break;
		}
	      if (line)
		{
		  en->buf[i] = malloc (strlen (line) + 1);
		  ++en->count;
		  memcpy (en->buf[i], &line, strlen (line) + 1);
		}
	    }

	}



    }
  fclose (f);

  return 0;

}
int main(int argc, char** argv) {
    int current_size, queue_size;

    struct epoll_event e, events[MAX_EVENTS];
    int epoll_fd;
    if (argc < 2) {
        puts("Usage : %s [size of client queue]", argv[0]);
        return 0;
    }

    current_size = 0;
    queue_size = argv[1];
    CIRCLEQ_INIT(&head);
    while (1) {

    }

    return 0;
}
Пример #11
0
void pluto_init_log(void)
{
	set_alloc_exit_log_func(exit_log);
	if (log_to_stderr)
		setbuf(stderr, NULL);

	if (pluto_log_file != NULL) {
		pluto_log_fp = fopen(pluto_log_file, "w");
		if (pluto_log_fp == NULL) {
			fprintf(stderr,
				"Cannot open logfile '%s': %s\n",
				pluto_log_file, strerror(errno));
		} else {
			setbuf(pluto_log_fp, NULL);
		}
	}

	if (log_to_syslog)
		openlog("pluto", LOG_CONS | LOG_NDELAY | LOG_PID,
			LOG_AUTHPRIV);

	CIRCLEQ_INIT(&perpeer_list);
}
Пример #12
0
Файл: iod.c Проект: Yomin/neobox
int main(int argc, char* argv[])
{
    int opt, ret;
    int daemon = 1, lock = 0;
    int screen_status, aux_pressed, power_pressed, y, x;
    char *config;
    FILE *file;
    struct sockaddr_un addr;
    
    struct chain_socket *aux_grabber = 0, *power_grabber = 0;
    
    struct input_event input;
    struct iod_cmd cmd;
    struct chain_socket *cs;
    
    size_t size;
    
    y = x = screen_status = aux_pressed = power_pressed = 0;
    pwd = IOD_PWD;
    
    while((opt = getopt(argc, argv, "fd:")) != -1)
    {
        switch(opt)
        {
        case 'f':
            daemon = 0;
            break;
        case 'd':
            pwd = optarg;
            break;
        default:
            usage(argv[0]);
            return 0;
        }
    }
    
    if(optind == argc)
    {
        usage(argv[0]);
        return 0;
    }
    
    config = argv[optind];
    
    if(mkdir(pwd, 0777) == -1 && errno != EEXIST)
    {
        perror("Failed to create working dir");
        return 7;
    }
    
    if(daemon)
    {
        int tmp = fork();
        if(tmp < 0)
        {
            perror("Failed to fork process");
            return 1;
        }
        if(tmp > 0)
        {
            return 0;
        }
        
        setsid();
        
        close(0); close(1); close(2);
        tmp = open("/dev/null", O_RDWR); dup(tmp); dup(tmp);
        
        chdir(pwd);
        
        if((tmp = open("pid", O_WRONLY|O_CREAT, 755)) < 0)
        {
            perror("Failed to open pidfile");
            return 2;
        }
        
        pid_t pid = getpid();
        char buf[10];
        int count = sprintf(buf, "%i", pid);
        write(tmp, &buf, count*sizeof(char));
        
        if(lockf(tmp, F_TLOCK, -count*sizeof(char)) < 0)
        {
            perror("Daemon already running");
            return 3;
        }
    }
    
    if(!(file = fopen(config, "r")))
    {
        perror("Failed to open config file");
        return 4;
    }
    
    if((size = getline(&screen_dev, &size, file)) == -1)
    {
        fprintf(stderr, "Failed to read screen config\n");
        return 5;
    }
    screen_dev[size-1] = 0;
    
    if((screen_fd = open(screen_dev, O_RDONLY)) == -1)
    {
        perror("Failed to open screen socket");
        return 6;
    }
    
    if((size = getline(&aux_dev, &size, file)) == -1)
    {
        fprintf(stderr, "Failed to read aux config\n");
        return 7;
    }
    aux_dev[size-1] = 0;
    
    if((aux_fd = open(aux_dev, O_RDONLY)) == -1)
    {
        perror("Failed to open aux socket");
        return 8;
    }
    
    if((size = getline(&power_dev, &size, file)) == -1)
    {
        fprintf(stderr, "Failed to read power config\n");
        return 9;
    }
    power_dev[size-1] = 0;
    fclose(file);
    
    if((power_fd = open(power_dev, O_RDONLY)) == -1)
    {
        perror("Failed to open power socket");
        return 10;
    }
    
    DEBUG(print_info(screen_fd));
    DEBUG(print_info(aux_fd));
    DEBUG(print_info(power_fd));
    
    if((ret = open_socket(&sock, &addr)))
        return ret;
    
    pfds_cap = 10;
    pfds = malloc(pfds_cap*sizeof(struct pollfd));
    pfds[0].fd = screen_fd;
    pfds[0].events = POLLIN;
    pfds[1].fd = aux_fd;
    pfds[1].events = POLLIN;
    pfds[2].fd = power_fd;
    pfds[2].events = POLLIN;
    pfds[3].fd = sock;
    pfds[3].events = POLLIN;
    
    client_count = 0;
    CIRCLEQ_INIT(&client_list);
    
    signal(SIGINT, signal_handler);
    
    DEBUG(printf("Ready\n"));
    
    while(1)
    {
        poll(pfds, client_count+4, -1);
        
        if(pfds[0].revents & POLLHUP || pfds[0].revents & POLLERR)
        {
            DEBUG(printf("pollhup/err on screen socket\n"));
            close(screen_fd);
            if((screen_fd = open(screen_dev, O_RDONLY)) < 0)
            {
                perror("Failed to open screen socket");
                screen_fd = 0;
                cleanup();
                return 6;
            }
        }
        else if(pfds[0].revents & POLLIN)
        {
            read(screen_fd, &input, sizeof(struct input_event));
            
            if(lock)
                continue;
            
            switch(input.type)
            {
            case EV_KEY:
                switch(input.code)
                {
                case BTN_TOUCH:
                    switch(input.value)
                    {
                        case 0:
                            screen_status = 0;
                            break;
                        case 1:
                            screen_status = 1;
                            break;
                    }
                    break;
                }
                break;
            case EV_ABS:
                switch(input.code)
                {
                case ABS_X:
                    y = input.value-MIN_PIXEL;
                    break;
                case ABS_Y:
                    x = input.value-MIN_PIXEL;
                    break;
                case ABS_PRESSURE:
                    break;
                }
                break;
            case EV_SYN:
                switch(input.code)
                {
                case SYN_REPORT:
                    switch(screen_status)
                    {
                    case 0:
                        DEBUG(printf("Touchscreen released (%i,%i)\n", y, x));
                        send_client_cord(IOD_EVENT_RELEASED, y, x, 0);
                        break;
                    case 1:
                        DEBUG(printf("Touchscreen pressed (%i,%i)\n", y, x));
                        send_client_cord(IOD_EVENT_PRESSED, y, x, 0);
                        screen_status = 2;
                        break;
                    case 2:
                        send_client_cord(IOD_EVENT_MOVED, y, x, 0);
                        break;
                    }
                    break;
                }
                break;
            }
        }
        else if(pfds[1].revents & POLLHUP || pfds[1].revents & POLLERR)
        {
            DEBUG(printf("pollhup/err on aux socket\n"));
            close(aux_fd);
            if((aux_fd = open(aux_dev, O_RDONLY)) == -1)
            {
                perror("Failed to open aux socket");
                aux_fd = 0;
                cleanup();
                return 8;
            }
        }
        else if(pfds[1].revents & POLLIN)
        {
            read(aux_fd, &input, sizeof(struct input_event));
            switch(input.type)
            {
            case EV_KEY:
                switch(input.code)
                {
                case KEY_PHONE:
                    aux_pressed = input.value;
                    break;
                }
                break;
            case EV_SYN:
                switch(input.code)
                {
                case SYN_REPORT:
                    DEBUG(printf("AUX %s\n",
                        aux_pressed ? "pressed" : "released"));
                    cs = aux_grabber ? aux_grabber : 0;
                    send_client_status(IOD_EVENT_AUX, aux_pressed, cs);
                    break;
                }
                break;
            }
        }
        else if(pfds[2].revents & POLLHUP || pfds[2].revents & POLLERR)
        {
            DEBUG(printf("pollhup/err on power socket\n"));
            close(power_fd);
            if((power_fd = open(power_dev, O_RDONLY)) == -1)
            {
                perror("Failed to open power socket");
                power_fd = 0;
                cleanup();
                return 10;
            }
        }
        else if(pfds[2].revents & POLLIN)
        {
            read(power_fd, &input, sizeof(struct input_event));
            switch(input.type)
            {
            case EV_KEY:
                switch(input.code)
                {
                case KEY_POWER:
                    power_pressed = input.value;
                    break;
                }
                break;
            case EV_PWR:
                break;
            case EV_SYN:
                switch(input.code)
                {
                case SYN_REPORT:
                    DEBUG(printf("Power %s\n",
                        power_pressed ? "pressed" : "released"));
                    cs = power_grabber ? power_grabber : 0;
                    send_client_status(IOD_EVENT_POWER, power_pressed, cs);
                    break;
                }
                break;
            }
        }
        else if(pfds[3].revents & POLLHUP || pfds[3].revents & POLLERR)
        {
            DEBUG(printf("pollhup/err on socket\n"));
            close(sock);
            if((ret = open_socket(&sock, &addr)))
            {
                sock = 0;
                cleanup();
                return ret;
            }
        }
        else if(pfds[3].revents & POLLIN)
        {
            int client;
            if((client = accept(sock, 0, 0)) == -1)
            {
                DEBUG(perror("Failed to accept client"));
                continue;
            }
            cs = client_list.cqh_first;
            add_client(client);
            if(cs != (void*)&client_list)
                send_client_status(IOD_EVENT_DEACTIVATED, 0, cs);
            else
                send_client_status(IOD_EVENT_ACTIVATED, 0, 0);
        }
        else
        {
            int x;
            for(x=4; x<client_count+4; x++)
                if(pfds[x].revents & POLLHUP || pfds[x].revents & POLLERR)
                {
                    DEBUG(printf("pollhup/pollerr on client socket [%i]\n", pfds[x].fd));
                    cs = find_client(&x, 0);
remove:             if(cs == aux_grabber)
                    {
                        DEBUG(printf("AUX ungrabbed [%i] %i\n",
                            cs->sock, cs->pid));
                        aux_grabber = 0;
                    }
                    if(cs == power_grabber)
                    {
                        DEBUG(printf("Power ungrabbed [%i] %i\n",
                            cs->sock, cs->pid));
                        power_grabber = 0;
                    }
                    if(cs->lock)
                    {
                        DEBUG(printf("Screen unlocked [%i] %i\n",
                            cs->sock, cs->pid));
                        lock = 0;
                    }
                    if(rem_client(x, cs))
                        send_client_status(IOD_EVENT_ACTIVATED, 0, 0);
                    break;
                }
                else if(pfds[x].revents & POLLIN)
                {
                    if(recv_client(pfds[x].fd, &cmd))
                        break;
                    switch(cmd.cmd)
                    {
                    case IOD_CMD_REGISTER:
                        register_client(x, cmd.pid);
                        break;
                    case IOD_CMD_REMOVE:
                        if((cs = find_client(&x, cmd.pid)))
                        {
                            if(cs->sock == pfds[x].fd)
                                goto remove;
                            else
                            {
                                DEBUG(printf("Client remove [%i] %i\n",
                                    cs->sock, cs->pid));
                                send_client_status(
                                    IOD_EVENT_REMOVED, 0, cs);
                            }
                        }
                        break;
                    case IOD_CMD_SWITCH:
                        cs = client_list.cqh_first;
                        if(switch_client(cmd.value, x, cmd.pid))
                            send_client_status(
                                IOD_EVENT_DEACTIVATED, 0, cs);
                        break;
                    case IOD_CMD_LOCK:
                        cs = find_client(&x, 0);
                        if(!lock || cs->lock)
                        {
                            lock = cs->lock = cmd.value;
                            DEBUG(printf("Screen %s [%i] %i\n",
                                lock ? "locked" : "unlocked",
                                x, cs->pid));
                            send_client_status(
                                IOD_EVENT_LOCK, IOD_SUCCESS_MASK, cs);
                        }
                        else
                            send_client_status(
                                IOD_EVENT_LOCK, 0, cs);
                        break;
                    case IOD_CMD_HIDE:
                        hide_client(x, cmd.pid,
                            cmd.value & ~IOD_HIDE_MASK,
                            cmd.value & IOD_HIDE_MASK);
                        break;
                    case IOD_CMD_ACK:
                        switch(cmd.value)
                        {
                        case IOD_EVENT_DEACTIVATED:
                            cs = client_list.cqh_first;
                            DEBUG(printf("Client switched [%i] %i -> [%i] %i\n",
                                pfds[x].fd, find_client(&x, 0)->pid,
                                cs->sock, cs->pid));
                            send_client_status(
                                IOD_EVENT_ACTIVATED, 0, 0);
                            break;
                        case IOD_EVENT_REMOVED:
                            cs = find_client(&x, 0);
                            goto remove;
                        default:
                            DEBUG(printf("Client done [%i] %i\n",
                                pfds[x].fd, find_client(&x, 0)->pid));
                            break;
                        }
                        break;
                    case IOD_CMD_GRAB:
                        cs = find_client(&x, 0);
                        switch(cmd.value & ~IOD_GRAB_MASK)
                        {
                        case IOD_GRAB_AUX:
                            if(!aux_grabber || cs == aux_grabber)
                            {
                                if(cmd.value & IOD_GRAB_MASK)
                                {
                                    DEBUG(printf("AUX grabbed [%i] %i\n",
                                        cs->sock, cs->pid));
                                    aux_grabber = cs;
                                }
                                else
                                {
                                    DEBUG(printf("AUX ungrabbed [%i] %i\n",
                                        cs->sock, cs->pid));
                                    aux_grabber = 0;
                                }
                                send_client_status(IOD_EVENT_GRAB,
                                    IOD_SUCCESS_MASK|IOD_GRAB_AUX, cs);
                            }
                            else
                                send_client_status(IOD_EVENT_GRAB,
                                    IOD_GRAB_AUX, cs);
                            break;
                        case IOD_GRAB_POWER:
                            if(!power_grabber || cs == power_grabber)
                            {
                                if(cmd.value & IOD_GRAB_MASK)
                                {
                                    DEBUG(printf("Power grabbed [%i] %i\n",
                                        cs->sock, cs->pid));
                                    power_grabber = cs;
                                }
                                else
                                {
                                    DEBUG(printf("Power ungrabbed [%i] %i\n",
                                        cs->sock, cs->pid));
                                    power_grabber = 0;
                                }
                                send_client_status(IOD_EVENT_GRAB,
                                    IOD_SUCCESS_MASK|IOD_GRAB_POWER, cs);
                            }
                            else
                                send_client_status(IOD_EVENT_GRAB,
                                    IOD_GRAB_POWER, cs);
                            break;
                        }
                        break;
                    case IOD_CMD_POWERSAVE:
                        DEBUG(printf("Powersave %s broadcast\n",
                            cmd.value ? "on" : "off"));
                        cs = client_list.cqh_first;
                        while(cs != (void*)&client_list)
                        {
                            if(cs->sock != pfds[x].fd)
                                send_client_status(
                                    IOD_EVENT_POWERSAVE, cmd.value, cs);
                            cs = cs->chain.cqe_next;
                        }
                        break;
                    default:
                        DEBUG(printf("Unrecognized command 0x%02hhx [%i] %i\n",
                            cmd.cmd, pfds[x].fd, find_client(&x, 0)->pid));
                    }
                    break;
                }
        }
    }
    
    cleanup();
    
    return 0;
}
Пример #13
0
/*
 * screen_init --
 *	Do the default initialization of an SCR structure.
 *
 * PUBLIC: int screen_init __P((GS *, SCR *, SCR **));
 */
int
screen_init(GS *gp, SCR *orig, SCR **spp)
{
	SCR *sp;
	size_t len;

	*spp = NULL;
	CALLOC_RET(orig, sp, SCR *, 1, sizeof(SCR));
	*spp = sp;

/* INITIALIZED AT SCREEN CREATE. */
	sp->id = ++gp->id;
	sp->refcnt = 1;

	sp->gp = gp;			/* All ref the GS structure. */

	sp->ccnt = 2;			/* Anything > 1 */

	/*
	 * XXX
	 * sp->defscroll is initialized by the opts_init() code because
	 * we don't have the option information yet.
	 */

	CIRCLEQ_INIT(&sp->tiq);

/* PARTIALLY OR COMPLETELY COPIED FROM PREVIOUS SCREEN. */
	if (orig == NULL) {
		sp->searchdir = NOTSET;
	} else {
		sp->wp = orig->wp;

		/* Alternate file name. */
		if (orig->alt_name != NULL &&
		    (sp->alt_name = strdup(orig->alt_name)) == NULL)
			goto mem;

		/* Last executed at buffer. */
		if (F_ISSET(orig, SC_AT_SET)) {
			F_SET(sp, SC_AT_SET);
			sp->at_lbuf = orig->at_lbuf;
		}

		/* Retain searching/substitution information. */
		sp->searchdir = orig->searchdir == NOTSET ? NOTSET : FORWARD;
		if (orig->re != NULL && (sp->re =
		    v_wstrdup(sp, orig->re, orig->re_len)) == NULL)
			goto mem;
		sp->re_len = orig->re_len;
		if (orig->subre != NULL && (sp->subre =
		    v_wstrdup(sp, orig->subre, orig->subre_len)) == NULL)
			goto mem;
		sp->subre_len = orig->subre_len;
		if (orig->repl != NULL && (sp->repl =
		    v_wstrdup(sp, orig->repl, orig->repl_len)) == NULL)
			goto mem;
		sp->repl_len = orig->repl_len;
		if (orig->newl_len) {
			len = orig->newl_len * sizeof(size_t);
			MALLOC(sp, sp->newl, size_t *, len);
			if (sp->newl == NULL) {
mem:				msgq(orig, M_SYSERR, NULL);
				goto err;
			}
			sp->newl_len = orig->newl_len;
			sp->newl_cnt = orig->newl_cnt;
			memcpy(sp->newl, orig->newl, len);
		}

		if (opts_copy(orig, sp))
			goto err;

		F_SET(sp, F_ISSET(orig, SC_EX | SC_VI));
	}
Пример #14
0
/*
 * cut --
 *	Put a range of lines/columns into a TEXT buffer.
 *
 * There are two buffer areas, both found in the global structure.  The first
 * is the linked list of all the buffers the user has named, the second is the
 * unnamed buffer storage.  There is a pointer, too, which is the current
 * default buffer, i.e. it may point to the unnamed buffer or a named buffer
 * depending on into what buffer the last text was cut.  Logically, in both
 * delete and yank operations, if the user names a buffer, the text is cut
 * into it.  If it's a delete of information on more than a single line, the
 * contents of the numbered buffers are rotated up one, the contents of the
 * buffer named '9' are discarded, and the text is cut into the buffer named
 * '1'.  The text is always cut into the unnamed buffer.
 *
 * In all cases, upper-case buffer names are the same as lower-case names,
 * with the exception that they cause the buffer to be appended to instead
 * of replaced.  Note, however, that if text is appended to a buffer, the
 * default buffer only contains the appended text, not the entire contents
 * of the buffer.
 *
 * !!!
 * The contents of the default buffer would disappear after most operations
 * in historic vi.  It's unclear that this is useful, so we don't bother.
 *
 * When users explicitly cut text into the numeric buffers, historic vi became
 * genuinely strange.  I've never been able to figure out what was supposed to
 * happen.  It behaved differently if you deleted text than if you yanked text,
 * and, in the latter case, the text was appended to the buffer instead of
 * replacing the contents.  Hopefully it's not worth getting right, and here
 * we just treat the numeric buffers like any other named buffer.
 *
 * PUBLIC: int cut __P((SCR *, ARG_CHAR_T *, MARK *, MARK *, int));
 */
int
cut(SCR *sp, ARG_CHAR_T *namep, MARK *fm, MARK *tm, int flags)
{
	CB *cbp;
	ARG_CHAR_T name = '\0';
	db_recno_t lno;
	int append, copy_one, copy_def;

	/*
	 * If the user specified a buffer, put it there.  (This may require
	 * a copy into the numeric buffers.  We do the copy so that we don't
	 * have to reference count and so we don't have to deal with things
	 * like appends to buffers that are used multiple times.)
	 *
	 * Otherwise, if it's supposed to be put in a numeric buffer (usually
	 * a delete) put it there.  The rules for putting things in numeric
	 * buffers were historically a little strange.  There were three cases.
	 *
	 *	1: Some motions are always line mode motions, which means
	 *	   that the cut always goes into the numeric buffers.
	 *	2: Some motions aren't line mode motions, e.g. d10w, but
	 *	   can cross line boundaries.  For these commands, if the
	 *	   cut crosses a line boundary, it goes into the numeric
	 *	   buffers.  This includes most of the commands.
	 *	3: Some motions aren't line mode motions, e.g. d`<char>,
	 *	   but always go into the numeric buffers, regardless.  This
	 *	   was the commands: % ` / ? ( ) N n { } -- and nvi adds ^A.
	 *
	 * Otherwise, put it in the unnamed buffer.
	 */
	append = copy_one = copy_def = 0;
	if (namep != NULL) {
		name = *namep;
		if (LF_ISSET(CUT_NUMREQ) || (LF_ISSET(CUT_NUMOPT) &&
		    (LF_ISSET(CUT_LINEMODE) || fm->lno != tm->lno))) {
			copy_one = 1;
			cb_rotate(sp);
		}
		if ((append = ISUPPER(name)) == 1) {
			if (!copy_one)
				copy_def = 1;
			name = TOLOWER(name);
		}
namecb:		CBNAME(sp, cbp, name);
	} else if (LF_ISSET(CUT_NUMREQ) || (LF_ISSET(CUT_NUMOPT) &&
	    (LF_ISSET(CUT_LINEMODE) || fm->lno != tm->lno))) {
		name = '1';
		cb_rotate(sp);
		goto namecb;
	} else
		cbp = &sp->wp->dcb_store;

copyloop:
	/*
	 * If this is a new buffer, create it and add it into the list.
	 * Otherwise, if it's not an append, free its current contents.
	 */
	if (cbp == NULL) {
		CALLOC_RET(sp, cbp, CB *, 1, sizeof(CB));
		cbp->name = name;
		CIRCLEQ_INIT(&cbp->textq);
		LIST_INSERT_HEAD(&sp->wp->cutq, cbp, q);
	} else if (!append) {
Пример #15
0
Файл: exf.c Проект: fishman/nvi
/*
 * file_init --
 *	Start editing a file, based on the FREF structure.  If successsful,
 *	let go of any previous file.  Don't release the previous file until
 *	absolutely sure we have the new one.
 *
 * PUBLIC: int file_init __P((SCR *, FREF *, char *, int));
 */
int
file_init(SCR *sp, FREF *frp, char *rcv_name, int flags)
{
    EXF *ep;
    struct stat sb;
    size_t psize;
    int fd, exists, open_err, readonly, stolen;
    char *oname, tname[MAXPATHLEN];

    stolen = open_err = readonly = 0;

    /*
     * If the file is a recovery file, let the recovery code handle it.
     * Clear the FR_RECOVER flag first -- the recovery code does set up,
     * and then calls us!  If the recovery call fails, it's probably
     * because the named file doesn't exist.  So, move boldly forward,
     * presuming that there's an error message the user will get to see.
     */
    if (F_ISSET(frp, FR_RECOVER)) {
        F_CLR(frp, FR_RECOVER);
        return (rcv_read(sp, frp));
    }

    /*
     * Required FRP initialization; the only flag we keep is the
     * cursor information.
     */
    F_CLR(frp, ~FR_CURSORSET);

    /*
     * Scan the user's path to find the file that we're going to
     * try and open.
     */
    if (file_spath(sp, frp, &sb, &exists))
        return (1);

    /*
     * Check whether we already have this file opened in some
     * other screen.
     */
    if (exists) {
        EXF *exfp;
        for (exfp = sp->gp->exfq.cqh_first;
                exfp != (EXF *)&sp->gp->exfq; exfp = exfp->q.cqe_next) {
            if (exfp->mdev == sb.st_dev &&
                    exfp->minode == sb.st_ino &&
                    (exfp != sp->ep || exfp->refcnt > 1)) {
                ep = exfp;
                goto postinit;
            }
        }
    }

    /*
     * Required EXF initialization:
     *	Flush the line caches.
     *	Default recover mail file fd to -1.
     *	Set initial EXF flag bits.
     */
    CALLOC_RET(sp, ep, EXF *, 1, sizeof(EXF));
    CIRCLEQ_INIT(&ep->scrq);
    sp->c_lno = ep->c_nlines = OOBLNO;
    ep->rcv_fd = ep->fcntl_fd = -1;
    F_SET(ep, F_FIRSTMODIFY);

    /*
     * If no name or backing file, for whatever reason, create a backing
     * temporary file, saving the temp file name so we can later unlink
     * it.  If the user never named this file, copy the temporary file name
     * to the real name (we display that until the user renames it).
     */
    oname = frp->name;
    if (LF_ISSET(FS_OPENERR) || oname == NULL || !exists) {
        if (opts_empty(sp, O_TMP_DIRECTORY, 0))
            goto err;
        (void)snprintf(tname, sizeof(tname),
                       "%s/vi.XXXXXX", O_STR(sp, O_TMP_DIRECTORY));
        if ((fd = mkstemp(tname)) == -1) {
            msgq(sp, M_SYSERR,
                 "237|Unable to create temporary file");
            goto err;
        }
        (void)close(fd);

        if (frp->name == NULL)
            F_SET(frp, FR_TMPFILE);
        if ((frp->tname = strdup(tname)) == NULL ||
                (frp->name == NULL &&
                 (frp->name = strdup(tname)) == NULL)) {
            if (frp->tname != NULL) {
                free(frp->tname);
            }
            msgq(sp, M_SYSERR, NULL);
            (void)unlink(tname);
            goto err;
        }
        oname = frp->tname;
        psize = 1024;
        if (!LF_ISSET(FS_OPENERR))
            F_SET(frp, FR_NEWFILE);

        time(&ep->mtime);
    } else {
        /*
         * XXX
         * A seat of the pants calculation: try to keep the file in
         * 15 pages or less.  Don't use a page size larger than 10K
         * (vi should have good locality) or smaller than 1K.
         */
        psize = ((sb.st_size / 15) + 1023) / 1024;
        if (psize > 10)
            psize = 10;
        if (psize == 0)
            psize = 1;
        psize *= 1024;

        F_SET(ep, F_DEVSET);
        ep->mdev = sb.st_dev;
        ep->minode = sb.st_ino;

        ep->mtime = sb.st_mtime;

        if (!S_ISREG(sb.st_mode))
            msgq_str(sp, M_ERR, oname,
                     "238|Warning: %s is not a regular file");
    }

    /* Set up recovery. */
    if (rcv_name == NULL) {
        /* ep->rcv_path NULL if rcv_tmp fails */
        rcv_tmp(sp, ep, frp->name);
    } else {
        if ((ep->rcv_path = strdup(rcv_name)) == NULL) {
            msgq(sp, M_SYSERR, NULL);
            goto err;
        }
        F_SET(ep, F_MODIFIED);
    }

    if (db_setup(sp, ep))
        goto err;

    /* Open a db structure. */
    if ((sp->db_error = db_create(&ep->db, 0, 0)) != 0) {
        msgq(sp, M_DBERR, "db_create");
        goto err;
    }

    ep->db->set_re_delim(ep->db, '\n');		/* Always set. */
    ep->db->set_pagesize(ep->db, psize);
    ep->db->set_flags(ep->db, DB_RENUMBER | DB_SNAPSHOT);
    if (rcv_name == NULL)
        ep->db->set_re_source(ep->db, oname);

    /*
     * Don't let db use mmap when using fcntl for locking
     */
#ifdef HAVE_LOCK_FCNTL
#define NOMMAPIFFCNTL DB_NOMMAP
#else
#define NOMMAPIFFCNTL 0
#endif

#define _DB_OPEN_MODE	S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH

    if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO,
                                ((rcv_name == 0) ? DB_TRUNCATE : 0) | VI_DB_THREAD | NOMMAPIFFCNTL,
                                _DB_OPEN_MODE)) != 0) {
        msgq_str(sp,
                 M_DBERR, rcv_name == NULL ? oname : rcv_name, "%s");
        /*
         * !!!
         * Historically, vi permitted users to edit files that couldn't
         * be read.  This isn't useful for single files from a command
         * line, but it's quite useful for "vi *.c", since you can skip
         * past files that you can't read.
         */
        ep->db = NULL; /* Don't close it; it wasn't opened */

        if (LF_ISSET(FS_OPENERR))
            goto err;

        open_err = 1;
        goto oerr;
    }

    /* re_source is loaded into the database.
     * Close it and reopen it in the environment.
     */
    if ((sp->db_error = ep->db->close(ep->db, 0))) {
        msgq(sp, M_DBERR, "close");
        goto err;
    }
    if ((sp->db_error = db_create(&ep->db, ep->env, 0)) != 0) {
        msgq(sp, M_DBERR, "db_create 2");
        goto err;
    }
    if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO,
                                VI_DB_THREAD | NOMMAPIFFCNTL, _DB_OPEN_MODE)) != 0) {
        msgq_str(sp,
                 M_DBERR, ep->rcv_path, "%s");
        goto err;
    }

    /*
     * Do the remaining things that can cause failure of the new file,
     * mark and logging initialization.
     */
    if (mark_init(sp, ep) || log_init(sp, ep))
        goto err;

postinit:
    /*
     * Set the alternate file name to be the file we're discarding.
     *
     * !!!
     * Temporary files can't become alternate files, so there's no file
     * name.  This matches historical practice, although it could only
     * happen in historical vi as the result of the initial command, i.e.
     * if vi was executed without a file name.
     */
    if (LF_ISSET(FS_SETALT))
        set_alt_name(sp, sp->frp == NULL ||
                     F_ISSET(sp->frp, FR_TMPFILE) ? NULL : sp->frp->name);

    /*
     * Close the previous file; if that fails, close the new one and run
     * for the border.
     *
     * !!!
     * There's a nasty special case.  If the user edits a temporary file,
     * and then does an ":e! %", we need to re-initialize the backing
     * file, but we can't change the name.  (It's worse -- we're dealing
     * with *names* here, we can't even detect that it happened.)  Set a
     * flag so that the file_end routine ignores the backing information
     * of the old file if it happens to be the same as the new one.
     *
     * !!!
     * Side-effect: after the call to file_end(), sp->frp may be NULL.
     */
    if (sp->ep != NULL) {
        F_SET(frp, FR_DONTDELETE);
        if (file_end(sp, NULL, LF_ISSET(FS_FORCE))) {
            (void)file_end(sp, ep, 1);
            goto err;
        }
        sp->ep = NULL;
        F_CLR(frp, FR_DONTDELETE);
    }

    /*
     * Lock the file; if it's a recovery file, it should already be
     * locked.  Note, we acquire the lock after the previous file
     * has been ended, so that we don't get an "already locked" error
     * for ":edit!".
     *
     * XXX
     * While the user can't interrupt us between the open and here,
     * there's a race between the dbopen() and the lock.  Not much
     * we can do about it.
     *
     * XXX
     * We don't make a big deal of not being able to lock the file.  As
     * locking rarely works over NFS, and often fails if the file was
     * mmap(2)'d, it's far too common to do anything like print an error
     * message, let alone make the file readonly.  At some future time,
     * when locking is a little more reliable, this should change to be
     * an error.
     */
    if (rcv_name == NULL && ep->refcnt == 0) {
        if ((ep->fd = open(oname, O_RDWR)) == -1)
            goto no_lock;

        switch (file_lock(sp, oname, &ep->fcntl_fd, ep->fd, 1)) {
        case LOCK_FAILED:
no_lock:
            F_SET(frp, FR_UNLOCKED);
            break;
        case LOCK_UNAVAIL:
            readonly = 1;
            msgq_str(sp, M_INFO, oname,
                     "239|%s already locked, session is read-only");
            break;
        case LOCK_SUCCESS:
            break;
        }
    }

    /*
         * Historically, the readonly edit option was set per edit buffer in
         * vi, unless the -R command-line option was specified or the program
         * was executed as "view".  (Well, to be truthful, if the letter 'w'
         * occurred anywhere in the program name, but let's not get into that.)
     * So, the persistant readonly state has to be stored in the screen
     * structure, and the edit option value toggles with the contents of
     * the edit buffer.  If the persistant readonly flag is set, set the
     * readonly edit option.
     *
     * Otherwise, try and figure out if a file is readonly.  This is a
     * dangerous thing to do.  The kernel is the only arbiter of whether
     * or not a file is writeable, and the best that a user program can
     * do is guess.  Obvious loopholes are files that are on a file system
     * mounted readonly (access catches this one on a few systems), or
     * alternate protection mechanisms, ACL's for example, that we can't
     * portably check.  Lots of fun, and only here because users whined.
     *
     * !!!
     * Historic vi displayed the readonly message if none of the file
     * write bits were set, or if an an access(2) call on the path
     * failed.  This seems reasonable.  If the file is mode 444, root
     * users may want to know that the owner of the file did not expect
     * it to be written.
     *
     * Historic vi set the readonly bit if no write bits were set for
     * a file, even if the access call would have succeeded.  This makes
     * the superuser force the write even when vi expects that it will
     * succeed.  I'm less supportive of this semantic, but it's historic
     * practice and the conservative approach to vi'ing files as root.
     *
     * It would be nice if there was some way to update this when the user
     * does a "^Z; chmod ...".  The problem is that we'd first have to
     * distinguish between readonly bits set because of file permissions
     * and those set for other reasons.  That's not too hard, but deciding
     * when to reevaluate the permissions is trickier.  An alternative
     * might be to turn off the readonly bit if the user forces a write
     * and it succeeds.
     *
     * XXX
     * Access(2) doesn't consider the effective uid/gid values.  This
     * probably isn't a problem for vi when it's running standalone.
     */
    if (readonly || F_ISSET(sp, SC_READONLY) ||
            (!F_ISSET(frp, FR_NEWFILE) &&
             (!(sb.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) ||
              access(frp->name, W_OK))))
        O_SET(sp, O_READONLY);
    else
        O_CLR(sp, O_READONLY);

    /* Switch... */
    ++ep->refcnt;
    CIRCLEQ_INSERT_HEAD(&ep->scrq, sp, eq);
    sp->ep = ep;
    sp->frp = frp;

    /* Set the initial cursor position, queue initial command. */
    file_cinit(sp);

    /* Report conversion errors again. */
    F_CLR(sp, SC_CONV_ERROR);

    /* Redraw the screen from scratch, schedule a welcome message. */
    F_SET(sp, SC_SCR_REFORMAT | SC_STATUS);

    if (frp->lno == OOBLNO)
        F_SET(sp, SC_SCR_TOP);

    /* Append into the chain of file structures. */
    if (ep->refcnt == 1)
        CIRCLEQ_INSERT_TAIL(&sp->gp->exfq, ep, q);

    return (0);

err:
    if (frp->name != NULL) {
        free(frp->name);
        frp->name = NULL;
    }
    if (frp->tname != NULL) {
        (void)unlink(frp->tname);
        free(frp->tname);
        frp->tname = NULL;
    }

oerr:
    if (F_ISSET(ep, F_RCV_ON))
        (void)unlink(ep->rcv_path);
    if (ep->rcv_path != NULL) {
        free(ep->rcv_path);
        ep->rcv_path = NULL;
    }
    if (ep->db != NULL) {
        (void)ep->db->close(ep->db, DB_NOSYNC);
        ep->db = NULL;
    }
    free(ep);

    return (open_err && !LF_ISSET(FS_OPENERR) ?
            file_init(sp, frp, rcv_name, flags | FS_OPENERR) : 1);
}
Пример #16
0
void InitProcessTables (void)
{
    uint32 t;
    struct Process *proc;
    struct Timer *timer;
    struct ISRHandler *isr_handler;
    struct Channel *channel;
    struct Handle *handle;
    struct Parcel *parcel;
    
    KPRINTF ("InitProcessTables()");
        
        
    for (t=0;t<NIRQ;t++)
    {
        LIST_INIT (&isr_handler_list[t]);
    }
        
    for (t=0; t<32; t++)
    {
        CIRCLEQ_INIT (&realtime_queue[t]);
    }
    
    LIST_INIT (&stride_queue);
    
    
    LIST_INIT (&free_process_list)
        
    for (t=0; t<max_process; t++)
    {
        proc = (struct Process *)((uint8 *)process_table + t*PROCESS_SZ);
        
        LIST_ADD_TAIL (&free_process_list, proc, free_entry);
        proc->state = PROC_STATE_UNALLOC;
    }
    
    for (t=0; t<JIFFIES_PER_SECOND; t++)
    {
        LIST_INIT(&timing_wheel[t]);
    }
        
    softclock_seconds = hardclock_seconds = 0;
    softclock_jiffies = hardclock_jiffies = 0;

    LIST_INIT (&free_timer_list);
    
    for (t=0; t < max_timer; t++)
    {
        timer = &timer_table[t];
        LIST_ADD_TAIL (&free_timer_list, timer, timer_entry);
    }
        
    LIST_INIT (&free_isr_handler_list);
    
    for (t=0; t < max_isr_handler; t++)
    {
        isr_handler = &isr_handler_table[t];
        LIST_ADD_TAIL (&free_isr_handler_list, isr_handler, isr_handler_entry);
    }
        
        
    LIST_INIT (&free_channel_list);
    
    for (t=0; t < max_channel; t++)
    {
        channel = &channel_table[t];
        LIST_ADD_TAIL (&free_channel_list, channel, link);
    }
    
    
    LIST_INIT (&free_handle_list);
    
    for (t = 0; t < max_handle; t++)
    {
        handle = &handle_table[t];
        handle->type = HANDLE_TYPE_FREE;
        handle->pending = 0;
        handle->owner = NULL;
        handle->object = NULL;
        handle->flags = 0;
        
        LIST_ADD_TAIL (&free_handle_list, handle, link);
    }
    
    
    LIST_INIT (&free_parcel_list);
    
    for (t=0; t < max_parcel; t++)
    {
        parcel = &parcel_table[t];
        LIST_ADD_TAIL (&free_parcel_list, parcel, link);
    }
}