Пример #1
0
int Gpm_GetEvent(Gpm_Event *e){
    VimEvent event;

    int n = read(gpm_fd, (void*)&event, sizeof(VimEvent));
    if(event.type == VIM_EVENT_TYPE_GPM) {
        memcpy(e, (void*)&event.event.gpm, sizeof(Gpm_Event));
        return 1;
    }else if(event.type == VIM_EVENT_TYPE_CMD) {
        do_cmdline_cmd((char_u *) event.event.cmd);
    }else if(event.type == VIM_EVENT_TYPE_RELINE) {
        char* str = event.event.cmd;
        ml_replace(curwin->w_cursor.lnum,(char_u*)str, TRUE);
        changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L);
    }else if(event.type == VIM_EVENT_TYPE_UPDATE){
        vimtouch_lock();
        update_screen(0);
        setcursor();
        out_flush();
        vimtouch_unlock();
    }else if(event.type == VIM_EVENT_TYPE_SETCOL){
        curwin->w_cursor.col = event.event.num;
    }else if(event.type == VIM_EVENT_TYPE_SCROLL){
        int do_scroll = event.event.num;
        scroll_redraw(do_scroll > 0, do_scroll>0?do_scroll:-do_scroll);
    }else if(event.type == VIM_EVENT_TYPE_RESIZE){
        out_flush();
        shell_resized_check();
        redraw_later(CLEAR);
        update_screen(CLEAR);
        out_flush();
    }
    return 0;
}
Пример #2
0
int Gpm_GetEvent(Gpm_Event *e){
    VimEvent event;

    int n = read(gpm_fd, (void*)&event, sizeof(VimEvent));
    if(event.type == VIM_EVENT_TYPE_GPM) {
        memcpy(e, (void*)&event.event.gpm, sizeof(Gpm_Event));
        return 1;
    }else if(event.type == VIM_EVENT_TYPE_ANDROID_SEND) {
        vimtouch_send_android_event(event.event.num, (char_u *) &event.event.nums[1]);
		return 0;
    }else if(event.type == VIM_EVENT_TYPE_CMD) {
        do_cmdline_cmd((char_u *) event.event.cmd);
    }else if(event.type == VIM_EVENT_TYPE_RELINE) {
        char* str = event.event.cmd;
        ml_replace(curwin->w_cursor.lnum,(char_u*)str, TRUE);
        changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L);
    }else if(event.type == VIM_EVENT_TYPE_UPDATE){
        //vimtouch_lock();
        update_screen(0);
        setcursor();
        out_flush();
        //vimtouch_unlock();
    }else if(event.type == VIM_EVENT_TYPE_CURSOR){
        mouse_col = event.event.nums[0];
        mouse_row = event.event.nums[1];

        jump_to_mouse(MOUSE_DID_MOVE, NULL, 0);
    }else if(event.type == VIM_EVENT_TYPE_SETCOL){
        curwin->w_cursor.col = event.event.num;
    }else if(event.type == VIM_EVENT_TYPE_SCROLL){
        int do_scroll = event.event.num;
        scroll_redraw(do_scroll > 0, do_scroll>0?do_scroll:-do_scroll);
    }else if(event.type == VIM_EVENT_TYPE_RESIZE){
        out_flush();
        shell_resized_check();
        redraw_later(CLEAR);
        out_flush();
    }else if(event.type == VIM_EVENT_TYPE_SETTAB){
        int nr = event.event.nums[0];

        if (nr != tabpage_index(curtab)){
            current_tab = nr;
            if (current_tab == 255)     /* -1 in a byte gives 255 */
            current_tab = -1;
            goto_tabpage(current_tab);
            update_screen(CLEAR);
            out_flush();
        }
    }else if(event.type == VIM_EVENT_TYPE_HISTORY){
        char buf[1024];
        int i = 1;
        for(i = 1; i <= 10; i++){
            sprintf(buf, "HISTORY:%d,%s\n",i-1,get_history_entry(HIST_CMD,i));
            write(gpm_fd,buf,strlen(buf));
        }
    }
    vimtouch_sync();
    return 0;
}
Пример #3
0
/* use cols for offsets only, load actual data from *data */
static void proc_row_fake(struct Context *ctx, PGresult *res, PGdataValue *cols, char *data)
{
	int n = PQnfields(res);
	const char *val;
	int i, vlen;
	const char *xstart = cols[0].value;

	ctx->count++;

	for (i = 0; i < n; i++) {
		if (i > 0)
			out_char(ctx, '\t');
		if (cols[i].len == -1) {
			out_char(ctx, '\\');
			out_char(ctx, 'N');
			continue;
		}

		vlen = cols[i].len;

		/* recalcuate value into *data */
		val = data + (cols[i].value - xstart);

		proc_value(ctx, val, vlen);
	}
	out_char(ctx, '\n');
	out_flush(ctx);
}
Пример #4
0
/*
 * print the changelist
 */
void ex_changes(exarg_T *eap)
{
  int i;
  char_u      *name;

  /* Highlight title */
  MSG_PUTS_TITLE(_("\nchange line  col text"));

  for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i) {
    if (curbuf->b_changelist[i].lnum != 0) {
      msg_putchar('\n');
      if (got_int)
        break;
      sprintf((char *)IObuff, "%c %3d %5ld %4d ",
          i == curwin->w_changelistidx ? '>' : ' ',
          i > curwin->w_changelistidx ? i - curwin->w_changelistidx
          : curwin->w_changelistidx - i,
          (long)curbuf->b_changelist[i].lnum,
          curbuf->b_changelist[i].col);
      msg_outtrans(IObuff);
      name = mark_line(&curbuf->b_changelist[i], 17);
      if (name == NULL)
        break;
      msg_outtrans_attr(name, hl_attr(HLF_D));
      vim_free(name);
      ui_breakcheck();
    }
    out_flush();
  }
  if (curwin->w_changelistidx == curbuf->b_changelistlen)
    MSG_PUTS("\n>");
}
Пример #5
0
static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
{
  // TODO(tarruda): avoid using a growable array for this, refactor the
  // algorithm to call `ml_append` directly(skip unecessary copies/resizes)
  int i;
  ProcessData *pdata = (ProcessData *)stream->data;

  if (cnt <= 0) {
    if (cnt != UV_ENOBUFS) {
      uv_read_stop(stream);
      uv_close((uv_handle_t *)stream, NULL);
      pdata->exited++;
    }
    return;
  }

  for (i = 0; i < cnt; ++i) {
    if (pdata->rbuffer[i] == NL) {
      // Insert the line
      append_ga_line(&pdata->ga);
    } else if (pdata->rbuffer[i] == NUL) {
      // Translate NUL to NL
      ga_append(&pdata->ga, NL);
    } else {
      // buffer data into the grow array
      ga_append(&pdata->ga, pdata->rbuffer[i]);
    }
  }

  windgoto(msg_row, msg_col);
  cursor_on();
  out_flush();

  pdata->reading = false;
}
Пример #6
0
static void out_push (out_t *out, const u8 *pw_buf, const int pw_len)
{
  char *ptr = out->buf + out->len;

  memcpy (ptr, pw_buf, pw_len);

  #if defined (_WIN)

  ptr[pw_len + 0] = '\r';
  ptr[pw_len + 1] = '\n';

  out->len += pw_len + 2;

  #else

  ptr[pw_len] = '\n';

  out->len += pw_len + 1;

  #endif

  if (out->len >= HCBUFSIZ_TINY - 300)
  {
    out_flush (out);
  }
}
Пример #7
0
static void vimtouch_Exec_setPtyWindowSize(JNIEnv *env, jobject clazz,
    jobject fileDescriptor, jint row, jint col, jint xpixel, jint ypixel)
{
    int fd;
    struct winsize sz;

    fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);

    if (env->ExceptionOccurred() != NULL) {
        return;
    }
    
    sz.ws_row = row;
    sz.ws_col = col;
    sz.ws_xpixel = xpixel;
    sz.ws_ypixel = ypixel;
    
    ioctl(fd, TIOCSWINSZ, &sz);

    vimtouch_lock();
    out_flush();
    shell_resized_check();
    redraw_later(CLEAR);
    vimtouch_unlock();
    //update_screen(CLEAR);
    //setcursor();
    //out_flush();
}
Пример #8
0
/*
 * If the machine has job control, use it to suspend the program,
 * otherwise fake it by starting a new shell.
 */
