Esempio n. 1
0
static int
get_next_seq(seq_p_t sp, unsigned int offset, int warnMultiSeq)
{
  const int lenStr = 24;
  unsigned int headerLen;
  char *buf = sp->rb.line;
  int res;
  while (sp->rb.lc > 0 && buf[0] != '>')
    buf = read_line_buf(&sp->rb, sp->fd);
  if (sp->rb.lc == 0)
    return -1;
  /* We have the FASTA header.  */
  if (sp->rb.lc + lenStr + 1 > sp->maxHead) {
    sp->maxHead = sp->rb.lc + lenStr + 1;
    sp->header = (char *) xrealloc(sp->header, sp->maxHead * sizeof(char));
  }
  headerLen = sp->rb.lc;
  memcpy(sp->header, buf, (sp->rb.lc + 1) * sizeof(char));
  sp->len = 0;
  buf = read_line_buf(&sp->rb, sp->fd);
  while (sp->rb.lc > 0 && buf[0] != '>') {
    unsigned char c;
    /* Make sure we have enough room for this additional line.  */
    if (sp->len + sp->rb.lc + 1 > sp->max) {
      sp->max = max(sp->len + sp->rb.lc + 1,
		    sp->max + 0x40000);
      sp->seq = (unsigned char *)
	xrealloc(sp->seq, sp->max * sizeof(unsigned char));
    }
    while ((c = *buf++) != 0) {
      if (isupper(c)) {
	sp->seq[sp->len++] = c;
      } else if (islower(c)) {
	sp->seq[sp->len++] = toupper(c);
      }
    }
    buf = read_line_buf(&sp->rb, sp->fd);
  }
  if (warnMultiSeq && sp->rb.lc > 0)
    fprintf(stderr, "\n"
	    "***  WARNING                                           ***\n"
	    "***  there appears to be several sequences in the DNA  ***\n"
	    "***  sequence file.  Only the first one will be used,  ***\n"
	    "***  which might not be what was intended.             ***\n"
	    "\n");
  sp->seq[sp->len] = 0;
  buf = strstr(sp->header, "; LEN=");
  if (buf) {
    char *s = buf + 6;
    headerLen -= 6;
    while (isdigit(*s)) {
      s += 1;
      headerLen -= 1;
    }
    while (*s)
      *buf++ = *s++;
  }
  buf = sp->header + headerLen - 1;
  while (iscntrl(*buf) || isspace(*buf))
    buf -= 1;
  res = snprintf(buf + 1, lenStr, "; LEN=%u\n", sp->len + offset);
  if (res < 0 || res >= lenStr)
    fatal("Sequence too long: %u\n", sp->len);
  return 0;
}
Esempio n. 2
0
static void eraser(unsigned char c, struct tty_struct *tty)
{
	enum { ERASE, WERASE, KILL } kill_type;
	int head, seen_alnums, cnt;
	unsigned long flags;

	if (tty->read_head == tty->canon_head) {
		/* opost('\a', tty); */		/* what do you think? */
		return;
	}
	if (c == ERASE_CHAR(tty))
		kill_type = ERASE;
	else if (c == WERASE_CHAR(tty))
		kill_type = WERASE;
	else {
		if (!L_ECHO(tty)) {
			spin_lock_irqsave(&tty->read_lock, flags);
			tty->read_cnt -= ((tty->read_head - tty->canon_head) &
					  (N_TTY_BUF_SIZE - 1));
			tty->read_head = tty->canon_head;
			spin_unlock_irqrestore(&tty->read_lock, flags);
			return;
		}
		if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
			spin_lock_irqsave(&tty->read_lock, flags);
			tty->read_cnt -= ((tty->read_head - tty->canon_head) &
					  (N_TTY_BUF_SIZE - 1));
			tty->read_head = tty->canon_head;
			spin_unlock_irqrestore(&tty->read_lock, flags);
			finish_erasing(tty);
			echo_char(KILL_CHAR(tty), tty);
			/* Add a newline if ECHOK is on and ECHOKE is off. */
			if (L_ECHOK(tty))
				opost('\n', tty);
			return;
		}
		kill_type = KILL;
	}

	seen_alnums = 0;
	while (tty->read_head != tty->canon_head) {
		head = tty->read_head;

		/* erase a single possibly multibyte character */
		do {
			head = (head - 1) & (N_TTY_BUF_SIZE-1);
			c = tty->read_buf[head];
		} while (is_continuation(c, tty) && head != tty->canon_head);

		/* do not partially erase */
		if (is_continuation(c, tty))
			break;

		if (kill_type == WERASE) {
			/* Equivalent to BSD's ALTWERASE. */
			if (isalnum(c) || c == '_')
				seen_alnums++;
			else if (seen_alnums)
				break;
		}
		cnt = (tty->read_head - head) & (N_TTY_BUF_SIZE-1);
		spin_lock_irqsave(&tty->read_lock, flags);
		tty->read_head = head;
		tty->read_cnt -= cnt;
		spin_unlock_irqrestore(&tty->read_lock, flags);
		if (L_ECHO(tty)) {
			if (L_ECHOPRT(tty)) {
				if (!tty->erasing) {
					put_char('\\', tty);
					tty->column++;
					tty->erasing = 1;
				}
				/* if cnt > 1, output a multi-byte character */
				echo_char(c, tty);
				while (--cnt > 0) {
					head = (head+1) & (N_TTY_BUF_SIZE-1);
					put_char(tty->read_buf[head], tty);
				}
			} else if (kill_type == ERASE && !L_ECHOE(tty)) {
				echo_char(ERASE_CHAR(tty), tty);
			} else if (c == '\t') {
				unsigned int col = tty->canon_column;
				unsigned long tail = tty->canon_head;

				/* Find the column of the last char. */
				while (tail != tty->read_head) {
					c = tty->read_buf[tail];
					if (c == '\t')
						col = (col | 7) + 1;
					else if (iscntrl(c)) {
						if (L_ECHOCTL(tty))
							col += 2;
					} else if (!is_continuation(c, tty))
						col++;
					tail = (tail+1) & (N_TTY_BUF_SIZE-1);
				}

				/* should never happen */
				if (tty->column > 0x80000000)
					tty->column = 0; 

				/* Now backup to that column. */
				while (tty->column > col) {
					/* Can't use opost here. */
					put_char('\b', tty);
					if (tty->column > 0)
						tty->column--;
				}
			} else {
				if (iscntrl(c) && L_ECHOCTL(tty)) {
					put_char('\b', tty);
					put_char(' ', tty);
					put_char('\b', tty);
					if (tty->column > 0)
						tty->column--;
				}
				if (!iscntrl(c) || L_ECHOCTL(tty)) {
					put_char('\b', tty);
					put_char(' ', tty);
					put_char('\b', tty);
					if (tty->column > 0)
						tty->column--;
				}
			}
		}
		if (kill_type == ERASE)
			break;
	}
	if (tty->read_head == tty->canon_head)
		finish_erasing(tty);
}
Esempio n. 3
0
int
iscntrlTurbo (int c)
{
  return (iscntrl (c));
}
Esempio n. 4
0
/* Taking the address of a builtin with a library "fallback" must be
   allowed, either using the __builtin_xxx form or the xxx form, when
   the library fallback is declared either explicitly or implicitly
   by virtue of first calling the function.  */
void test_taking_address_of_library_builtin (int i)
{
  {
    typedef int F (int);

    /* Compute the address of libc's abs using the implicitly declared
       __builtin_abs form (all expressions are valid).  */
    F *p = __builtin_abs;
    p = &__builtin_abs;
    p = *__builtin_abs;

    /* Compute the address of libc's abs declared above.  */
    p = abs;
    p = &abs;
    p = *abs;
    (void)p;
  }

  {
    typedef __SIZE_TYPE__ size_t;
    typedef size_t F (const char*);

    /* Compute the address of libc's strlen using the implicitly
       declared __builtin_strlen form.  */
    F *p = __builtin_strlen;
    p = &__builtin_strlen;
    p = *__builtin_strlen;

    /* Compute the address of libc's strlen declared above.  */
    p = strlen;
    p = &strlen;
    p = *strlen;
    (void)p;
  }

  {
    typedef int F (int);

    /* Compute the address of libc's isxxx functions using the implicitly
       declared __builtin_xxx form.  */
    F *p = __builtin_isalnum;
    p = &__builtin_isalpha;
    p = *__builtin_iscntrl;

    /* According to C90 (see also the discussion in c/67386):
       If the expression that precedes the parenthesized argument list
       in a function call consists solely of an identifier, and if no
       declaration is visible for this identifier, the identifier is
       implicitly declared exactly as if, in the innermost block
       containing the function call, the declaration
       extern int identifier();
       appeared.  */

    /* Call the functions first to have their declarations "injected"
       into the enclosing block.  Suppress warnings.  */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
    i = isalnum (i) || isalpha (i) || iscntrl (i);
#pragma GCC diagnostic pop

    /* Take the address of the functions relying on their declarations
       having been implicitly provided by the calls above.  */
    p = isalnum;
    p = &isalpha;
    p = *iscntrl;
    (void)p;
  }
}
Esempio n. 5
0
/*********************************************************************
 *                  iscntrl   (NTDLL.@)
 */