void mch_suspend()
{
  /* BeOS does have SIGTSTP, but it doesn't work. */
#if defined(SIGTSTP) && !defined(__BEOS__)
  out_flush();              /* needed to make cursor visible on some systems */
  settmode(TMODE_COOK);
  out_flush();              /* needed to disable mouse on some systems */


# if defined(_REENTRANT) && defined(SIGCONT)
  sigcont_received = FALSE;
# endif
  kill(0, SIGTSTP);         /* send ourselves a STOP signal */
# if defined(_REENTRANT) && defined(SIGCONT)
  /*
   * Wait for the SIGCONT signal to be handled. It generally happens
   * immediately, but somehow not all the time. Do not call pause()
   * because there would be race condition which would hang Vim if
   * signal happened in between the test of sigcont_received and the
   * call to pause(). If signal is not yet received, call sleep(0)
   * to just yield CPU. Signal should then be received. If somehow
   * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
   * further if signal is not received after 1+2+3+4 ms (not expected
   * to happen).
   */
  {
    long wait_time;
    for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++)
      /* Loop is not entered most of the time */
      os_delay(wait_time, FALSE);
  }
# endif

  /*
   * Set oldtitle to NULL, so the current title is obtained again.
   */
  vim_free(oldtitle);
  oldtitle = NULL;
  settmode(TMODE_RAW);
  need_check_timestamps = TRUE;
  did_check_timestamps = FALSE;
#else
  suspend_shell();
#endif
}
Пример #9
0
 virtual bool receive_request(talas::protocol::tls::connection& connection) {
     bool success = true;
     string_t request;
     if ((success = read_http(connection, request))) {
         out(request.chars(), request.length());
         out_flush();
     }
     return success;
 }
Пример #10
0
static void updateScreen()
{
    vimtouch_lock();
    //redraw_later(NOT_VALID);
    update_screen(0);
    //setcursor();
    out_flush();
    vimtouch_unlock();
}
Пример #11
0
static int vimtouch_Exec_scrollBy(JNIEnv *env, jobject clazz,
    jint line) {
    int do_scroll = line;
    vimtouch_lock();
    scroll_redraw(do_scroll > 0, do_scroll>0?do_scroll:-do_scroll);
    update_screen(0);
    out_flush();
    vimtouch_unlock();
    return line;
}
Пример #12
0
void mch_init()
{
  Columns = 80;
  Rows = 24;

  out_flush();

#ifdef MACOS_CONVERT
  mac_conv_init();
#endif

  event_init();
}
Пример #13
0
/*
 * Set the window title and icon.
 */
void mch_settitle(char_u *title, char_u *icon)
{
  int type = 0;
  static int recursive = 0;

  if (T_NAME == NULL)       /* no terminal name (yet) */
    return;
  if (title == NULL && icon == NULL)        /* nothing to do */
    return;

  /* When one of the X11 functions causes a deadly signal, we get here again
   * recursively.  Avoid hanging then (something is probably locked). */
  if (recursive)
    return;
  ++recursive;

  /*
   * if the window ID and the display is known, we may use X11 calls
   */

  /*
   * Note: if "t_ts" is set, title is set with escape sequence rather
   *	     than x11 calls, because the x11 calls don't always work
   */
  if ((type || *T_TS != NUL) && title != NULL) {
    if (oldtitle == NULL
        )                       /* first call but not in GUI, save title */
      (void)get_x11_title(FALSE);

    if (*T_TS != NUL)                   /* it's OK if t_fs is empty */
      term_settitle(title);
    did_set_title = TRUE;
  }

  if ((type || *T_CIS != NUL) && icon != NULL) {
    if (oldicon == NULL
        )                       /* first call, save icon */
      get_x11_icon(FALSE);

    if (*T_CIS != NUL) {
      out_str(T_CIS);                           /* set icon start */
      out_str_nf(icon);
      out_str(T_CIE);                           /* set icon end */
      out_flush();
    }
    did_set_icon = TRUE;
  }
  --recursive;
}
Пример #14
0
static void 
show_one_mark (
    int c,
    char_u *arg,
    pos_T *p,
    char_u *name,
    int current                    /* in current file */
)
{
  static int did_title = FALSE;
  int mustfree = FALSE;

  if (c == -1) {                            /* finish up */
    if (did_title)
      did_title = FALSE;
    else {
      if (arg == NULL)
        MSG(_("No marks set"));
      else
        EMSG2(_("E283: No marks matching \"%s\""), arg);
    }
  }
  /* don't output anything if 'q' typed at --more-- prompt */
  else if (!got_int
           && (arg == NULL || vim_strchr(arg, c) != NULL)
           && p->lnum != 0) {
    if (!did_title) {
      /* Highlight title */
      MSG_PUTS_TITLE(_("\nmark line  col file/text"));
      did_title = TRUE;
    }
    msg_putchar('\n');
    if (!got_int) {
      sprintf((char *)IObuff, " %c %6ld %4d ", c, p->lnum, p->col);
      msg_outtrans(IObuff);
      if (name == NULL && current) {
        name = mark_line(p, 15);
        mustfree = TRUE;
      }
      if (name != NULL) {
        msg_outtrans_attr(name, current ? hl_attr(HLF_D) : 0);
        if (mustfree)
          vim_free(name);
      }
    }
    out_flush();                    /* show one line at a time */
  }
}
Пример #15
0
/*
 * Initialize the icon information for a new sign
 */
    static void
sign_define_init_icon(sign_T *sp, char_u *icon)
{
    vim_free(sp->sn_icon);
    sp->sn_icon = vim_strsave(icon);
    backslash_halve(sp->sn_icon);
# ifdef FEAT_SIGN_ICONS
    if (gui.in_use)
    {
	out_flush();
	if (sp->sn_image != NULL)
	    gui_mch_destroy_sign(sp->sn_image);
	sp->sn_image = gui_mch_register_sign(sp->sn_icon);
    }
# endif
}
Пример #16
0
void out_action
(
    char const * const action,
    char const * const target,
    char const * const command,
    char const * const out_d,
    char const * const err_d,
    int const exit_reason
)
{
    /* Print out the action + target line, if the action is quiet the action
     * should be null.
     */
    if ( action )
        out_printf( "%s %s\n", action, target );

    /* Print out the command executed if given -d+2. */
    if ( DEBUG_EXEC )
    {
        out_puts( command );
        out_putc( '\n' );
    }

    /* If the process expired, make user aware with an explicit message, but do
     * this only for non-quiet actions.
     */
    if ( exit_reason == EXIT_TIMEOUT && action )
        out_printf( "%ld second time limit exceeded\n", globs.timeout );

    /* Print out the command output, if requested, or if the program failed, but
     * only output for non-quiet actions.
     */
    if ( action || exit_reason != EXIT_OK )
    {
        if ( out_d &&
           ( ( globs.pipe_action & 1 /* STDOUT_FILENO */ ) ||
             ( globs.pipe_action == 0 ) ) )
            out_data( out_d );
        if ( err_d && ( globs.pipe_action & 2 /* STDERR_FILENO */ ) )
            err_data( err_d );
    }

    out_flush();
    err_flush();
}
Пример #17
0
/* Flush the output forwarding buffer if it is time or say how long until it
 * will be time.
 */
time_t
out_flush_ck(const struct timeval *now, time_t delay)
{
	time_t ms;
	struct timeval now0;

	if (time_out_flush.tv_sec == 0)
		return (delay);

	if (now == NULL) {
		gettimeofday(&now0, NULL);
		now = &now0;
	}

	ms = OUT_FLUSH_MS - axa_elapsed_ms(now, &time_out_flush);
	if (ms > 0)
		return (max(delay, ms));

	out_flush();
	return (delay);
}
Пример #18
0
void
out_ip_pcap_file(const uint8_t *pkt, size_t caplen, size_t len,
		 const struct timeval *tv)
{
	/* From pcap-int.h, which is not present on some systems,
	 * and written in the stone of uncounted saved pcap files. */
	struct {
		struct {
			int32_t	    tv_sec;
			int32_t	    tv_usec;
		} ts;			/* time stamp */
		bpf_u_int32 caplen;	/* length of portion present */
		bpf_u_int32 len;	/* length this packet (off wire) */
	} sf_hdr;

	if (caplen > sizeof(out_buf) - sizeof(sf_hdr) - out_buf_len
	    || out_buf_base != 0) {
		out_flush();
		if (caplen > sizeof(out_buf) - sizeof(sf_hdr) - out_buf_len) {
			out_error("forwarding output stalled; dropping");
			return;
		}
	}

	/* Use the official version of struct pcap_sf_pkthdr and hope
	 * even the "experts" with "patched" versions can handle the
	 * standard form. */
	sf_hdr.ts.tv_sec = tv->tv_sec;
	sf_hdr.ts.tv_usec = tv->tv_usec;
	sf_hdr.caplen = caplen;
	sf_hdr.len = len;

	memcpy(&out_buf[out_buf_len], &sf_hdr, sizeof(sf_hdr));
	out_buf_len += sizeof(sf_hdr);
	memcpy(&out_buf[out_buf_len], pkt, caplen);
	out_buf_len += caplen;
	if (time_out_flush.tv_sec == 0)
		gettimeofday(&time_out_flush, NULL);
}
Пример #19
0
/*
 * print the jumplist
 */
void ex_jumps(exarg_T *eap)
{
  int i;
  char_u      *name;

  cleanup_jumplist();
  /* Highlight title */
  MSG_PUTS_TITLE(_("\n jump line  col file/text"));
  for (i = 0; i < curwin->w_jumplistlen && !got_int; ++i) {
    if (curwin->w_jumplist[i].fmark.mark.lnum != 0) {
      if (curwin->w_jumplist[i].fmark.fnum == 0)
        fname2fnum(&curwin->w_jumplist[i]);
      name = fm_getname(&curwin->w_jumplist[i].fmark, 16);
      if (name == NULL)             /* file name not available */
        continue;

      msg_putchar('\n');
      if (got_int) {
        vim_free(name);
        break;
      }
      sprintf((char *)IObuff, "%c %2d %5ld %4d ",
          i == curwin->w_jumplistidx ? '>' : ' ',
          i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx
          : curwin->w_jumplistidx - i,
          curwin->w_jumplist[i].fmark.mark.lnum,
          curwin->w_jumplist[i].fmark.mark.col);
      msg_outtrans(IObuff);
      msg_outtrans_attr(name,
          curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
          ? hl_attr(HLF_D) : 0);
      vim_free(name);
      ui_breakcheck();
    }
    out_flush();
  }
  if (curwin->w_jumplistidx == curwin->w_jumplistlen)
    MSG_PUTS("\n>");
}
Пример #20
0
    static void
load_window(
	char	*filename,		/* filename to load */
	int	 lnum)			/* linenumber to go to */
{
    buf_T	*buf;		/* buffer filename is stored in */
    win_T	*win;		/* window filenme is displayed in */

    /*
     * Make sure filename is displayed and is the current window.
     */

    buf = buflist_findname((char_u *)filename);
    if (buf == NULL || (win = get_window(buf)) == NULL)
    {
	/* No buffer or buffer is not in current window */
	/* wsdebug("load_window: load_buffer_by_name(\"%s\", %d)\n",
		filename, lnum); */
	load_buffer_by_name(filename, lnum);
    }
    else
    {
	/* buf is in a window */
	if (win != curwin)
	{
	    win_enter(win, False);
	    /* wsdebug("load_window: window endter %s\n",
		    win->w_buffer->b_sfname); */
	}
	if (lnum > 0 && win->w_cursor.lnum != lnum)
	{
	    warp_to_pc(lnum);
	    /* wsdebug("load_window: warp to %s[%d]\n",
		    win->w_buffer->b_sfname, lnum); */
	}
    }
    out_flush();
}
Пример #21
0
Файл: hd.c Проект: seppo0010/hd
static inline void out_line(char *bp, int bcnt) {
  if (op + end_off + 1 >= obuf_end)
    out_flush();

  if (f_duprm && pdat_mod && bcnt == n_byt &&
      0 == memcmp(pdat, bp, n_byt)) {
    if (pdat_mod == 1) {
      *op++= '*'; *op++= '\n';
      pdat_mod= 2;
    }
    return;
  }
  
  memcpy(pdat, bp, n_byt);
  pdat_mod= 1;

  memset(op, ' ', end_off);
  ocl= op;
  opp= op + hxoff[bcnt-1] + 2;

  if (f_addr) {
    hex(op, addr>>16);
    hex(op+2, addr>>8);
    hex(op+4, addr);
    op[6]= ':';
  }

  int a;
  for (a= 0; a<bcnt; a++) {
    int ch= bp[a] & 255;
    hex(op + hxoff[a], ch);
    op[choff[a]]= (ch < ' ' || ch >= 127) ? '.' : ch;
  }
  op += choff[bcnt-1]+1;
  *op++= '\n';
}
Пример #22
0
/* quote one row for copy from regular PGresult */
static void proc_row(struct Context *ctx, PGresult *res, int tup)
{
	int n = PQnfields(res);
	const char *val;
	int i, vlen;

	ctx->count++;

	for (i = 0; i < n; i++) {
		if (i > 0)
			out_char(ctx, '\t');
		if (PQgetisnull(res, tup, i)) {
			out_char(ctx, '\\');
			out_char(ctx, 'N');
			continue;
		}

		vlen = PQgetlength(res, tup, i);
		val = PQgetvalue(res, tup, i);
		proc_value(ctx, val, vlen);
	}
	out_char(ctx, '\n');
	out_flush(ctx);
}
Пример #23
0
/* load row data directly from network buffer */
static void proc_row_zcopy(struct Context *ctx, PGresult *res, PGdataValue *cols)
{
	int n = PQnfields(res);
	const char *val;
	int i, vlen;

	ctx->count++;

	for (i = 0; i < n; i++) {
		if (i > 0)
			out_char(ctx, '\t');
		if (cols[i].len == -1) {
			out_char(ctx, '\\');
			out_char(ctx, 'N');
			continue;
		}

		vlen = cols[i].len;
		val = cols[i].value;
		proc_value(ctx, val, vlen);
	}
	out_char(ctx, '\n');
	out_flush(ctx);
}
Пример #24
0
/*
 * Open the terminal version of the popup menu and don't return until it is
 * closed.
 */
    void