int __cdecl NTDLL_iscntrl( int c )
{
    return iscntrl( c );
}
Esempio n. 6
0
int
run(void) {
	char buf[32];
	char c;
	FILE *f;
	int n;

	while(1) {
		read(0, &c, 1);
		memset(buf, '\0', sizeof buf);
		buf[0]=c;
		switch_top:
		switch(c) {
		case CONTROL('['):
			read(0, &c, 1);
			esc_switch_top:
			switch(c) {
				case CONTROL('['): /* ESC, need to press twice due to console limitations */
					c=CONTROL('C');
					goto switch_top;
				case '[':
					read(0, &c, 1);
					switch(c) {
						case '1': /* Home */
						case '7':
						case 'H':
							if(c!='H') read(0, &c, 1); /* Remove trailing '~' from stdin */
							c=CONTROL('A');
							goto switch_top;
						case '2': /* Insert */
							read(0, &c, 1); /* Remove trailing '~' from stdin */
							c=CONTROL('Y');
							goto switch_top;
						case '3': /* Delete */
							read(0, &c, 1); /* Remove trailing '~' from stdin */
							c=CONTROL('D');
							goto switch_top;
						case '4': /* End */
						case '8':
						case 'F':
							if(c!='F') read(0, &c, 1); /* Remove trailing '~' from stdin */
							c=CONTROL('E');
							goto switch_top;
						case '5': /* PageUp */
							read(0, &c, 1); /* Remove trailing '~' from stdin */
							c=CONTROL('V');
							goto switch_top;
						case '6': /* PageDown */
							read(0, &c, 1); /* Remove trailing '~' from stdin */
							c='v';
							goto esc_switch_top;
						case 'A': /* Up arrow */
							c=CONTROL('P');
							goto switch_top;
						case 'B': /* Down arrow */
							c=CONTROL('N');
							goto switch_top;
						case 'C': /* Right arrow */
							c=CONTROL('F');
							goto switch_top;
						case 'D': /* Left arrow */
							c=CONTROL('B');
							goto switch_top;
					}
					break;
				case 'b':
					while(cursor > 0 && text[nextrune(-1)] == ' ')
						cursor = nextrune(-1);
					while(cursor > 0 && text[nextrune(-1)] != ' ')
						cursor = nextrune(-1);
					break;
				case 'f':
					while(text[cursor] != '\0' && text[nextrune(+1)] == ' ')
						cursor = nextrune(+1);
					if(text[cursor] != '\0') do
						cursor = nextrune(+1);
					while(text[cursor] != '\0' && text[cursor] != ' ');
					break;
				case 'd':
					while(text[cursor] != '\0' && text[nextrune(+1)] == ' ') {
						cursor = nextrune(+1);
						insert(NULL, nextrune(-1) - cursor);
					}
					if(text[cursor] != '\0') do {
						cursor = nextrune(+1);
						insert(NULL, nextrune(-1) - cursor);
					} while(text[cursor] != '\0' && text[cursor] != ' ');
					break;
				case 'v':
					if(!next)
						break;
					sel=curr=next;
					calcoffsets();
					break;
				default:
					break;
			}
			break;
		case CONTROL('C'):
			return EXIT_FAILURE;
		case CONTROL('M'): /* Return */
		case CONTROL('J'):
			if(sel) strncpy(text, sel->text, sizeof text); /* Complete the input first, when hitting return */
			cursor = strlen(text);
			match(TRUE);
			drawmenu();
			/* fallthrough */
		case CONTROL(']'):
		case CONTROL('\\'): /* These are usually close enough to RET to replace Shift+RET, again due to console limitations */
			puts(text);
			return EXIT_SUCCESS;
		case CONTROL('A'):
			if(sel == matches) {
				cursor=0;
				break;
			}
			sel=curr=matches;
			calcoffsets();
			break;
		case CONTROL('E'):
			if(text[cursor] != '\0') {
				cursor = strlen(text);
				break;
			}
			if(next) {
				curr = matchend;
				calcoffsets();
				curr = prev;
				calcoffsets();
				while(next && (curr = curr->right))
					calcoffsets();
			}
			sel = matchend;
			break;
		case CONTROL('B'):
			if(cursor > 0 && (!sel || !sel->left || lines > 0)) {
				cursor = nextrune(-1);
				break;
			}
			/* fallthrough */
		case CONTROL('P'):
			if(sel && sel->left && (sel = sel->left)->right == curr) {
				curr = prev;
				calcoffsets();
			}
			break;
		case CONTROL('F'):
			if(text[cursor] != '\0') {
				cursor = nextrune(+1);
				break;
			}
			/* fallthrough */
		case CONTROL('N'):
			if(sel && sel->right && (sel = sel->right) == next) {
				curr = next;
				calcoffsets();
			}
			break;
		case CONTROL('D'):
			if(text[cursor] == '\0')
				break;
			cursor = nextrune(+1);
			/* fallthrough */
		case CONTROL('H'):
		case CONTROL('?'): /* Backspace */
			if(cursor == 0)
				break;
			insert(NULL, nextrune(-1) - cursor);
			break;
		case CONTROL('I'): /* TAB */
			if(!sel)
				break;
			strncpy(text, sel->text, sizeof text);
			cursor = strlen(text);
			match(TRUE);
			break;
		case CONTROL('K'):
			text[cursor] = '\0';
			match(FALSE);
			break;
		case CONTROL('U'):
			insert(NULL, 0 - cursor);
			break;
		case CONTROL('W'):
			while(cursor > 0 && text[nextrune(-1)] == ' ')
				insert(NULL, nextrune(-1) - cursor);
			while(cursor > 0 && text[nextrune(-1)] != ' ')
				insert(NULL, nextrune(-1) - cursor);
			break;
		case CONTROL('V'):
			if(!prev)
				break;
			sel = curr = prev;
			calcoffsets();
			break;
		case CONTROL('Y'):
			if((f=popen(XSEL, "r")) != NULL) {
				while((n= fread(&buf, 1, sizeof buf, f)) > 0) insert(buf, n);
				pclose(f);
			}
		default:
			if(!iscntrl(*buf))
				insert(buf, strlen(buf));
			break;
		}
		drawmenu();
	}
}
Esempio n. 7
0
int main(int argc, char** argv)
{
	unsigned char addr;
	unsigned char data[5];
	
	char device_name[20];
	
	int opt;
	int bus = 0;
	int n = 0;
	char mode = 'b';
	int num;
	char format = 'x';

	uint8_t array_byte[128];

	const char *fmt_byte;
	const char *fmt_short;
	const char *fmt_long;
	
	char *base_name;

	while ((opt = getopt(argc, argv, "d:f:m:r:wh")) != -1) {
		switch (opt) {
			case 'f':
				format = optarg[0];
				break;
			case 'd':
				bus = atoi(optarg);
				break;
			case 'm':
				mode = optarg[0];
				break;
			case 'r':
				n = atoi(optarg);
				break;			
			case 'h':
			default:
				base_name = basename(argv[0]);

				fprintf(stderr, "Usage: %s [-d I2CBUS] [[-r N] [-m MODE] [-f FORMAT]] ADDRESS [VAL1 VAL2 ...]\n"
						"       %s 0x20 0x00\n"
						"       %s 0x20 -r 1 -m s -f d\n"
						"  I2CBUS is an integer\n"
						"  N      is an integer the number of element to be read\n"
						"  MODE   is b|s|l   - byte|short|long\n"
						"  FORMAT is x|d|u   - hex|signed|unsigned\n",
                    			base_name, base_name, base_name);
				return -1;
		}
	}
	//fprintf(stderr, "bus=%d; mode=%c; n=%d; optind=%d\n", bus, mode, n, optind);

	if ( format == 'x' ) {
		fmt_byte = "0x%02X";
		fmt_short = "0x%04X";
		fmt_long = "0x%08lX";
	}
	else if ( format == 'd' ) {
		fmt_byte = "%d";
		fmt_short = "%d";
		fmt_long = "%ld";	
	}
	else {
		fmt_byte = "%u";
		fmt_short = "%u";
		fmt_long = "%lu";
	}

	if ( mode == 's' ) {
		n *= 2;
	}
	else if ( mode == 'l' ) {
		n *= 4;
	}
	else if ( mode == 'c' ) {
	}
	
	if ( optind >= argc ) {
        fprintf(stderr, "Expected ADDRESS\n");
        return -1;
    	}	
	addr = _atoi(argv[optind++]);
	//fprintf(stderr, "addr=0x%02X\n", addr);

	num = 0;
	for (;optind < argc; optind++) {
		if ( num >= 128 )
			break;
		array_byte[num++] = (uint8_t)_atoi(argv[optind]);
	}	
	//fprintf(stderr, "num=%d\n", num);	

	sprintf(device_name, "/dev/i2c-%u", bus);
	fd = open(device_name,O_RDWR);
	if ( fd < 0 ) {
		fprintf(stderr, "Couldn't open %s!\n", device_name);
		return -2;
	}
	
	setaddr(addr);

	if ( num ) {
		if ( write(fd, array_byte, num) < 0 ) {
			fprintf(stderr, "Unable to write!\n");
			close(fd);
			return -2;
		}
	}
	
	if ( n ) {
		int i;

		n = n < 128 ? n : 128;
		read(fd, array_byte, n);
		
		if ( mode == 'c' ) {
			for ( i = 0; i < n; i++ ) {
				char c;
				
				c = array_byte[i];
				printf("%c", iscntrl(c) ? '.' : c);
			}
		
		}
		else if ( mode == 's' ) {
			union {
				uint16_t u16;
				uint8_t arr[2];
			} w;
			
			for ( i = 0; i < n; i += 2 ) {
				w.arr[0] = array_byte[i];
				w.arr[1] = array_byte[i + 1];
				
				if ( i != 0 )
					printf(" ");

				if ( format == 'd' )
					printf(fmt_short, (int16_t)le16toh(w.u16));
				else
					printf(fmt_short, (uint16_t)le16toh(w.u16));
			}
		}
		else if ( mode == 'l' ) {
			union {
				uint32_t u32;
				uint8_t arr[4];
			} w;
			
			for ( i = 0; i < n; i += 4 ) {
				w.arr[0] = array_byte[i];
				w.arr[1] = array_byte[i + 1];
				w.arr[2] = array_byte[i + 2];
				w.arr[3] = array_byte[i + 3];
				
				if ( i != 0 )
					printf(" ");

				if ( format == 'd' )
					printf(fmt_long, (int32_t)le32toh(w.u32));
				else
					printf(fmt_long, (uint32_t)le32toh(w.u32));
			}
	
		}		
		else {
			for ( i = 0; i < n; i++ ) {				
				if ( i != 0 )
					printf(" ");

				if ( format == 'd' )
					printf(fmt_byte, (int8_t)array_byte[i]);
				else				
					printf(fmt_byte, array_byte[i]);
			}
		}
		printf("\n");
	}
	
	close(fd);
	return 0;
}
Esempio n. 8
0
int iscntrl_l(int c, locale_t l)
{
	return iscntrl(c);
}
Esempio n. 9
0
int
main(int argc, char **argv) {
    char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
    char buf[32], passwd[256], passdisp[256];
    int num, screen, width, height, update, sleepmode, term, pid;

#ifndef HAVE_BSD_AUTH
    const char *pws;
#endif
    unsigned int len;
    Bool running = True;
    Cursor invisible;
    Display *dpy;
    KeySym ksym;
    Pixmap pmap;
    Window root, w;
    XColor black, red, dummy;
    XEvent ev;
    XSetWindowAttributes wa;
    XFontStruct* font;
    GC gc;
    XGCValues values;

    // defaults
    char* passchar = "*";
    char* fontname = "-*-dejavu sans-bold-r-*-*-*-420-100-100-*-*-iso8859-1";
    char* username = "";
    int showline = 1;
    int xshift = 0;

    for (int i = 0; i < argc; i++) {
        if (!strcmp(argv[i], "-c")) {
            if (i + 1 < argc)
                passchar = argv[i + 1];
            else
                die("error: no password character given.\n");
        } else if (!strcmp(argv[i], "-f")) {
            if (i + 1 < argc)
                fontname = argv[i + 1];
            else
                die("error: font not specified.\n");
        }
        else if (!strcmp(argv[i], "-v"))
            die("sflock-"VERSION", © 2015 Ben Ruijl\n");
        else if (!strcmp(argv[i], "-h"))
            showline = 0;
        else if (!strcmp(argv[i], "-xshift"))
            xshift = atoi(argv[i + 1]);
        else if (!strcmp(argv[i], "?"))
            die("usage: sflock [-v] [-c passchars] [-f fontname] [-xshift horizontal shift]\n");
    }

    // fill with password characters
    for (int i = 0; i < sizeof passdisp; i+= strlen(passchar))
        for (int j = 0; j < strlen(passchar) && i + j < sizeof passdisp; j++)
            passdisp[i + j] = passchar[j];


    /* disable tty switching */
    if ((term = open("/dev/console", O_RDWR)) == -1) {
        perror("error opening console");
    }

    if ((ioctl(term, VT_LOCKSWITCH)) == -1) {
        perror("error locking console");
    }

    /* deamonize */
    pid = fork();
    if (pid < 0)
        die("Could not fork sflock.");
    if (pid > 0)
        exit(0); // exit parent

#ifndef HAVE_BSD_AUTH
    pws = get_password();
    username = getpwuid(geteuid())->pw_name;
#else
    username = getlogin();
#endif

    if(!(dpy = XOpenDisplay(0)))
        die("sflock: cannot open dpy\n");

    screen = DefaultScreen(dpy);
    root = RootWindow(dpy, screen);
    width = DisplayWidth(dpy, screen);
    height = DisplayHeight(dpy, screen);

    wa.override_redirect = 1;
    wa.background_pixel = XBlackPixel(dpy, screen);
    w = XCreateWindow(dpy, root, 0, 0, width, height,
                      0, DefaultDepth(dpy, screen), CopyFromParent,
                      DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel, &wa);

    XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "orange red", &red, &dummy);
    XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &dummy);
    pmap = XCreateBitmapFromData(dpy, w, curs, 8, 8);
    invisible = XCreatePixmapCursor(dpy, pmap, pmap, &black, &black, 0, 0);
    XDefineCursor(dpy, w, invisible);
    XMapRaised(dpy, w);

    font = XLoadQueryFont(dpy, fontname);

    if (font == 0) {
        die("error: could not find font. Try using a full description.\n");
    }

    gc = XCreateGC(dpy, w, (unsigned long)0, &values);
    XSetFont(dpy, gc, font->fid);
    XSetForeground(dpy, gc, XWhitePixel(dpy, screen));

    for(len = 1000; len; len--) {
        if(XGrabPointer(dpy, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
                        GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess)
            break;
        usleep(1000);
    }
    if((running = running && (len > 0))) {
        for(len = 1000; len; len--) {
            if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
                    == GrabSuccess)
                break;
            usleep(1000);
        }
        running = (len > 0);
    }

    len = 0;
    XSync(dpy, False);
    update = True;
    sleepmode = False;

    /* main event loop */
    while(running && !XNextEvent(dpy, &ev)) {
        if (sleepmode) {
            DPMSEnable(dpy);
            DPMSForceLevel(dpy, DPMSModeOff);
            XFlush(dpy);
        }

        if (update) {
            int x, y, dir, ascent, descent;
            XCharStruct overall;

            XClearWindow(dpy, w);
            XTextExtents (font, passdisp, len, &dir, &ascent, &descent, &overall);
            x = (width - overall.width) / 2;
            y = (height + ascent - descent) / 2;

            XDrawString(dpy,w,gc, (width - XTextWidth(font, username, strlen(username))) / 2 + xshift, y - ascent - 20, username, strlen(username));

            if (showline)
                XDrawLine(dpy, w, gc, width * 3 / 8 + xshift, y - ascent - 10, width * 5 / 8 + xshift, y - ascent - 10);

            XDrawString(dpy,w,gc, x + xshift, y, passdisp, len);
            update = False;
        }

        if (ev.type == MotionNotify) {
            sleepmode = False;
        }

        if(ev.type == KeyPress) {
            sleepmode = False;

            buf[0] = 0;
            num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0);
            if(IsKeypadKey(ksym)) {
                if(ksym == XK_KP_Enter)
                    ksym = XK_Return;
                else if(ksym >= XK_KP_0 && ksym <= XK_KP_9)
                    ksym = (ksym - XK_KP_0) + XK_0;
            }
            if(IsFunctionKey(ksym) || IsKeypadKey(ksym)
                    || IsMiscFunctionKey(ksym) || IsPFKey(ksym)
                    || IsPrivateKeypadKey(ksym))
                continue;

            switch(ksym) {
            case XK_Return:
                passwd[len] = 0;
#ifdef HAVE_BSD_AUTH
                running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd);
#else
                running = strcmp(crypt(passwd, pws), pws);
#endif
                if (running != 0)
                    // change background on wrong password
                    XSetWindowBackground(dpy, w, red.pixel);
                len = 0;
                break;
            case XK_Escape:
                len = 0;

                if (DPMSCapable(dpy)) {
                    sleepmode = True;
                }

                break;
            case XK_BackSpace:
                if(len)
                    --len;
                break;
            default:
                if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) {
                    memcpy(passwd + len, buf, num);
                    len += num;
                }

                break;
            }

            update = True; // show changes
        }
    }

    /* free and unlock */
    setreuid(geteuid(), 0);
    if ((ioctl(term, VT_UNLOCKSWITCH)) == -1) {
        perror("error unlocking console");
    }

    close(term);
    setuid(getuid()); // drop rights permanently


    XUngrabPointer(dpy, CurrentTime);
    XFreePixmap(dpy, pmap);
    XFreeFont(dpy, font);
    XFreeGC(dpy, gc);
    XDestroyWindow(dpy, w);
    XCloseDisplay(dpy);
    return 0;
}
Esempio n. 10
0
File: main.c Progetto: Arkq/alock
static void eventLoop(Display *display, struct aModules *modules) {

    XEvent ev;
    KeySym ks;
    char cbuf[10];
    wchar_t pass[128];
    unsigned int clen;
    unsigned int pass_pos = 0, pass_len = 0;
    unsigned long keypress_time = 0;

    /* if possible do not page this address to the swap area */
    mlock(pass, sizeof(pass));

    debug("entering event main loop");
    for (;;) {

        if (keypress_time) {
            /* check for any key press event (or root window state change) */
            if (XCheckMaskEvent(display, KeyPressMask | StructureNotifyMask, &ev) == False) {

                /* user fell asleep while typing (5 seconds inactivity) */
                if (alock_mtime() - keypress_time > 5000) {
                    modules->input->setstate(AINPUT_STATE_NONE);
                    keypress_time = 0;
                }

                /* wait a bit */
                usleep(25000);
                continue;
            }
        }
        else {

#if WITH_XBLIGHT
            /* dim out display backlight */
            if (modules->backlight != -1)
                setBacklightBrightness(0);
#endif /* WITH_XBLIGHT */

            /* block until any key press event arrives */
            XMaskEvent(display, KeyPressMask | StructureNotifyMask, &ev);

#if WITH_XBLIGHT
            /* restore original backlight brightness value */
            if (modules->backlight != -1)
                setBacklightBrightness(modules->backlight);
#endif /* WITH_XBLIGHT */
        }

        switch (ev.type) {
        case KeyPress:

            /* swallow up first key press to indicate "enter mode" */
            if (keypress_time == 0) {
                modules->input->setstate(AINPUT_STATE_INIT);
                keypress_time = alock_mtime();
                pass_pos = pass_len = 0;
                pass[0] = '\0';
                break;
            }

            keypress_time = alock_mtime();
            clen = XLookupString(&ev.xkey, cbuf, sizeof(cbuf), &ks, NULL);
            debug("key input: %lx, %d, `%.*s`", ks, clen, clen, cbuf);

            /* terminal-like key remapping */
            if (clen == 1 && iscntrl(cbuf[0]))
                switch (cbuf[0]) {
                case 0x03 /* Ctrl-C */ :
                    ks = XK_Escape;
                    break;
                case 0x08 /* Ctrl-H */ :
                    ks = XK_BackSpace;
                    break;
                case 0x0A /* Ctrl-J */ :
                case 0x0D /* Ctrl-M */ :
                    ks = XK_Return;
                    break;
                }

            /* translate key press symbol */
            ks = modules->input->keypress(ks);

            switch (ks) {
            case NoSymbol:
                break;

            /* clear/initialize input buffer */
            case XK_Escape:
            case XK_Clear:
                pass_pos = pass_len = 0;
                pass[0] = '\0';
                break;

            /* input position navigation */
            case XK_Begin:
            case XK_Home:
                pass_pos = 0;
                break;
            case XK_End:
                pass_pos = pass_len;
                break;
            case XK_Left:
                if (pass_pos > 0)
                    pass_pos--;
                break;
            case XK_Right:
                if (pass_pos < pass_len)
                    pass_pos++;
                break;

            /* remove entered characters */
            case XK_Delete:
                if (pass_pos < pass_len) {
                    wmemmove(&pass[pass_pos], &pass[pass_pos + 1], pass_len - pass_pos);
                    pass_len--;
                }
                break;
            case XK_BackSpace:
                if (pass_pos > 0) {
                    wmemmove(&pass[pass_pos - 1], &pass[pass_pos], pass_len - pass_pos + 1);
                    pass_pos--;
                    pass_len--;
                }
                break;

            /* input confirmation and authentication test */
            case XK_KP_Enter:
            case XK_Linefeed:
            case XK_Return: {

                char rbuf[sizeof(pass)];
                int rv;

                modules->input->setstate(AINPUT_STATE_CHECK);

                wcstombs(rbuf, pass, sizeof(rbuf));
                rv = modules->auth->authenticate(rbuf);

                memset(rbuf, 0, sizeof(rbuf));
                memset(pass, 0, sizeof(pass));
                pass_pos = pass_len = 0;

                if (rv == 0) { /* successful authentication */
                    modules->input->setstate(AINPUT_STATE_VALID);
                    return;
                }

                modules->input->setstate(AINPUT_STATE_ERROR);
                modules->input->setstate(AINPUT_STATE_INIT);
                keypress_time = alock_mtime();

                break;
            }

            /* input new character at the current input position */
            default:
                if (clen > 0 && !iscntrl(cbuf[0]) && pass_len < (sizeof(pass) / sizeof(*pass) - 1)) {
                    wmemmove(&pass[pass_pos + 1], &pass[pass_pos], pass_len - pass_pos + 1);
                    mbtowc(&pass[pass_pos], cbuf, clen);
                    pass_pos++;
                    pass_len++;
                }
                break;
            }

            debug("entered phrase [%zu]: `%ls`", wcslen(pass), pass);
            break;

        case ConfigureNotify:
            /* NOTE: This event should be generated for the root window upon
             *       the display reconfiguration (e.g. resolution change). */

            debug("received configure notify event");
            break;

#if 0
        case Expose:
            XClearWindow(dpy, ((XExposeEvent*)&ev)->window);
            break;
#endif

        }
    }
}
Esempio n. 11
0
int convert_to_enduse(char *string, void *data, PROPERTY *prop)
{
	enduse *e = (enduse*)data;
	char buffer[1024];
	char *token = NULL;

	/* check string length before copying to buffer */
	if (strlen(string)>sizeof(buffer)-1)
	{
		output_error("convert_to_enduse(string='%-.64s...', ...) input string is too long (max is 1023)",string);
		return 0;
	}
	strcpy(buffer,string);

	/* parse tuples separate by semicolon*/
	while ((token=strtok(token==NULL?buffer:NULL,";"))!=NULL)
	{
		/* colon separate tuple parts */
		char *param = token;
		char *value = strchr(token,':');

		/* isolate param and token and eliminte leading whitespaces */
		while (isspace(*param) || iscntrl(*param)) param++;
		if (value==NULL)
			value="1";
		else
			*value++ = '\0'; /* separate value from param */
		while (isspace(*value) || iscntrl(*value)) value++;

		// parse params
		if (strcmp(param,"current_fraction")==0)
			e->current_fraction = atof(value);
		else if (strcmp(param,"impedance_fraction")==0)
			e->impedance_fraction = atof(value);
		else if (strcmp(param,"power_fraction")==0)
			e->power_fraction = atof(value);
		else if (strcmp(param,"power_factor")==0)
			e->power_factor = atof(value);
		else if (strcmp(param,"loadshape")==0)
		{
			PROPERTY *pref = class_find_property(prop->oclass,value);
			if (pref==NULL)
			{
				output_warning("convert_to_enduse(string='%-.64s...', ...) loadshape '%s' not found in class '%s'",string,value,prop->oclass->name);
				return 0;
			}
			e->shape = (loadshape*)((char*)e - (int64)(prop->addr) + (int64)(pref->addr));
		}
		else
		{
			output_error("convert_to_enduse(string='%-.64s...', ...) parameter '%s' is not valid",string,param);
			return 0;
		}
	}

	/* reinitialize the loadshape */
	if (enduse_init((enduse*)data))
		return 0;

	/* everything converted ok */
	return 1;
}
Esempio n. 12
0
void expr_print( struct expr *e )
{
	if (!e) return;
	switch(e->kind) {
		case EXPR_ADD:
			printf("(");
			expr_print(e->left);
			printf("+");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_SUB:
			printf("(");
			expr_print(e->left);
			printf("-");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_MUL:
			printf("(");
			expr_print(e->left);
			printf("*");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_DIV:
			printf("(");
			expr_print(e->left);
			printf("/");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_POST_DECREASE:
			printf("(");
			expr_print(e->left);
			printf("--");
			printf(")");
			break;
		case EXPR_POST_INCREASE:
			printf("(");
			expr_print(e->left);
			printf("++");
			printf(")");
			break;
		case EXPR_EXPO:
			printf("(");
			expr_print(e->left);
			printf("^");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_NOT:
			printf("(");
			printf("!");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_MODULO:
			printf("(");
			expr_print(e->left);
			printf("%c",'%');
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_GE:
			printf("(");
			expr_print(e->left);
			printf(">=");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_LE:
			printf("(");
			expr_print(e->left);
			printf("<=");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_GT:
			printf("(");
			expr_print(e->left);
			printf(">");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_LT:
			printf("(");
			expr_print(e->left);
			printf("<");
			expr_print(e->right);
			printf(")");
			break;						
		case EXPR_EQ:
			printf("(");
			expr_print(e->left);
			printf("==");
			expr_print(e->right);
			printf(")");
			break;		
		case EXPR_NEQ:
			printf("(");
			expr_print(e->left);
			printf("!=");
			expr_print(e->right);
			printf(")");
			break;	
		case EXPR_AND:
			printf("(");
			expr_print(e->left);
			printf("&&");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_OR:
			printf("(");
			expr_print(e->left);
			printf("||");
			expr_print(e->right);
			printf(")");
			break;		
		case EXPR_INT_VAL:
			printf("%d", e->literal_value);
			break;
		case EXPR_NAME:
			printf("%s", e->name);
			break;
		case EXPR_STRING_VAL:
			printf("%s", e->string_literal);
			break;
		case EXPR_CHAR_VAL:
			if (iscntrl(e->literal_value)) {
				printf("\'\\");
				switch( e-> literal_value) {					
					case '\n':
						printf("n");
						break;
					case '\0':
						printf("0");
						break;
					default:
						// this should never be executed
						printf("%c", e->literal_value);
						break;
				}
				printf("\'");
			} else {
				printf("\'%c\'", e->literal_value);
			}
			break;
		case EXPR_BOOLEAN_VAL:
			if (e->literal_value) {
				printf("true");
			} else {
				printf("false");
			}
			break;
		case EXPR_ARRAY_VAL:
			printf("{");
			struct expr* vals_array = e->right;
			while(vals_array) {
				expr_print(vals_array);				
				vals_array = vals_array->next;
				if (vals_array) printf(",");
			}
			printf("}");
			break;
		case EXPR_FUNCTION_VAL:
			printf("%s(", e->name);
			struct expr *vals_func = e->right;
			while(vals_func) {
				expr_print(vals_func);
				vals_func = vals_func->next;
				if (vals_func) printf(",");
			}
			printf(")");
			break;
		case EXPR_ASSIGN:
			printf("(");
			expr_print(e->left);
			printf("=");
			expr_print(e->right);
			printf(")");
			break;
		case EXPR_ARRAY_SUB:
			printf("(");
			expr_print(e->left);
			printf("[");
			expr_print(e->right);
			printf("]");
			printf(")");
			break;
	}
}
Esempio n. 13
0
bool HHVM_FUNCTION(ctype_cntrl, CVarRef text) {
  return ctype(text, [] (int i) -> int { return iscntrl(i); });
}
Esempio n. 14
0
char*
fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags)
{
	register unsigned char*	s = (unsigned char*)as;
	register unsigned char*	e = s + n;
	register char*		b;
	register int		c;
	register int		m;
	register int		escaped;
	register int		spaced;
	register int		doublequote;
	register int		singlequote;
	int			shell;
	char*			f;
	char*			buf;

	c = 4 * (n + 1);
	if (qb)
		c += strlen((char*)qb);
	if (qe)
		c += strlen((char*)qe);
	b = buf = fmtbuf(c);
	shell = 0;
	doublequote = 0;
	singlequote = 0;
	if (qb)
	{
		if (qb[0] == '$' && qb[1] == '\'' && qb[2] == 0)
			shell = 1;
		else if ((flags & FMT_SHELL) && qb[1] == 0)
		{
			if (qb[0] == '"')
				doublequote = 1;
			else if (qb[0] == '\'')
				singlequote = 1;
		}
		while (*b = *qb++)
			b++;
	}
	else if (flags & FMT_SHELL)
		doublequote = 1;
	f = b;
	escaped = spaced = !!(flags & FMT_ALWAYS);
	while (s < e)
	{
		if ((m = mbsize(s)) > 1 && (s + m) <= e)
		{
#if _hdr_wchar && _hdr_wctype
			c = mbchar(s);
			if (!spaced && !escaped && (iswspace(c) || iswcntrl(c)))
				spaced = 1;
			s -= m;
#endif
			while (m--)
				*b++ = *s++;
		}
		else
		{
			c = *s++;
			if (!(flags & FMT_ESCAPED) && (iscntrl(c) || !isprint(c) || c == '\\'))
			{
				escaped = 1;
				*b++ = '\\';
				switch (c)
				{
				case CC_bel:
					c = 'a';
					break;
				case '\b':
					c = 'b';
					break;
				case '\f':
					c = 'f';
					break;
				case '\n':
					c = 'n';
					break;
				case '\r':
					c = 'r';
					break;
				case '\t':
					c = 't';
					break;
				case CC_vt:
					c = 'v';
					break;
				case CC_esc:
					c = 'E';
					break;
				case '\\':
					break;
				default:
					if (!(flags & FMT_WIDE) || !(c & 0200))
					{
						*b++ = '0' + ((c >> 6) & 07);
						*b++ = '0' + ((c >> 3) & 07);
						c = '0' + (c & 07);
					}
					else
						b--;
					break;
				}
			}
Esempio n. 15
0
E_TYPE gettoken(FILE *fpin, char *token)
{
	int		c;
	int		tokenpos = 0;
	int		linepos = 0;

	while ((c = fgetc(fpin)) != EOF) {
		if (isgraph(c)) {
			// visible character
			if (ispunct(c)) {
				// token delimita
				printf("[%s] 1 \n", token);

				return ID;
//				if (':' == c) {
//					printf("|%c| ':' \n", c);
//					c = getchar();
//					if (':' == c) {
//						printf("|%c| '::' \n", c);
//						// class method declare
//					}
//					else {
//						ungetc(c, stdin);
//					}
//				}
//				else {
//					printf("|%c| SYM \n", c);
//					// iroiro na kigou
//				}
			}
			else if (isalpha(c)) {
				printf("|%c| ALPHABET \n", c);
				// alpha beta
				token[tokenpos] = c;
				tokenpos++;
			}
			else if (isdigit(c)) {
				printf("|%c| NUMERIC \n", c);
				// numbers
				token[tokenpos] = c;
				tokenpos++;
			}
			else {
				printf("|%c| OTHER 1 \n", c);
			}
		}
		else if (isspace(c)) {
			// token delimita
			printf("[%s] 2 \n", token);

			return ID;
//			if (0x0a == c) {
//				printf("|%c| NL \n", c);
//				// NL
//				linepos++;
//			}
//			else {
//				printf("|%c| SPACE \n", c);
//				// other white space
//			}
		}
		else if (iscntrl(c)) {
			printf("|%c| CNTRL \n", c);
			// NULL ??
		}
		else {
			printf("|%c| OTHER 2 \n", c);
			// arienai
		}
	}
	
	return END;
}
Esempio n. 16
0
/*
 * Return the character-type bits for the given character.  There are several
 * cases.
 *
 * vile supports a 256-entry table for "character classes", which are used
 * mainly to support systems with single-byte encodings.  Some of those (no all
 * older systems) may have incorrect character types; that is the reason for
 * having the ability to change classes at runtime.
 *
 * If use_locale is TRUE, this uses the system's character type functions,
 * (wide if available) e.g., for Unicode.  However, we still allow the
 * character-classes to override.  The simple case is where the wide/narrow
 * encodings coincide (up to latin1_codes).
 *
 * A more complicated case is for narrow encodings such as ISO-8859-2, where
 * latin_codes is less than 256.  Then we have to check first if it corresponds
 * to the narrow encoding before using the system's character type functions.
 *
 * If use_locale is -TRUE (negative), then use the system's 8-bit character
 * tests to get the narrow locale information used as a starting point for the
 * character classes.  On some systems, this may give odd results, but that is
 * why it is configurable.
 *
 * If use_locale is FALSE, then use the 256-entry table of character classes.
 */
CHARTYPE
vl_ctype_bits(int ch, int use_locale GCC_UNUSED)
{
    CHARTYPE result = 0;

    if (ch < 0) {
        ;
    }
#if OPT_LOCALE
    else if (use_locale > 0) {
        int check;

        /* handle case where character-classes can be overridden */
        if (ch < latin1_codes) {
            result = vlCTYPE(ch);
            ch = -1;
        } else if (vl_ucs_to_8bit(&check, ch)) {
            result = vlCTYPE(check);
            ch = -1;
        }

        if (ch >= 0) {
            if (sys_isalpha(ch))
                result |= (vl_ident | vl_pathn | vl_qident);
            if (sys_iscntrl(ch))
                result |= (vl_cntrl);
            if (sys_isdigit(ch))
                result |= (vl_digit | vl_ident | vl_pathn | vl_qident);
            if (sys_islower(ch))
                result |= vl_lower;
            if (sys_isprint(ch) && ch != '\t')
                result |= vl_print;
            if (sys_ispunct(ch))
                result |= vl_punct;
            if (sys_isspace(ch))
                result |= vl_space;
            else
                result |= vl_nonspace;
            if (sys_isupper(ch))
                result |= vl_upper;
#ifdef vl_xdigit
            if (sys_isxdigit(ch))
                result |= vl_xdigit;
#endif
        }
    } else if (use_locale < 0) {
        if (isalpha(ch))
            result |= (vl_ident | vl_pathn | vl_qident);
        if (iscntrl(ch))
            result |= (vl_cntrl);
        if (isdigit(ch))
            result |= (vl_digit | vl_ident | vl_pathn | vl_qident);
        if (islower(ch))
            result |= vl_lower;
        if (isprint(ch) && ch != '\t')
            result |= vl_print;
        if (ispunct(ch))
            result |= vl_punct;
        if (isspace(ch))
            result |= vl_space;
        else
            result |= vl_nonspace;
        if (isupper(ch))
            result |= vl_upper;
#ifdef vl_xdigit
        if (isxdigit(ch))
            result |= vl_xdigit;
#endif
    } else
#endif /* OPT_LOCALE */
        if (ch < N_chars)
            result = vlCTYPE(ch);
    return result;
}
Esempio n. 17
0
int isprint(int c) {
    if(!iscntrl(c)) {
        return 1;
    }
    return 0;
}
Esempio n. 18
0
bool
char_class (const unsigned char c, const unsigned int flags)
{
  if (!flags)
    return false;
  if (flags & CC_ANY)
    return true;

  if ((flags & CC_NULL) && c == '\0')
    return true;

  if ((flags & CC_ALNUM) && isalnum (c))
    return true;
  if ((flags & CC_ALPHA) && isalpha (c))
    return true;
  if ((flags & CC_ASCII) && isascii (c))
    return true;
  if ((flags & CC_CNTRL) && iscntrl (c))
    return true;
  if ((flags & CC_DIGIT) && isdigit (c))
    return true;
  if ((flags & CC_PRINT) && (c >= 32 && c != 127)) /* allow ascii non-control and UTF-8, consider DEL to be a control */
    return true;
  if ((flags & CC_PUNCT) && ispunct (c))
    return true;    
  if ((flags & CC_SPACE) && isspace (c))
    return true;
  if ((flags & CC_XDIGIT) && isxdigit (c))
    return true;

  if ((flags & CC_BLANK) && (c == ' ' || c == '\t'))
    return true;
  if ((flags & CC_NEWLINE) && c == '\n')
    return true;
  if ((flags & CC_CR) && c == '\r')
    return true;

  if ((flags & CC_BACKSLASH) && c == '\\')
    return true;
  if ((flags & CC_UNDERBAR) && c == '_')
    return true;
  if ((flags & CC_DASH) && c == '-')
    return true;
  if ((flags & CC_DOT) && c == '.')
    return true;
  if ((flags & CC_COMMA) && c == ',')
    return true;
  if ((flags & CC_COLON) && c == ':')
    return true;
  if ((flags & CC_SLASH) && c == '/')
    return true;
  if ((flags & CC_SINGLE_QUOTE) && c == '\'')
    return true;
  if ((flags & CC_DOUBLE_QUOTE) && c == '\"')
    return true;
  if ((flags & CC_REVERSE_QUOTE) && c == '`')
    return true;
  if ((flags & CC_AT) && c == '@')
    return true;
  if ((flags & CC_EQUAL) && c == '=')
    return true;

  return false;
}
Esempio n. 19
0
void
keypress(XKeyEvent *ev) {
	char buf[32];
	int len;
	KeySym ksym = NoSymbol;
	Status status;

	len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
	if(status == XBufferOverflow)
		return;
	if(ev->state & ControlMask)
		switch(ksym) {
		case XK_a: ksym = XK_Home;      break;
		case XK_b: ksym = XK_Left;      break;
		case XK_c: ksym = XK_Escape;    break;
		case XK_d: ksym = XK_Delete;    break;
		case XK_e: ksym = XK_End;       break;
		case XK_f: ksym = XK_Right;     break;
		case XK_h: ksym = XK_BackSpace; break;
		case XK_i: ksym = XK_Tab;       break;
		case XK_j: ksym = XK_Return;    break;
		case XK_m: ksym = XK_Return;    break;
		case XK_n: ksym = XK_Down;      break;
		case XK_p: ksym = XK_Up;        break;

		case XK_k: /* delete right */
			text[cursor] = '\0';
			match();
			break;
		case XK_u: /* delete left */
			insert(NULL, 0 - cursor);
			break;
		case XK_w: /* delete word */
			while(cursor > 0 && text[nextrune(-1)] == ' ')
				insert(NULL, nextrune(-1) - cursor);
			while(cursor > 0 && text[nextrune(-1)] != ' ')
				insert(NULL, nextrune(-1) - cursor);
			break;
		case XK_y: /* paste selection */
			XConvertSelection(dc->dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
			                  utf8, utf8, win, CurrentTime);
			return;
		default:
			return;
		}
	else if(ev->state & Mod1Mask)
		switch(ksym) {
		case XK_g: ksym = XK_Home;  break;
		case XK_G: ksym = XK_End;   break;
		case XK_h: ksym = XK_Up;    break;
		case XK_j: ksym = XK_Next;  break;
		case XK_k: ksym = XK_Prior; break;
		case XK_l: ksym = XK_Down;  break;
		default:
			return;
		}
	switch(ksym) {
	default:
		if(!iscntrl(*buf))
			insert(buf, len);
		break;
	case XK_Delete:
		if(text[cursor] == '\0')
			return;
		cursor = nextrune(+1);
		/* fallthrough */
	case XK_BackSpace:
		if(cursor == 0)
			return;
		insert(NULL, nextrune(-1) - cursor);
		break;
	case XK_End:
		if(text[cursor] != '\0') {
			cursor = strlen(text);
			break;
		}
		if(next) {
			/* jump to end of list and position items in reverse */
			curr = matchend;
			calcoffsets();
			curr = prev;
			calcoffsets();
			while(next && (curr = curr->right))
				calcoffsets();
		}
		sel = matchend;
		break;
	case XK_Escape:
		ret = EXIT_FAILURE;
		running = False;
	case XK_Home:
		if(sel == matches) {
			cursor = 0;
			break;
		}
		sel = curr = matches;
		calcoffsets();
		break;
	case XK_Left:
		if(cursor > 0 && (!sel || !sel->left || lines > 0)) {
			cursor = nextrune(-1);
			break;
		}
		if(lines > 0)
			return;
		/* fallthrough */
	case XK_Up:
		if(sel && sel->left && (sel = sel->left)->right == curr) {
			curr = prev;
			calcoffsets();
		}
		break;
	case XK_Next:
		if(!next)
			return;
		sel = curr = next;
		calcoffsets();
		break;
	case XK_Prior:
		if(!prev)
			return;
		sel = curr = prev;
		calcoffsets();
		break;
	case XK_Return:
	case XK_KP_Enter:
		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
		writehistory( (sel == NULL) ? text : sel->text);
		ret = EXIT_SUCCESS;
		running = False;
	case XK_Right:
		if(text[cursor] != '\0') {
			cursor = nextrune(+1);
			break;
		}
		if(lines > 0)
			return;
		/* fallthrough */
	case XK_Down:
		if(sel && sel->right && (sel = sel->right) == next) {
			curr = next;
			calcoffsets();
		}
		break;
	case XK_Tab:
		if(!sel)
			return;
		strncpy(text, sel->text, sizeof text);
		cursor = strlen(text);
		match();
		break;
	}
	drawmenu();
}
Esempio n. 20
0
void
describe_char(int c)
{
	unsigned char cp = c,
				up = toupper(c),
				lo = tolower(c);

	if (!isprint(cp))
		cp = ' ';
	if (!isprint(up))
		up = ' ';
	if (!isprint(lo))
		lo = ' ';

	printf("chr#%-4d%2c%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%4c%4c\n", c, cp, flag(isalnum(c)), flag(isalpha(c)), flag(iscntrl(c)), flag(isdigit(c)), flag(islower(c)), flag(isgraph(c)), flag(isprint(c)), flag(ispunct(c)), flag(isspace(c)), flag(isupper(c)), flag(isxdigit(c)), lo, up);
}
Esempio n. 21
0
// ----- predicate

defmethod(OBJ, gisAlnum, Char)
  retmethod(isalnum(self->Int.value) ? True : False);
endmethod

defmethod(OBJ, gisAlpha, Char)
  retmethod(isalpha(self->Int.value) ? True : False);
endmethod

defmethod(OBJ, gisBlank, Char)
  retmethod(isblank(self->Int.value) ? True : False);
endmethod

defmethod(OBJ, gisCntrl, Char)
  retmethod(iscntrl(self->Int.value) ? True : False);
endmethod

defmethod(OBJ, gisDigit, Char)
  retmethod(isdigit(self->Int.value) ? True : False);
endmethod

defmethod(OBJ, gisGraph, Char)
  retmethod(isgraph(self->Int.value) ? True : False);
endmethod

defmethod(OBJ, gisLower, Char)
  retmethod(islower(self->Int.value) ? True : False);
endmethod

defmethod(OBJ, gisPrint, Char)
Esempio n. 22
0
int (iscntrl)(int c)
{
  return iscntrl(c);
}
Esempio n. 23
0
void
makemsg(char *fname)
{
	int cnt;
	unsigned char ch;
	struct tm *lt;
	struct passwd *pw;
	struct stat sbuf;
	time_t now;
	FILE *fp;
	int fd;
	char *p, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64];
	const char *tty;
	const char *whom;
	gid_t egid;

	(void)snprintf(tmpname, sizeof(tmpname), "%s/wall.XXXXXX", _PATH_TMP);
	if ((fd = mkstemp(tmpname)) == -1 || !(fp = fdopen(fd, "r+")))
		err(1, "can't open temporary file");
	(void)unlink(tmpname);

	if (!nobanner) {
		tty = ttyname(STDERR_FILENO);
		if (tty == NULL)
			tty = "no tty";

		if (!(whom = getlogin()))
			whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
		(void)gethostname(hostname, sizeof(hostname));
		(void)time(&now);
		lt = localtime(&now);

		/*
		 * all this stuff is to blank out a square for the message;
		 * we wrap message lines at column 79, not 80, because some
		 * terminals wrap after 79, some do not, and we can't tell.
		 * Which means that we may leave a non-blank character
		 * in column 80, but that can't be helped.
		 */
		(void)fprintf(fp, "\r%79s\r\n", " ");
		(void)snprintf(lbuf, sizeof(lbuf), 
		    "Broadcast Message from %s@%s",
		    whom, hostname);
		(void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
		(void)snprintf(lbuf, sizeof(lbuf),
		    "        (%s) at %d:%02d %s...", tty,
		    lt->tm_hour, lt->tm_min, lt->tm_zone);
		(void)fprintf(fp, "%-79.79s\r\n", lbuf);
	}
	(void)fprintf(fp, "%79s\r\n", " ");

	if (fname) {
		egid = getegid();
		setegid(getgid());
	       	if (freopen(fname, "r", stdin) == NULL)
			err(1, "can't read %s", fname);
		setegid(egid);
	}
	cnt = 0;
	while (fgets(lbuf, sizeof(lbuf), stdin)) {
		for (p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
			if (ch == '\r') {
				putc('\r', fp);
				cnt = 0;
				continue;
			} else if (ch == '\n') {
				for (; cnt < 79; ++cnt)
					putc(' ', fp);
				putc('\r', fp);
				putc('\n', fp);
				break;
			}
			if (cnt == 79) {
				putc('\r', fp);
				putc('\n', fp);
				cnt = 0;
			}
			if (((ch & 0x80) && ch < 0xA0) ||
				   /* disable upper controls */
				   (!isprint(ch) && !isspace(ch) &&
				    ch != '\a' && ch != '\b')
				  ) {
				if (ch & 0x80) {
					ch &= 0x7F;
					putc('M', fp);
					if (++cnt == 79) {
						putc('\r', fp);
						putc('\n', fp);
						cnt = 0;
					}
					putc('-', fp);
					if (++cnt == 79) {
						putc('\r', fp);
						putc('\n', fp);
						cnt = 0;
					}
				}
				if (iscntrl(ch)) {
					ch ^= 040;
					putc('^', fp);
					if (++cnt == 79) {
						putc('\r', fp);
						putc('\n', fp);
						cnt = 0;
					}
				}
			}
			putc(ch, fp);
		}
	}
	(void)fprintf(fp, "%79s\r\n", " ");
	rewind(fp);

	if (fstat(fd, &sbuf))
		err(1, "can't stat temporary file");
	mbufsize = sbuf.st_size;
	if (!(mbuf = malloc((u_int)mbufsize)))
		err(1, "out of memory");
	if ((int)fread(mbuf, sizeof(*mbuf), mbufsize, fp) != mbufsize)
		err(1, "can't read temporary file");
	(void)close(fd);
}
Esempio n. 24
0
// Scan dismantels the given string <buf> into its components.
// The components are divided either by <,> or <">
// the results are saved in arg
int Scan(char *line, char *buf, ULONG *arg)
{
	int i = 0, argi, len;
	char *end, *pos;
	pos = line;
	strcpy(buf, "");
	if (!pos)
		return 0;

	argi = 0;

	while (pos[i] && (iscntrl(pos[i]) || pos[i] == ' '))	// ignore spaces
		i++;
	if (!pos[i] || pos[i] == '\n' || (pos[i] == '/' && pos[i + 1] == '/'))	
		return 1;								// return if empty line or comment

	// read as long as there are arguments
	while (!(!pos[i] || pos[i] == '\n' || (pos[i] == '/' && pos[i + 1] == '/')))
	{
		while (pos[i] && (iscntrl(pos[i]) || pos[i] == ' '))	// ignore spaces
			i++;

		if (pos[i] == ',' && argi > 0)
		{
			i++;
			while (pos[i] && (iscntrl(pos[i]) || pos[i] == ' '))	// ignore spaces
				i++;
		}
		
		if (pos[i] == '<')
			end = strpbrk(&pos[i+1], ">\n") + 1;
		else
			if (pos[i] == '"')
				end = strpbrk(&pos[++i], "\"\n") + 1;
			else
		    	end = strpbrk(&pos[i], ", \"\n");

		if (end)
			len = int(end - &pos[i]);
		else
			len = strlen(&pos[i]);

		if (argi == 0)
		{
			strncpy(buf, &pos[i], len);
			buf[len] = '\0';
		}
		else
		{
			if (len > 0)
			{
				arg[argi - 1] = (ULONG)(new char[len + 1]);
				strncpy((char *)arg[argi - 1], &pos[i], len);
				((char *)(arg[argi - 1]))[len] = 0;
				if (pos[i + len - 1] == '"')
					((char *)(arg[argi - 1]))[len - 1] = 0;  // that's SOOO dirty!!!
			}
		}
		i+= len;
		argi++;
	}
	return 0;
}
Esempio n. 25
0
int
iswcntrl(wint_t c)
{
  return iscntrl((int)c);
}
Esempio n. 26
0
// state machine based lexer
// tokens are recorded in 'tokens', ended by a NONE token
bool lex( char * line, const bool mode ) {
	char * start = NULL, *end = NULL, *s = line ;
	char term[ 256 ], *pterm = NULL ;
	LexState state = lsInit ;

	// state machine
	for ( ptok = tokens ; ptok < &tokens[ 256 ] ; ) {
		switch ( state ) {
		case lsInit :
			ptok->type = tNONE ;
			ptok->subtype = stNONE ;
			ptok->value = 0 ;
			ptok->text = NULL ;

			pterm = term ;
			*pterm = '\0' ;
			state = lsIdle ;
			break ;

		case lsIdle :
			// starting characters of tokens to be
			if ( *s == '\0' || *s == '\r' || *s == '\n' ) {
				// end of line
				return true ;
			} else if ( *s == ' ' || iscntrl( *s ) ) {
				// white space, 'space' and all control characters, except \0, \r and \n
				s++ ;
			} else if ( mode && ( isalnum( *s ) || *s == '_'  ) ) {
				// KCPSM mode, all alphanum is accepted for idents, could be hex values
				// ident
				start = s++ ;
				state = lsIdent ;
			} else if ( !mode && ( isalpha( *s ) || *s == '_' ) ) {
				// ident
				start = s++ ;
				state = lsIdent ;
			} else if ( *s == ';' ) {
				// comment
				start = s++ ;
				state = lsComment ;
			} else if ( *s == '0' ) {
				// maybe hex or bin
				start = s++ ;
				state = lsHexBin ;
			} else if ( isdigit( *s ) ) {
				// decimal number
				start = s++ ;
				state = lsDec ;
			} else if ( *s == '$' ) {
				// hexadecimal number
				start = ++s ;
				state = lsHex ;
			} else if ( *s == '%' ) {
				// binary number
				start = ++s ;
				state = lsBin ;
			} else if ( *s == '.' ) {
				// directives, indexing, local labels, etc
				start = s++ ;
				state = lsIndex ;
			} else if ( *s == ':' || *s == ',' || *s == '(' || *s == ')' ) {
				// punctuation ',', ':', '(', ')', '~'
				start = s++ ;
				state = lsPunct ;
			} else if ( *s == '*' || *s == '/' || *s == '#' || *s == '+' || *s == '-' ||
					*s == '|' || *s == '&' || *s == '^' || *s == '~' ) {
				// operators
				start = s++ ;
				state = lsOperator ;
			} else if ( *s == '<' || *s == '>' ) {
				// double char operators
				start = s++ ;
				state = lsDoubleOp ;
			} else if ( *s == '\'' ) {
				// 'c'
				start = ++s ;
				state = lsChar ;
			} else if ( *s == '"' ) {
				// "string"
				start = ++s ;
				state = lsString ;
			} else
				state = lsError ;
			break ;

		case lsComment :
			if ( *s != '\0' && *s != '\r' && *s != '\n' )
				// anything till end of line
				s++ ;
			else {
				end = s ;
				ptok->type = tNONE ;
				ptok->subtype = stCOMMENT ;
				state = lsCopy ;
			}
			break ;

		case lsChar :
			if ( *s == '\'' ) {
				ptok->type = tCHAR ;
				end = s++ ;
				state = lsCopy ;
			} else if ( *s == '\\' ) {
				s += 1 ;
				if ( *s != '\0' )
					s += 1 ;
			} else if ( isgraph( *s ) || *s == ' ' ) {
				s++ ;
			} else
				state = lsError ;
			break ;

		case lsString :
			if ( *s == '"' ) {
				ptok->type = tSTRING ;
				end = s++ ;
				state = lsCopy ;
			} else if ( *s == '\\' ) {
				s += 1 ;
				if ( *s != '\0' )
					s += 1 ;
			} else if ( isgraph( *s ) || *s == ' ' )
				s++ ;
			else
				state = lsError ;
			break ;

		case lsIdent :
			if ( isalnum( *s ) || *s == '_' )
				s++ ;
			else {
				end = s ;
				ptok->type = tIDENT ;
				ptok->subtype = stNONE ;
				state = lsCopy ;
			}
			break ;

		case lsHexBin :
			if ( *s == 'x' ) {
				start = ++s ;
				state = lsHex ;
			} else if ( *s == 'b' ) {
				start = ++s ;
				state = lsBin ;
			} else
				// missing the first '0' doesn't hurt here
				state = lsDec ;
			break ;

		case lsHex :
			if ( isxdigit( *s ) )
				s++ ;
			else {
				end = s ;
				ptok->type = tHEX ;
				state = lsCopy ;
			}
			break ;

		case lsBin :
			if ( *s == '0' || *s == '1' )
				s++ ;
			else {
				end = s ;
				ptok->type = tBIN ;
				state = lsCopy ;
			}
			break ;

		case lsDec :
			if ( isdigit( *s ) )
				s++ ;
			else {
				end = s ;
				ptok->type = tDEC ;
				state = lsCopy ;
			}
			break ;

		case lsOperator :
			ptok->type = tOPERATOR ;
			switch ( *start ) {
			case '*' :
				ptok->subtype = stMUL ;
				break ;
			case '/' :
				ptok->subtype = stDIV ;
				break ;
			case '#' :
				ptok->subtype = stMOD ;
				break ;
			case '+' :
				ptok->subtype = stADD ;
				break ;
			case '-' :
				ptok->subtype = stSUB ;
				break ;
			case '|' :
				ptok->subtype = stIOR ;
				break ;
			case '&' :
				ptok->subtype = stAND ;
				break ;
			case '^' :
				ptok->subtype = stXOR ;
				break ;
			case '~' :
				ptok->subtype = stTILDA ;
				break ;
			}
			end = s ;
			state = lsCopy ;
			break ;

		case lsDoubleOp :
			if ( *start == *s ) { // << or >>
				ptok->type = tOPERATOR ;
				switch ( *start ) {
				case '<' :
					ptok->subtype = stSHL ;
					break ;
				case '>' :
					ptok->subtype = stSHR ;
					break ;
				}
				end = ++s ;
				state = lsCopy ;
			} else
				state = lsError ;
			break ;

		case lsPunct :
			end = s ;
			state = lsCopy ;
			switch ( *start ) {
			case ':' :
				ptok->type = tCOLON ;
				break ;
			case '(' :
				ptok->type = tLPAREN ;
				break ;
			case ')' :
				ptok->type = tRPAREN ;
				break ;
			case ',' :
				ptok->type = tCOMMA ;
				break ;
			default :
				state = lsError ;
			}
			break ;

		case lsIndex :
			// any of .IX, .IX++, .--IX, .-IX+
			if ( isalnum( *s ) || *s == '-' || *s == '+' )
				s++ ;
			else {
				end = s ;
				ptok->type = tIDENT ;
				ptok->subtype = stDOT ;
				state = lsCopy ;
			}
			break ;

			// final token collector
		case lsCopy :
			while ( start < end )
				*pterm++ = *start++ ;
			*pterm = '\0' ;
			ptok->text = strdup( term ) ;
			ptok++ ;
			state = lsInit ;
			break ;

			// any errors
		case lsError :
			*pterm = '\0' ;
			ptok->type = tERROR ;
			return false ;
		}
	}
	return false ;
}
Esempio n. 27
0
File: llex.c Progetto: 0w/moai-dev
const char *luaX_token2str (LexState *ls, int token) {
  if (token < FIRST_RESERVED) {
    lua_assert(token == cast(unsigned char, token));
    return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
                              luaO_pushfstring(ls->L, "%c", token);
  }
Esempio n. 28
0
/* This function builds a set of character tables for use by PCRE2 and returns
a pointer to them. They are build using the ctype functions, and consequently
their contents will depend upon the current locale setting. When compiled as
part of the library, the store is obtained via a general context malloc, if
supplied, but when DFTABLES is defined (when compiling the dftables auxiliary
program) malloc() is used, and the function has a different name so as not to
clash with the prototype in pcre2.h.

Arguments:   none when DFTABLES is defined
             else a PCRE2 general context or NULL
Returns:     pointer to the contiguous block of data
*/

#ifdef DFTABLES  /* Included in freestanding dftables.c program */
static const uint8_t *maketables(void)
{
uint8_t *yield = (uint8_t *)malloc(tables_length);

#else  /* Not DFTABLES, compiling the library */
PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION
pcre2_maketables(pcre2_general_context *gcontext)
{
uint8_t *yield = (uint8_t *)((gcontext != NULL)?
  gcontext->memctl.malloc(tables_length, gcontext->memctl.memory_data) :
  malloc(tables_length));
#endif  /* DFTABLES */

int i;
uint8_t *p;

if (yield == NULL) return NULL;
p = yield;

/* First comes the lower casing table */

for (i = 0; i < 256; i++) *p++ = tolower(i);

/* Next the case-flipping table */

for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);

/* Then the character class tables. Don't try to be clever and save effort on
exclusive ones - in some locales things may be different.

Note that the table for "space" includes everything "isspace" gives, including
VT in the default locale. This makes it work for the POSIX class [:space:].
From release 8.34 is is also correct for Perl space, because Perl added VT at
release 5.18.

Note also that it is possible for a character to be alnum or alpha without
being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the
fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must
test for alnum specially. */

memset(p, 0, cbit_length);
for (i = 0; i < 256; i++)
  {
  if (isdigit(i)) p[cbit_digit  + i/8] |= 1 << (i&7);
  if (isupper(i)) p[cbit_upper  + i/8] |= 1 << (i&7);
  if (islower(i)) p[cbit_lower  + i/8] |= 1 << (i&7);
  if (isalnum(i)) p[cbit_word   + i/8] |= 1 << (i&7);
  if (i == '_')   p[cbit_word   + i/8] |= 1 << (i&7);
  if (isspace(i)) p[cbit_space  + i/8] |= 1 << (i&7);
  if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7);
  if (isgraph(i)) p[cbit_graph  + i/8] |= 1 << (i&7);
  if (isprint(i)) p[cbit_print  + i/8] |= 1 << (i&7);
  if (ispunct(i)) p[cbit_punct  + i/8] |= 1 << (i&7);
  if (iscntrl(i)) p[cbit_cntrl  + i/8] |= 1 << (i&7);
  }
p += cbit_length;

/* Finally, the character type table. In this, we used to exclude VT from the
white space chars, because Perl didn't recognize it as such for \s and for
comments within regexes. However, Perl changed at release 5.18, so PCRE changed
at release 8.34. */

for (i = 0; i < 256; i++)
  {
  int x = 0;
  if (isspace(i)) x += ctype_space;
  if (isalpha(i)) x += ctype_letter;
  if (isdigit(i)) x += ctype_digit;
  if (isxdigit(i)) x += ctype_xdigit;
  if (isalnum(i) || i == '_') x += ctype_word;

  /* Note: strchr includes the terminating zero in the characters it considers.
  In this instance, that is ok because we want binary zero to be flagged as a
  meta-character, which in this sense is any character that terminates a run
  of data characters. */

  if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta;
  *p++ = x;
  }

return yield;
}
Esempio n. 29
0
File: cat.c Progetto: Henauxg/minix
void
cook_buf(FILE *fp)
{
	int ch, gobble, line, prev;

	line = gobble = 0;
	for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
		if (prev == '\n') {
			if (ch == '\n') {
				if (sflag) {
					if (!gobble && nflag && !bflag)
						(void)fprintf(stdout,
							"%6d\t\n", ++line);
					else if (!gobble && putchar(ch) == EOF)
						break;
					gobble = 1;
					continue;
				}
				if (nflag) {
					if (!bflag) {
						(void)fprintf(stdout,
						    "%6d\t", ++line);
						if (ferror(stdout))
							break;
					} else if (eflag) {
						(void)fprintf(stdout,
						    "%6s\t", "");
						if (ferror(stdout))
							break;
					}
				}
			} else if (nflag) {
				(void)fprintf(stdout, "%6d\t", ++line);
				if (ferror(stdout))
					break;
			}
		}
		gobble = 0;
		if (ch == '\n') {
			if (eflag)
				if (putchar('$') == EOF)
					break;
		} else if (ch == '\t') {
			if (tflag) {
				if (putchar('^') == EOF || putchar('I') == EOF)
					break;
				continue;
			}
		} else if (vflag) {
			if (!isascii(ch)) {
				if (putchar('M') == EOF || putchar('-') == EOF)
					break;
				ch = toascii(ch);
			}
			if (iscntrl(ch)) {
				if (putchar('^') == EOF ||
				    putchar(ch == '\177' ? '?' :
				    ch | 0100) == EOF)
					break;
				continue;
			}
		}
		if (putchar(ch) == EOF)
			break;
	}
	if (ferror(fp)) {
		warn("%s", filename);
		rval = EXIT_FAILURE;
		clearerr(fp);
	}
	if (ferror(stdout))
		err(EXIT_FAILURE, "stdout");
}
Esempio n. 30
0
/*
 *	'Wait for' this string to appear on this file descriptor.
 */
int
get_string(char *string)
{
    char temp[STR_LEN];
    int c, printed = 0;
    size_t len, minlen;
    char *s = temp, *end = s + STR_LEN;
    char *logged = temp;

    fail_reason = (char *)0;

    if (strlen(string) > STR_LEN) {
	chat_logf("expect string is too long");
	exit_code = 1;
	return 0;
    }

    string = clean(string, 0);
    len = strlen(string);
    minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1;

    if (verbose)
	chat_logf("expect (%v)", string);

    if (len == 0) {
	if (verbose)
	    chat_logf("got it");
	return (1);
    }

    alarm(timeout);
    alarmed = 0;

    while ( ! alarmed && (c = get_char()) >= 0) {
	int n, abort_len, report_len;

	if (echo)
	    echo_stderr(c);
	if (verbose && c == '\n') {
	    if (s == logged)
		chat_logf("");	/* blank line */
	    else
		chat_logf("%0.*v", s - logged, logged);
	    logged = s + 1;
	}

	*s++ = c;

	if (verbose && s >= logged + 80) {
	    chat_logf("%0.*v", s - logged, logged);
	    logged = s;
	}

	if (Verbose) {
	   if (c == '\n')
	       fputc( '\n', stderr );
	   else if (c != '\r')
	       fprintf( stderr, "%s", character(c) );
	}

	if (!report_gathering) {
	    for (n = 0; n < n_reports; ++n) {
		if ((report_string[n] != (char*) NULL) &&
		    s - temp >= (report_len = strlen(report_string[n])) &&
		    strncmp(s - report_len, report_string[n], report_len) == 0) {
		    time_t time_now   = time ((time_t*) NULL);
		    struct tm* tm_now = localtime (&time_now);

		    strftime (report_buffer, 20, "%b %d %H:%M:%S ", tm_now);
		    strcat (report_buffer, report_string[n]);

		    report_string[n] = (char *) NULL;
		    report_gathering = 1;
		    break;
		}
	    }
	}
	else {
	    if (!iscntrl (c)) {
		int rep_len = strlen (report_buffer);
		report_buffer[rep_len]     = c;
		report_buffer[rep_len + 1] = '\0';
	    }
	    else {
		report_gathering = 0;
		fprintf (report_fp, "chat:  %s\n", report_buffer);
	    }
	}

	if ((size_t)(s - temp) >= len &&
	    c == string[len - 1] &&
	    strncmp(s - len, string, len) == 0) {
	    if (verbose) {
		if (s > logged)
		    chat_logf("%0.*v", s - logged, logged);
		chat_logf(" -- got it\n");
	    }

	    alarm(0);
	    alarmed = 0;
	    return (1);
	}

	for (n = 0; n < n_aborts; ++n) {
	    if (s - temp >= (abort_len = strlen(abort_string[n])) &&
		strncmp(s - abort_len, abort_string[n], abort_len) == 0) {
		if (verbose) {
		    if (s > logged)
			chat_logf("%0.*v", s - logged, logged);
		    chat_logf(" -- failed");
		}

		alarm(0);
		alarmed = 0;
		exit_code = n + 4;
		strcpy(fail_reason = fail_buffer, abort_string[n]);
		return (0);
	    }
	}

	if (s >= end) {
	    if (logged < s - minlen) {
		chat_logf("%0.*v", s - logged, logged);
		logged = s;
	    }
	    s -= minlen;
	    memmove(temp, s, minlen);
	    logged = temp + (logged - s);
	    s = temp + minlen;
	}

	if (alarmed && verbose)
	    chat_logf("warning: alarm synchronization problem");
    }

    alarm(0);
    
    if (verbose && printed) {
	if (alarmed)
	    chat_logf(" -- read timed out");
	else
	    chat_logf(" -- read failed: %m");
    }

    exit_code = 3;
    alarmed   = 0;
    return (0);
}