pum_show_popupmenu(vimmenu_T *menu)
{
    vimmenu_T   *mp;
    int		idx = 0;
    pumitem_T	*array;
#ifdef FEAT_BEVAL_TERM
    int		save_bevalterm = p_bevalterm;
#endif
    int		mode;

    pum_undisplay();
    pum_size = 0;
    mode = get_menu_mode_flag();

    for (mp = menu->children; mp != NULL; mp = mp->next)
	if (menu_is_separator(mp->dname)
		|| (mp->modes & mp->enabled & mode))
	    ++pum_size;

    array = (pumitem_T *)alloc_clear((unsigned)sizeof(pumitem_T) * pum_size);
    if (array == NULL)
	return;

    for (mp = menu->children; mp != NULL; mp = mp->next)
	if (menu_is_separator(mp->dname))
	    array[idx++].pum_text = (char_u *)"";
	else if (mp->modes & mp->enabled & mode)
	    array[idx++].pum_text = mp->dname;

    pum_array = array;
    pum_compute_size();
    pum_scrollbar = 0;
    pum_height = pum_size;
    pum_position_at_mouse(20);

    pum_selected = -1;
    pum_first = 0;
#  ifdef FEAT_BEVAL_TERM
    p_bevalterm = TRUE;  /* track mouse movement */
    mch_setmouse(TRUE);
#  endif

    for (;;)
    {
	int	c;

	pum_redraw();
	setcursor_mayforce(TRUE);
	out_flush();

	c = vgetc();
	if (c == ESC || c == Ctrl_C)
	    break;
	else if (c == CAR || c == NL)
	{
	    /* enter: select current item, if any, and close */
	    pum_execute_menu(menu, mode);
	    break;
	}
	else if (c == 'k' || c == K_UP || c == K_MOUSEUP)
	{
	    /* cursor up: select previous item */
	    while (pum_selected > 0)
	    {
		--pum_selected;
		if (*array[pum_selected].pum_text != NUL)
		    break;
	    }
	}
	else if (c == 'j' || c == K_DOWN || c == K_MOUSEDOWN)
	{
	    /* cursor down: select next item */
	    while (pum_selected < pum_size - 1)
	    {
		++pum_selected;
		if (*array[pum_selected].pum_text != NUL)
		    break;
	    }
	}
	else if (c == K_RIGHTMOUSE)
	{
	    /* Right mouse down: reposition the menu. */
	    vungetc(c);
	    break;
	}
	else if (c == K_LEFTDRAG || c == K_RIGHTDRAG || c == K_MOUSEMOVE)
	{
	    /* mouse moved: select item in the mouse row */
	    pum_select_mouse_pos();
	}
	else if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM || c == K_RIGHTRELEASE)
	{
	    /* left mouse click: select clicked item, if any, and close;
	     * right mouse release: select clicked item, close if any */
	    pum_select_mouse_pos();
	    if (pum_selected >= 0)
	    {
		pum_execute_menu(menu, mode);
		break;
	    }
	    if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM)
		break;
	}
    }

    vim_free(array);
    pum_undisplay();
#  ifdef FEAT_BEVAL_TERM
    p_bevalterm = save_bevalterm;
    mch_setmouse(TRUE);
#  endif
}
Пример #25
0
int process_stdout (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 pws_cnt)
{
  combinator_ctx_t *combinator_ctx = hashcat_ctx->combinator_ctx;
  hashconfig_t     *hashconfig     = hashcat_ctx->hashconfig;
  mask_ctx_t       *mask_ctx       = hashcat_ctx->mask_ctx;
  outfile_ctx_t    *outfile_ctx    = hashcat_ctx->outfile_ctx;
  straight_ctx_t   *straight_ctx   = hashcat_ctx->straight_ctx;
  user_options_t   *user_options   = hashcat_ctx->user_options;

  out_t out;

  out.fp = stdout;

  char *filename = outfile_ctx->filename;

  if (filename)
  {
    FILE *fp = fopen (filename, "ab");

    if (fp == NULL)
    {
      event_log_error (hashcat_ctx, "%s: %s", filename, strerror (errno));

      return -1;
    }

    if (lock_file (fp) == -1)
    {
      fclose (fp);

      event_log_error (hashcat_ctx, "%s: %s", filename, strerror (errno));

      return -1;
    }

    out.fp = fp;
  }

  out.len = 0;

  u32 plain_buf[64] = { 0 };

  u8 *plain_ptr = (u8 *) plain_buf;

  u32 plain_len = 0;

  const u32 il_cnt = device_param->kernel_params_buf32[30]; // ugly, i know

  if (user_options->attack_mode == ATTACK_MODE_STRAIGHT)
  {
    pw_t pw;

    for (u64 gidvid = 0; gidvid < pws_cnt; gidvid++)
    {
      const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);

      if (rc == -1)
      {
        if (filename) fclose (out.fp);

        return -1;
      }

      for (u32 il_pos = 0; il_pos < il_cnt; il_pos++)
      {
        const u32 off = device_param->innerloop_pos + il_pos;

        if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL)
        {
          for (int i = 0; i < 8; i++)
          {
            plain_buf[i] = pw.i[i];
          }

          plain_len = apply_rules_optimized (straight_ctx->kernel_rules_buf[off].cmds, &plain_buf[0], &plain_buf[4], pw.pw_len);
        }
        else
        {
          for (int i = 0; i < 64; i++)
          {
            plain_buf[i] = pw.i[i];
          }

          plain_len = apply_rules (straight_ctx->kernel_rules_buf[off].cmds, plain_buf, pw.pw_len);
        }

        if (plain_len > hashconfig->pw_max) plain_len = hashconfig->pw_max;

        out_push (&out, plain_ptr, plain_len);
      }
    }
  }
  else if (user_options->attack_mode == ATTACK_MODE_COMBI)
  {
    pw_t pw;

    for (u64 gidvid = 0; gidvid < pws_cnt; gidvid++)
    {
      const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);

      if (rc == -1)
      {
        if (filename) fclose (out.fp);

        return -1;
      }

      for (u32 il_pos = 0; il_pos < il_cnt; il_pos++)
      {
        for (int i = 0; i < 64; i++)
        {
          plain_buf[i] = pw.i[i];
        }

        plain_len = pw.pw_len;

        char *comb_buf = (char *) device_param->combs_buf[il_pos].i;
        u32   comb_len =          device_param->combs_buf[il_pos].pw_len;

        if (combinator_ctx->combs_mode == COMBINATOR_MODE_BASE_LEFT)
        {
          memcpy (plain_ptr + plain_len, comb_buf, comb_len);
        }
        else
        {
          memmove (plain_ptr + comb_len, plain_ptr, plain_len);

          memcpy (plain_ptr, comb_buf, comb_len);
        }

        plain_len += comb_len;

        if (plain_len > hashconfig->pw_max) plain_len = hashconfig->pw_max;

        out_push (&out, plain_ptr, plain_len);
      }
    }
  }
  else if (user_options->attack_mode == ATTACK_MODE_BF)
  {
    for (u64 gidvid = 0; gidvid < pws_cnt; gidvid++)
    {
      for (u32 il_pos = 0; il_pos < il_cnt; il_pos++)
      {
        u64 l_off = device_param->kernel_params_mp_l_buf64[3] + gidvid;
        u64 r_off = device_param->kernel_params_mp_r_buf64[3] + il_pos;

        u32 l_start = device_param->kernel_params_mp_l_buf32[5];
        u32 r_start = device_param->kernel_params_mp_r_buf32[5];

        u32 l_stop = device_param->kernel_params_mp_l_buf32[4];
        u32 r_stop = device_param->kernel_params_mp_r_buf32[4];

        sp_exec (l_off, (char *) plain_ptr + l_start, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, l_start, l_start + l_stop);
        sp_exec (r_off, (char *) plain_ptr + r_start, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, r_start, r_start + r_stop);

        plain_len = mask_ctx->css_cnt;

        out_push (&out, plain_ptr, plain_len);
      }
    }
  }
  else if (user_options->attack_mode == ATTACK_MODE_HYBRID1)
  {
    pw_t pw;

    for (u64 gidvid = 0; gidvid < pws_cnt; gidvid++)
    {
      const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);

      if (rc == -1)
      {
        if (filename) fclose (out.fp);

        return -1;
      }

      for (u32 il_pos = 0; il_pos < il_cnt; il_pos++)
      {
        for (int i = 0; i < 64; i++)
        {
          plain_buf[i] = pw.i[i];
        }

        plain_len = pw.pw_len;

        u64 off = device_param->kernel_params_mp_buf64[3] + il_pos;

        u32 start = 0;
        u32 stop  = device_param->kernel_params_mp_buf32[4];

        sp_exec (off, (char *) plain_ptr + plain_len, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, start, start + stop);

        plain_len += start + stop;

        out_push (&out, plain_ptr, plain_len);
      }
    }
  }
  else if (user_options->attack_mode == ATTACK_MODE_HYBRID2)
  {
    pw_t pw;

    for (u64 gidvid = 0; gidvid < pws_cnt; gidvid++)
    {
      const int rc = gidd_to_pw_t (hashcat_ctx, device_param, gidvid, &pw);

      if (rc == -1)
      {
        if (filename) fclose (out.fp);

        return -1;
      }

      for (u32 il_pos = 0; il_pos < il_cnt; il_pos++)
      {
        u64 off = device_param->kernel_params_mp_buf64[3] + gidvid;

        u32 start = 0;
        u32 stop  = device_param->kernel_params_mp_buf32[4];

        sp_exec (off, (char *) plain_ptr, mask_ctx->root_css_buf, mask_ctx->markov_css_buf, start, start + stop);

        plain_len = stop;

        char *comb_buf = (char *) device_param->combs_buf[il_pos].i;
        u32   comb_len =          device_param->combs_buf[il_pos].pw_len;

        memcpy (plain_ptr + plain_len, comb_buf, comb_len);

        plain_len += comb_len;

        if (plain_len > hashconfig->pw_max) plain_len = hashconfig->pw_max;

        out_push (&out, plain_ptr, plain_len);
      }
    }
  }

  out_flush (&out);

  if (filename) fclose (out.fp);

  return 0;
}
Пример #26
0
int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
{
  uv_stdio_container_t proc_stdio[3];
  uv_process_options_t proc_opts;
  uv_process_t proc;
  uv_pipe_t proc_stdin, proc_stdout;
  uv_write_t write_req;
  int expected_exits = 1;
  ProcessData pdata = {
    .reading = false,
    .exited = 0,
    .old_mode = cur_tmode,
    .old_state = State,
    .shell_stdin = (uv_stream_t *)&proc_stdin,
    .wbuffer = NULL,
  };

  out_flush();
  if (opts & kShellOptCooked) {
    // set to normal mode
    settmode(TMODE_COOK);
  }

  // While the child is running, ignore terminating signals
  signal_reject_deadly();

  // Create argv for `uv_spawn`
  // TODO(tarruda): we can use a static buffer for small argument vectors. 1024
  // bytes should be enough for most of the commands and if more is necessary
  // we can allocate a another buffer
  proc_opts.args = shell_build_argv(cmd, extra_shell_arg);
  proc_opts.file = proc_opts.args[0];
  proc_opts.exit_cb = exit_cb;
  // Initialize libuv structures
  proc_opts.stdio = proc_stdio;
  proc_opts.stdio_count = 3;
  // Hide window on Windows :)
  proc_opts.flags = UV_PROCESS_WINDOWS_HIDE;
  proc_opts.cwd = NULL;
  proc_opts.env = NULL;

  // The default is to inherit all standard file descriptors(this will change
  // when the UI is moved to an external process)
  proc_stdio[0].flags = UV_INHERIT_FD;
  proc_stdio[0].data.fd = 0;
  proc_stdio[1].flags = UV_INHERIT_FD;
  proc_stdio[1].data.fd = 1;
  proc_stdio[2].flags = UV_INHERIT_FD;
  proc_stdio[2].data.fd = 2;

  if (opts & (kShellOptHideMess | kShellOptExpand)) {
    // Ignore the shell stdio(redirects to /dev/null on unixes)
    proc_stdio[0].flags = UV_IGNORE;
    proc_stdio[1].flags = UV_IGNORE;
    proc_stdio[2].flags = UV_IGNORE;
  } else {
    State = EXTERNCMD;

    if (opts & kShellOptWrite) {
      // Write from the current buffer into the process stdin
      uv_pipe_init(uv_default_loop(), &proc_stdin, 0);
      write_req.data = &pdata;
      proc_stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
      proc_stdio[0].data.stream = (uv_stream_t *)&proc_stdin;
    }

    if (opts & kShellOptRead) {
      // Read from the process stdout into the current buffer
      uv_pipe_init(uv_default_loop(), &proc_stdout, 0);
      proc_stdout.data = &pdata;
      proc_stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
      proc_stdio[1].data.stream = (uv_stream_t *)&proc_stdout;
      ga_init(&pdata.ga, 1, BUFFER_LENGTH);
    }
  }

  if (uv_spawn(uv_default_loop(), &proc, &proc_opts)) {
    // Failed, probably due to `sh` not being executable
    if (!emsg_silent) {
      MSG_PUTS(_("\nCannot execute shell "));
      msg_outtrans(p_sh);
      msg_putchar('\n');
    }

    return proc_cleanup_exit(&pdata, &proc_opts, opts);
  }

  // Assign the flag address after `proc` is initialized by `uv_spawn`
  proc.data = &pdata;

  if (opts & kShellOptWrite) {
    // Queue everything for writing to the shell stdin
    write_selection(&write_req);
    expected_exits++;
  }

  if (opts & kShellOptRead) {
    // Start the read stream for the shell stdout
    uv_read_start((uv_stream_t *)&proc_stdout, alloc_cb, read_cb);
    expected_exits++;
  }

  // Keep running the loop until all three handles are completely closed
  while (pdata.exited < expected_exits) {
    uv_run(uv_default_loop(), UV_RUN_ONCE);

    if (got_int) {
      // Forward SIGINT to the shell
      // TODO(tarruda): for now this is only needed if the terminal is in raw
      // mode, but when the UI is externalized we'll also need it, so leave it
      // here
      uv_process_kill(&proc, SIGINT);
      got_int = false;
    }
  }

  if (opts & kShellOptRead) {
    if (pdata.ga.ga_len > 0) {
      // If there's an unfinished line in the growable array, append it now.
      append_ga_line(&pdata.ga);
      // remember that the NL was missing
      curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
    } else {
      curbuf->b_no_eol_lnum = 0;
    }
    ga_clear(&pdata.ga);
  }

  if (opts & kShellOptWrite) {
    free(pdata.wbuffer);
  }

  return proc_cleanup_exit(&pdata, &proc_opts, opts);
}

static int tokenize(char_u *str, char **argv)
{
  int argc = 0, len;
  char_u *p = str;

  while (*p != NUL) {
    len = word_length(p);

    if (argv != NULL) {
      // Fill the slot
      argv[argc] = xmalloc(len + 1);
      memcpy(argv[argc], p, len);
      argv[argc][len] = NUL;
    }

    argc++;
    p += len;
    p = skipwhite(p);
  }

  return argc;
}
Пример #27
0
Файл: hd.c Проект: seppo0010/hd
void do_file(int fd) {
  int cnt;
  fd_set fset;
  char lbuf[MAX_BPL];
  char lbuf_cnt= 0;
  char *bp;

  // Text mode is sufficiently different that it is worth putting into
  // another function
  if (f_text) { do_file_text(fd); return; }
  
  pdat_mod= 0;
  addr= 0;

  if (f_real && fcntl(fd, F_SETFL, O_NONBLOCK))
    error("Can't set non-blocking input for real-time mode");

  while (0 != (cnt= read(fd, buf, buflen))) {
    if (cnt < 0) {
      if (errno != EAGAIN) error("Read error, errno==%d", errno);

      // We have to wait for more data - flush out the buffer if we
      // are in real-time mode.
      if (f_real) {
	if (lbuf_cnt == 0) 
	  out_flush();
	else {
	  // obop can only be >= op if there is already something
	  // partially displayed, in which case the partially displayed
	  // line will start at obuf anyway
	  if (obop < op) out_flush(); 
	  out_line(lbuf, lbuf_cnt); op= opp;
	  out_flush(); obop= opp;
	}
      }
	
      FD_ZERO(&fset);
      FD_SET(fd, &fset);
      if (-1 == select(fd+1, &fset, 0, &fset, 0)) error("Select failure");
      continue;
    }

    // Process tail-end of last read here
    bp= buf;
    if (lbuf_cnt > 0) {
      int len= n_byt - lbuf_cnt;
      if (len > cnt) len= cnt;
      memcpy(lbuf + lbuf_cnt, bp, len);
      bp += len; cnt -= len; lbuf_cnt += len;
      if (lbuf_cnt < n_byt) continue;
      out_line(lbuf, n_byt); addr += n_byt;
    }

    // Process bulk of read here
    while (cnt >= n_byt) {
      out_line(bp, n_byt); addr += n_byt;
      bp += n_byt; cnt -= n_byt;
    }

    // Hang onto trailing bytes for next read
    lbuf_cnt= cnt;
    if (cnt > 0)
      memcpy(lbuf, bp, cnt);
  }

  // Sort out trailing bytes
  if (lbuf_cnt > 0) {
    out_line(lbuf, lbuf_cnt); 
    addr += lbuf_cnt;
  }

  // Finish off
  if (f_addr) {
    out_line(lbuf, 1);
    op= ocl + 6; *op++= '\n';
  }
  out_flush();
}
Пример #28
0
/*
 * Either execute a command by calling the shell or start a new shell
 */
    int
mch_call_shell(
    char_u *cmd,
    int options)	    /* SHELL_, see vim.h */
{
    int		x;
    int		tmode = cur_tmode;

    out_flush();


#ifdef MCH_WRITE_DUMP
    if (fdDump)
    {
	fprintf(fdDump, "mch_call_shell(\"%s\", %d)\n", cmd, options);
	fflush(fdDump);
    }
#endif

    /*
     * Catch all deadly signals while running the external command, because a
     * CTRL-C, Ctrl-Break or illegal instruction  might otherwise kill us.
     */
    signal(SIGINT, SIG_IGN);
    signal(SIGILL, SIG_IGN);
    signal(SIGFPE, SIG_IGN);
    signal(SIGSEGV, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
    signal(SIGABRT, SIG_IGN);

    if (options & SHELL_COOKED)
	settmode(TMODE_COOK);	/* set to normal mode */

    if (cmd == NULL)
    {
	x = mch_system(p_sh, options);
    }
    else
    {
	/* we use "command" or "cmd" to start the shell; slow but easy */
	char_u *newcmd;

	newcmd = lalloc(
		STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10, TRUE);
	if (newcmd != NULL)
	{
	    if (STRNICMP(cmd, "start ", 6) == 0)
	    {
		sprintf((char *)newcmd, "%s\0", cmd+6);
		if (WinExec((LPCSTR)newcmd, SW_SHOWNORMAL) > 31)
		    x = 0;
		else
		    x = -1;
	    }
	    else
	    {
		sprintf((char *)newcmd, "%s%s %s %s",
			"",
			p_sh,
			p_shcf,
			cmd);
		x = mch_system((char *)newcmd, options);
	    }
	    vim_free(newcmd);
	}
    }

    if (tmode == TMODE_RAW)
	settmode(TMODE_RAW);	/* set to raw mode */

    if (x && !(options & SHELL_SILENT) && !emsg_silent)
    {
	smsg(_("shell returned %d"), x);
	msg_putchar('\n');
    }
#ifdef FEAT_TITLE
    resettitle();
#endif

    signal(SIGINT, SIG_DFL);
    signal(SIGILL, SIG_DFL);
    signal(SIGFPE, SIG_DFL);
    signal(SIGSEGV, SIG_DFL);
    signal(SIGTERM, SIG_DFL);
    signal(SIGABRT, SIG_DFL);


    return x;
}
Пример #29
0
static void
unbuffered(const char *arg0, int argc, char **argv)
{
  TINO_BUF	buf;

  if (!line_cont_suffix && !flag_hexdump)
    if (flag_localtime || flag_linecount || flag_utc || flag_verbose)
      line_cont_suffix = "\n";
  producer = 0;
  if (argc)
    {
      int	fds[2], redir[TINO_OPEN_MAX], fdmax, i;

      if (tino_file_pipeE(fds))
	tino_exit("cannot create pipe");

      fdmax = fd_in<3 ? 3 : fd_in+1;

      for (i=fdmax; --i>=0; )
        redir[i] = -1;				/* preserve all FDs	*/

      if (fd_in<0)
        fd_in = 1;

      redir[2] = flag_both ? fds[1] : 2;	/* catch stderr on -d, too	*/
      if (fd_in==2)
        redir[1] = redir[2];			/* swap stdin/stderr on -i2	*/
      redir[fd_in] = fds[1];			/* catch the given FD */

      /* catch the child's output for preprocessing
       */
      producer = tino_fork_execO(redir, fdmax, argv, NULL, 0, NULL);
      tino_file_closeE(fds[1]);

      fd_in = fds[0];

#if 0
      /* Following is a mess.  It is only needed for a consumer, though.
       * With a producer we see EOF on the pipe.
       * Shall be handled implicitely by a library somehow:
       */
      tino_sigset(SIGCHLD, terminate);
      terminate();	/* catch early terminated childs	*/
#endif
    }

  tino_buf_initO(&buf);
  if (producer && flag_verbose)
    {
      start_line(1, 1);
      add_prefix("start");
      for (; *argv; argv++)
	add_prefix(" '%s'", *argv);	/* XXX TODO sadly, escape is implemented in tino_io, not in tino_buf	*/
      add_prefix("\n");
      out_open();
      tino_data_putsA(&out, tino_buf_get_sN(&prefix));
    }

  if (fd_in<0)
    fd_in = 0;
  while (tino_buf_readE(&buf, fd_in, -1))
    {
      size_t		n;

      out_open();
      /* XXX TODO MISSING:
       * for flag_buffer==1 or flag_buffer==2
       * immediately write STDOUT(1),
       * but buffer STDERR(dump_line)
       */
      while ((n=tino_buf_get_lenO(&buf))>0)
	{
	  const char	*ptr;
	  size_t	k, p;

	  ptr	= tino_buf_getN(&buf);
	  p	= 0;
	  for (k=0; k<n; k++)
	    if (ptr[k]==line_terminator)
	      {
		dump_line(ptr+p, k-p, 1);
		p	= k+1;
	      }
	  /* k=n	*/
	  if (flag_buffer && p)
	    n = p;	/* do not output incomplete line	*/
	  else if ((flag_buffer>1 && n<=99999) || flag_buffer>2)
	    break;		/* buffer fragments	*/

	  /* We shall, nonblockingly, read additional input data here,
	   * if available.  Leave this to future.
	   */
	  TINO_XXX;

	  if (p<n)
	    dump_line(ptr+p, n-p, 0);
	  if (flag_cat)
	    tino_buf_advanceO(&buf, n);
	  else if (tino_buf_write_away_allE(&buf, 1, n))
	    {
	      /* silently drop out	*/
	      *tino_main_errflag	= 1;
	      break;
	    }
	  if (flag_buffer)
	    break;
	}
      out_flush();
    }
  {
      size_t		n;

      /* in case of flag_buffer: send the rest	*/
      if ((n=tino_buf_get_lenO(&buf))>0)
	{
	  const char	*ptr;

	  out_open();
	  ptr	= tino_buf_getN(&buf);
	  dump_line(ptr, n, 0);
	  if (!flag_cat && tino_buf_write_away_allE(&buf, 1, n))
	    *tino_main_errflag	= 1;
	}
  }
  if (producer)
    {
      char *cause;

#if 0
      tino_sigdummy(SIGCHLD);	/* prevent reentrance of waitpid()	*/
#endif
      /* wait for child to finish after the pipe was closed,
       * so give the child the chance to terminate.
       */
      tino_file_closeE(0);
      *tino_main_errflag	= tino_wait_child_exact(producer, &cause);
      if (flag_verbose)
	{
	  start_line(1, 1);
	  add_prefix("end %s\n", cause);
	  out_open();
	  tino_data_putsA(&out, tino_buf_get_sN(&prefix));
	}
    }
  out_close();			/* close(2)	*/
}
Пример #30
0
void make0
(
    TARGET * t,
    TARGET * p,       /* parent */
    int      depth,   /* for display purposes */
    COUNTS * counts,  /* for reporting */
    int      anyhow,
    TARGET * rescanning
)  /* forcibly touch all (real) targets */
{
    TARGETS    * c;
    TARGET     * ptime = t;
    TARGET     * located_target = 0;
    timestamp    last;
    timestamp    leaf;
    timestamp    hlast;
    int          fate;
    char const * flag = "";
    SETTINGS   * s;

#ifdef OPT_GRAPH_DEBUG_EXT
    int savedFate;
    int oldTimeStamp;
#endif

    if ( DEBUG_MAKEPROG )
        out_printf( "make\t--\t%s%s\n", spaces( depth ), object_str( t->name ) );

    /*
     * Step 1: Initialize.
     */

    if ( DEBUG_MAKEPROG )
        out_printf( "make\t--\t%s%s\n", spaces( depth ), object_str( t->name ) );

    t->fate = T_FATE_MAKING;
    t->depth = depth;

    /*
     * Step 2: Under the influence of "on target" variables, bind the target and
     * search for headers.
     */

    /* Step 2a: Set "on target" variables. */
    s = copysettings( t->settings );
    pushsettings( root_module(), s );

    /* Step 2b: Find and timestamp the target file (if it is a file). */
    if ( ( t->binding == T_BIND_UNBOUND ) && !( t->flags & T_FLAG_NOTFILE ) )
    {
        OBJECT * another_target;
        object_free( t->boundname );
        t->boundname = search( t->name, &t->time, &another_target,
            t->flags & T_FLAG_ISFILE );
        /* If it was detected that this target refers to an already existing and
         * bound target, we add a dependency so that every target depending on
         * us will depend on that other target as well.
         */
        if ( another_target )
            located_target = bindtarget( another_target );

        t->binding = timestamp_empty( &t->time )
            ? T_BIND_MISSING
            : T_BIND_EXISTS;
    }

    /* INTERNAL, NOTFILE header nodes have the time of their parents. */
    if ( p && ( t->flags & T_FLAG_INTERNAL ) )
        ptime = p;

    /* If temp file does not exist but parent does, use parent. */
    if ( p && ( t->flags & T_FLAG_TEMP ) &&
        ( t->binding == T_BIND_MISSING ) &&
        ( p->binding != T_BIND_MISSING ) )
    {
        t->binding = T_BIND_PARENTS;
        ptime = p;
    }

#ifdef OPT_SEMAPHORE
    {
        LIST * var = var_get( root_module(), constant_JAM_SEMAPHORE );
        if ( !list_empty( var ) )
        {
            TARGET * const semaphore = bindtarget( list_front( var ) );
            semaphore->progress = T_MAKE_SEMAPHORE;
            t->semaphore = semaphore;
        }
    }
#endif

    /* Step 2c: If its a file, search for headers. */
    if ( t->binding == T_BIND_EXISTS )
        headers( t );

    /* Step 2d: reset "on target" variables. */
    popsettings( root_module(), s );
    freesettings( s );

    /*
     * Pause for a little progress reporting.
     */

    if ( DEBUG_BIND )
    {
        if ( !object_equal( t->name, t->boundname ) )
            out_printf( "bind\t--\t%s%s: %s\n", spaces( depth ),
                object_str( t->name ), object_str( t->boundname ) );

        switch ( t->binding )
        {
        case T_BIND_UNBOUND:
        case T_BIND_MISSING:
        case T_BIND_PARENTS:
            out_printf( "time\t--\t%s%s: %s\n", spaces( depth ),
                object_str( t->name ), target_bind[ (int)t->binding ] );
            break;

        case T_BIND_EXISTS:
            out_printf( "time\t--\t%s%s: %s\n", spaces( depth ),
                object_str( t->name ), timestamp_str( &t->time ) );
            break;
        }
    }

    /*
     * Step 3: Recursively make0() dependencies & headers.
     */

    /* Step 3a: Recursively make0() dependencies. */
    for ( c = t->depends; c; c = c->next )
    {
        int const internal = t->flags & T_FLAG_INTERNAL;

        /* Warn about circular deps, except for includes, which include each
         * other alot.
         */
        if ( c->target->fate == T_FATE_INIT )
            make0( c->target, ptime, depth + 1, counts, anyhow, rescanning );
        else if ( c->target->fate == T_FATE_MAKING && !internal )
            out_printf( "warning: %s depends on itself\n", object_str(
                c->target->name ) );
        else if ( c->target->fate != T_FATE_MAKING && rescanning )
            make0rescan( c->target, rescanning );
        if ( rescanning && c->target->includes && c->target->includes->fate !=
            T_FATE_MAKING )
            make0rescan( target_scc( c->target->includes ), rescanning );
    }

    if ( located_target )
    {
        if ( located_target->fate == T_FATE_INIT )
            make0( located_target, ptime, depth + 1, counts, anyhow, rescanning
                );
        else if ( located_target->fate != T_FATE_MAKING && rescanning )
            make0rescan( located_target, rescanning );
    }

    /* Step 3b: Recursively make0() internal includes node. */
    if ( t->includes )
        make0( t->includes, p, depth + 1, counts, anyhow, rescanning );

    /* Step 3c: Add dependencies' includes to our direct dependencies. */
    {
        TARGETS * incs = 0;
        for ( c = t->depends; c; c = c->next )
            if ( c->target->includes )
                incs = targetentry( incs, c->target->includes );
        t->depends = targetchain( t->depends, incs );
    }

    if ( located_target )
        t->depends = targetentry( t->depends, located_target );

    /* Step 3d: Detect cycles. */
    {
        int cycle_depth = depth;
        for ( c = t->depends; c; c = c->next )
        {
            TARGET * scc_root = target_scc( c->target );
            if ( scc_root->fate == T_FATE_MAKING &&
                ( !scc_root->includes ||
                  scc_root->includes->fate != T_FATE_MAKING ) )
            {
                if ( scc_root->depth < cycle_depth )
                {
                    cycle_depth = scc_root->depth;
                    t->scc_root = scc_root;
                }
            }
        }
    }

    /*
     * Step 4: Compute time & fate.
     */

    /* Step 4a: Pick up dependencies' time and fate. */
    timestamp_clear( &last );
    timestamp_clear( &leaf );
    fate = T_FATE_STABLE;
    for ( c = t->depends; c; c = c->next )
    {
        /* If we are in a different strongly connected component, pull
         * timestamps from the root.
         */
        if ( c->target->scc_root )
        {
            TARGET * const scc_root = target_scc( c->target );
            if ( scc_root != t->scc_root )
            {
                timestamp_max( &c->target->leaf, &c->target->leaf,
                    &scc_root->leaf );
                timestamp_max( &c->target->time, &c->target->time,
                    &scc_root->time );
                c->target->fate = max( c->target->fate, scc_root->fate );
            }
        }

        /* If LEAVES has been applied, we only heed the timestamps of the leaf
         * source nodes.
         */
        timestamp_max( &leaf, &leaf, &c->target->leaf );
        if ( t->flags & T_FLAG_LEAVES )
        {
            timestamp_copy( &last, &leaf );
            continue;
        }
        timestamp_max( &last, &last, &c->target->time );
        fate = max( fate, c->target->fate );

#ifdef OPT_GRAPH_DEBUG_EXT
        if ( DEBUG_FATE )
            if ( fate < c->target->fate )
                out_printf( "fate change %s from %s to %s by dependency %s\n",
                    object_str( t->name ), target_fate[ (int)fate ],
                    target_fate[ (int)c->target->fate ], object_str(
                    c->target->name ) );
#endif
    }

    /* Step 4b: Pick up included headers time. */

    /*
     * If a header is newer than a temp source that includes it, the temp source
     * will need building.
     */
    if ( t->includes )
        timestamp_copy( &hlast, &t->includes->time );
    else
        timestamp_clear( &hlast );

    /* Step 4c: handle NOUPDATE oddity.
     *
     * If a NOUPDATE file exists, mark it as having eternally old dependencies.
     * Do not inherit our fate from our dependencies. Decide fate based only on
     * other flags and our binding (done later).
     */
    if ( t->flags & T_FLAG_NOUPDATE )
    {
#ifdef OPT_GRAPH_DEBUG_EXT
        if ( DEBUG_FATE )
            if ( fate != T_FATE_STABLE )
                out_printf( "fate change  %s back to stable, NOUPDATE.\n",
                    object_str( t->name ) );
#endif

        timestamp_clear( &last );
        timestamp_clear( &t->time );

        /* Do not inherit our fate from our dependencies. Decide fate based only
         * upon other flags and our binding (done later).
         */
        fate = T_FATE_STABLE;
    }

    /* Step 4d: Determine fate: rebuild target or what? */

    /*
        In English:
        If can not find or make child, can not make target.
        If children changed, make target.
        If target missing, make it.
        If children newer, make target.
        If temp's children newer than parent, make temp.
        If temp's headers newer than parent, make temp.
        If deliberately touched, make it.
        If up-to-date temp file present, use it.
        If target newer than non-notfile parent, mark target newer.
        Otherwise, stable!

        Note this block runs from least to most stable: as we make it further
        down the list, the target's fate gets more stable.
    */

#ifdef OPT_GRAPH_DEBUG_EXT
    savedFate = fate;
    oldTimeStamp = 0;
#endif

    if ( fate >= T_FATE_BROKEN )
    {
        fate = T_FATE_CANTMAKE;
    }
    else if ( fate >= T_FATE_SPOIL )
    {
        fate = T_FATE_UPDATE;
    }
    else if ( t->binding == T_BIND_MISSING )
    {
        fate = T_FATE_MISSING;
    }
    else if ( t->binding == T_BIND_EXISTS && timestamp_cmp( &last, &t->time ) >
        0 )
    {
#ifdef OPT_GRAPH_DEBUG_EXT
        oldTimeStamp = 1;
#endif
        fate = T_FATE_OUTDATED;
    }
    else if ( t->binding == T_BIND_PARENTS && timestamp_cmp( &last, &p->time ) >
        0 )
    {
#ifdef OPT_GRAPH_DEBUG_EXT
        oldTimeStamp = 1;
#endif
        fate = T_FATE_NEEDTMP;
    }
    else if ( t->binding == T_BIND_PARENTS && timestamp_cmp( &hlast, &p->time )
        > 0 )
    {
        fate = T_FATE_NEEDTMP;
    }
    else if ( t->flags & T_FLAG_TOUCHED )
    {
        fate = T_FATE_TOUCHED;
    }
    else if ( anyhow && !( t->flags & T_FLAG_NOUPDATE ) )
    {
        fate = T_FATE_TOUCHED;
    }
    else if ( t->binding == T_BIND_EXISTS && ( t->flags & T_FLAG_TEMP ) )
    {
        fate = T_FATE_ISTMP;
    }
    else if ( t->binding == T_BIND_EXISTS && p && p->binding != T_BIND_UNBOUND
        && timestamp_cmp( &t->time, &p->time ) > 0 )
    {
#ifdef OPT_GRAPH_DEBUG_EXT
        oldTimeStamp = 1;
#endif
        fate = T_FATE_NEWER;
    }
    else
    {
        fate = T_FATE_STABLE;
    }
#ifdef OPT_GRAPH_DEBUG_EXT
    if ( DEBUG_FATE && ( fate != savedFate ) )
	{
        if ( savedFate == T_FATE_STABLE )
            out_printf( "fate change  %s set to %s%s\n", object_str( t->name ),
                target_fate[ fate ], oldTimeStamp ? " (by timestamp)" : "" );
        else
            out_printf( "fate change  %s from %s to %s%s\n", object_str( t->name ),
                target_fate[ savedFate ], target_fate[ fate ], oldTimeStamp ?
                " (by timestamp)" : "" );
	}
#endif

    /* Step 4e: Handle missing files. */
    /* If it is missing and there are no actions to create it, boom. */
    /* If we can not make a target we do not care about it, okay. */
    /* We could insist that there are updating actions for all missing */
    /* files, but if they have dependencies we just pretend it is a NOTFILE. */

    if ( ( fate == T_FATE_MISSING ) && !t->actions && !t->depends )
    {
        if ( t->flags & T_FLAG_NOCARE )
        {
#ifdef OPT_GRAPH_DEBUG_EXT
            if ( DEBUG_FATE )
                out_printf( "fate change %s to STABLE from %s, "
                    "no actions, no dependencies and do not care\n",
                    object_str( t->name ), target_fate[ fate ] );
#endif
            fate = T_FATE_STABLE;
        }
        else
        {
            out_printf( "don't know how to make %s\n", object_str( t->name ) );
            fate = T_FATE_CANTFIND;
        }
    }

    /* Step 4f: Propagate dependencies' time & fate. */
    /* Set leaf time to be our time only if this is a leaf. */

    timestamp_max( &t->time, &t->time, &last );
    timestamp_copy( &t->leaf, timestamp_empty( &leaf ) ? &t->time : &leaf );
    /* This target's fate may have been updated by virtue of following some
     * target's rebuilds list, so only allow it to be increased to the fate we
     * have calculated. Otherwise, grab its new fate.
     */
    if ( fate > t->fate )
        t->fate = fate;
    else
        fate = t->fate;

    /*
     * Step 4g: If this target needs to be built, make0 all targets
     * that are updated by the same actions used to update this target.
     * These have already been marked as REBUILDS, and make1 has
     * special handling for them.  We just need to make sure that
     * they get make0ed.
     */
    if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) )
    {
        ACTIONS * a;
        TARGETS * c;
        for ( a = t->actions; a; a = a->next )
        {
            for ( c = a->action->targets; c; c = c->next )
            {
                if ( c->target->fate == T_FATE_INIT )
                {
                    make0( c->target, ptime, depth + 1, counts, anyhow, rescanning );
                }
            }
        }
    }

    /* Step 4h: If this target needs to be built, force rebuild everything in
     * its rebuilds list.
     */
    if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) )
        force_rebuilds( t );

    /*
     * Step 5: Sort dependencies by their update time.
     */

    if ( globs.newestfirst )
        t->depends = make0sort( t->depends );

    /*
     * Step 6: A little harmless tabulating for tracing purposes.
     */

    /* Do not count or report interal includes nodes. */
    if ( t->flags & T_FLAG_INTERNAL )
        return;

    if ( counts )
    {
#ifdef OPT_IMPROVED_PATIENCE_EXT
        ++counts->targets;
#else
        if ( !( ++counts->targets % 1000 ) && DEBUG_MAKE )
        {
            out_printf( "...patience...\n" );
            out_flush();
        }
#endif

        if ( fate == T_FATE_ISTMP )
            ++counts->temp;
        else if ( fate == T_FATE_CANTFIND )
            ++counts->cantfind;
        else if ( ( fate == T_FATE_CANTMAKE ) && t->actions )
            ++counts->cantmake;
        else if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) &&
            t->actions )
            ++counts->updating;
    }

    if ( !( t->flags & T_FLAG_NOTFILE ) && ( fate >= T_FATE_SPOIL ) )
        flag = "+";
    else if ( t->binding == T_BIND_EXISTS && p && timestamp_cmp( &t->time,
        &p->time ) > 0 )
        flag = "*";

    if ( DEBUG_MAKEPROG )
        out_printf( "made%s\t%s\t%s%s\n", flag, target_fate[ (int)t->fate ],
            spaces( depth ), object_str( t->name ) );
}