Beispiel #1
0
int
main(
	int	argc,
	char	**argv)
{
	int	c, i, done = 0;
	char	*input;
	char	**v;

	pushfile(stdin);
	init(argc, argv);

	for (i = 0; !done && i < ncmdline; i++) {
		v = breakline(cmdline[i], &c);
		if (c)
			done = command(c, v);
		xfree(v);
	}
	if (cmdline) {
		xfree(cmdline);
		return exitcode;
	}

	while (!done) {
		if ((input = fetchline()) == NULL)
			break;
		v = breakline(input, &c);
		if (c)
			done = command(c, v);
		doneline(input, v);
	}
	return exitcode;
}
Beispiel #2
0
void
command_loop(void)
{
	int		c, i, j = 0, done = 0;
	char		*input;
	char		**v;
	const cmdinfo_t	*ct;

	for (i = 0; !done && i < ncmdline; i++) {
		input = strdup(cmdline[i]);
		if (!input) {
			fprintf(stderr,
				_("cannot strdup command '%s': %s\n"),
				cmdline[i], strerror(errno));
			exit(1);
		}
		v = breakline(input, &c);
		if (c) {
			ct = find_command(v[0]);
			if (ct) {
				if (ct->flags & CMD_FLAG_GLOBAL)
					done = command(ct, c, v);
				else {
					j = 0;
					while (!done && (j = args_command(j)))
						done = command(ct, c, v);
				}
			} else
				fprintf(stderr, _("command \"%s\" not found\n"),
					v[0]);
		}
		doneline(input, v);
	}
	if (cmdline) {
		free(cmdline);
		return;
	}
	while (!done) {
		if ((input = fetchline()) == NULL)
			break;
		v = breakline(input, &c);
		if (c) {
			ct = find_command(v[0]);
			if (ct)
				done = command(ct, c, v);
			else
				fprintf(stderr, _("command \"%s\" not found\n"),
					v[0]);
		}
		doneline(input, v);
	}
}
Beispiel #3
0
main()
{
    int len;
//  extern int max;
//	extern char longest[];

    max=0;
    while((len=fetchline())  > 1)
        if (len>max) {
            max=len;
            copy();
        }
    printf("%s",longest);
    return 0;
}
Beispiel #4
0
main() /* find longest line */
{
    int len; /* current line length */
    int max; /* max length so far */
    char line[MAXLINE]; /* current input line */
    char save[MAXLINE]; /* longest line saved */

    max = 0;
    while ((len = fetchline(line, MAXLINE)) > 0)
        if (len > max) {
            max = len;
            copy(line, save);
        }
    if ((max == (MAXLINE - 1)) && (line[MAXLINE - 1] == '\0'))
        printf("max input line size exceeded\n");
    else if (max > 0) /* there was a line */
        printf("%s", save);
}
Beispiel #5
0
static void command_loop(void)
{
    int i, done = 0, fetchable = 0, prompted = 0;
    char *input;

    for (i = 0; !done && i < ncmdline; i++) {
        done = qemuio_command(qemuio_bs, cmdline[i]);
    }
    if (cmdline) {
        g_free(cmdline);
        return;
    }

    while (!done) {
        if (!prompted) {
            printf("%s", get_prompt());
            fflush(stdout);
            qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
            prompted = 1;
        }

        main_loop_wait(false);

        if (!fetchable) {
            continue;
        }

        input = fetchline();
        if (input == NULL) {
            break;
        }
        done = qemuio_command(qemuio_bs, input);
        g_free(input);

        prompted = 0;
        fetchable = 0;
    }
    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
}
/*  Converts a PEM encoded file into its binary form
 *
 *  RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
 *  RFC 934 Message Encapsulation, January 1985
 */
err_t pem_to_bin(chunk_t *blob, chunk_t *passphrase, bool *pgp)
{
	typedef enum {
		PEM_PRE    = 0,
		PEM_MSG    = 1,
		PEM_HEADER = 2,
		PEM_BODY   = 3,
		PEM_POST   = 4,
		PEM_ABORT  = 5
	} state_t;

	encryption_algorithm_t alg = ENCR_UNDEFINED;
	size_t key_size = 0;

	bool encrypted = FALSE;

	state_t state  = PEM_PRE;

	chunk_t src    = *blob;
	chunk_t dst    = *blob;
	chunk_t line   = CHUNK_INITIALIZER;
	chunk_t iv     = CHUNK_INITIALIZER;

	u_char iv_buf[16]; /* MD5 digest size */

	/* zero size of converted blob */
	dst.len = 0;

	/* zero size of IV */
	iv.ptr = iv_buf;
	iv.len = 0;

	pem_init_logger();

	while (fetchline(&src, &line))
	{
		if (state == PEM_PRE)
		{
			if (find_boundary("BEGIN", &line))
			{
				state = PEM_MSG;
			}
			continue;
		}
		else
		{
			if (find_boundary("END", &line))
			{
				state = PEM_POST;
				break;
			}
			if (state == PEM_MSG)
			{
				state = (memchr(line.ptr, ':', line.len) == NULL) ? PEM_BODY : PEM_HEADER;
			}
			if (state == PEM_HEADER)
			{
				err_t ugh = NULL;
				chunk_t name  = CHUNK_INITIALIZER;
				chunk_t value = CHUNK_INITIALIZER;

				/* an empty line separates HEADER and BODY */
				if (line.len == 0)
				{
					state = PEM_BODY;
					continue;
				}

				/* we are looking for a parameter: value pair */
				logger->log(logger, CONTROL|LEVEL2, "  %.*s", (int)line.len, line.ptr);
				ugh = extract_parameter_value(&name, &value, &line);
				if (ugh != NULL)
					continue;

				if (match("Proc-Type", &name) && *value.ptr == '4')
					encrypted = TRUE;
				else if (match("DEK-Info", &name))
				{
					size_t len = 0;
					chunk_t dek;

					if (!extract_token(&dek, ',', &value))
						dek = value;

					/* we support DES-EDE3-CBC encrypted files, only */
					if (match("DES-EDE3-CBC", &dek))
					{
						alg = ENCR_3DES;
						key_size = 24;
					}
					else if (match("AES-128-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 16;
					}
					else if (match("AES-192-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 24;
					}
					else if (match("AES-256-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 32;
					}
					else
					{
						return "encryption algorithm not supported";
					}

					eat_whitespace(&value);
					ugh = ttodata(value.ptr, value.len, 16, iv.ptr, 16, &len);
					if (ugh)
						return "error in IV";

					iv.len = len;
				}
			}
			else /* state is PEM_BODY */
			{
				const char *ugh = NULL;
				size_t len = 0;
				chunk_t data;
				
				/* remove any trailing whitespace */
				if (!extract_token(&data ,' ', &line))
				{
					data = line;
				}
				
				/* check for PGP armor checksum */
				if (*data.ptr == '=')
				{
					*pgp = TRUE;
					data.ptr++;
					data.len--;
					logger->log(logger, CONTROL|LEVEL2, "  Armor checksum: %.*s",
								(int)data.len, data.ptr);
		    		continue;
				}

				ugh = ttodata(data.ptr, data.len, 64, dst.ptr, blob->len - dst.len, &len);
				if (ugh)
				{
					state = PEM_ABORT;
					break;
				}
				else
				{
					dst.ptr += len;
					dst.len += len;
				}
			}
		}
	}
	/* set length to size of binary blob */
	blob->len = dst.len;

	if (state != PEM_POST)
		return "file coded in unknown format, discarded";

	return (encrypted)? pem_decrypt(blob, alg, key_size, &iv, passphrase) : NULL;
}
Beispiel #7
0
void vi()
{
	REG int			key;	/* keystroke from user */
	long			count;	/* numeric argument to some functions */
	REG struct keystru	*keyptr;/* pointer to vikeys[] element */
	MARK			tcurs;	/* temporary cursor */
	int			prevkey;/* previous key, if d/c/y/</>/! */
	MARK			range;	/* start of range for d/c/y/</>/! */
	char			text[132];
	int			dotkey;	/* last "key" of a change */
	int			dotpkey;/* last "prevkey" of a change */
	int			dotkey2;/* last extra "getkey()" of a change */
	int			dotcnt;	/* last "count" of a change */
	int			firstkey;
	REG int			i;

	/* tell the redraw() function to start from scratch */
	redraw(MARK_UNSET, FALSE);

#ifdef lint
	/* lint says that "range" might be used before it is set.  This
	 * can't really happen due to the way "range" and "prevkey" are used,
	 * but lint doesn't know that.  This line is here ONLY to keep lint
	 * happy.
	 */
	range = 0L;
#endif

	/* safeguard against '.' with no previous command */
	dotkey = dotpkey = dotkey2 = dotcnt = 0;

	/* go immediately into insert mode, if ":set inputmode" */
	firstkey = 0;
#ifndef NO_EXTENSIONS
	if (*o_inputmode)
	{
		firstkey = 'i';
	}
#endif

	/* Repeatedly handle VI commands */
	for (count = 0, prevkey = '\0'; mode == MODE_VI; )
	{
		/* if we've moved off the undoable line, then we can't undo it at all */
		if (markline(cursor) != U_line)
		{
			U_line = 0L;
		}

		/* report any changes from the previous command */
		if (rptlines >= *o_report)
		{
			redraw(cursor, FALSE);
			msg("%ld line%s %s", rptlines, (rptlines==1?"":"s"), rptlabel);
		}
		rptlines = 0L;

		/* get the next command key.  It must be ASCII */
		if (firstkey)
		{
			key = firstkey;
			firstkey = 0;
		}
		else
		{
			do
			{
				key = getkey(WHEN_VICMD);
			} while (key < 0 || key > 127);
		}
#ifdef DEBUG2
		debout("\nkey='%c'\n", key);
#endif

		/* Convert a doubled-up operator such as "dd" into "d_" */
		if (prevkey && key == prevkey)
		{
			key = '_';
		}

		/* look up the structure describing this command */
		keyptr = &vikeys[key];

		/* '&' and uppercase operators always act like doubled */
		if (!prevkey && keyptr->args == CURSOR_MOVED
			&& (key == '&' || isupper(key)))
		{
			range = cursor;
			prevkey = key;
			key = '_';
			keyptr = &vikeys[key];
		}

#ifndef NO_VISIBLE
		/* if we're in the middle of a v/V command, reject commands
		 * that aren't operators or movement commands
		 */
		if (V_from && !(keyptr->flags & VIZ))
		{
			beep();
			prevkey = 0;
			count = 0;
			continue;
		}
#endif

		/* if we're in the middle of a d/c/y/</>/! command, reject
		 * anything but movement.
		 */
		if (prevkey && !(keyptr->flags & (MVMT|PTMV)))
		{
			beep();
			prevkey = 0;
			count = 0;
			continue;
		}

		/* set the "dot" variables, if we're supposed to */
		if (((keyptr->flags & SDOT)
			|| (prevkey && vikeys[prevkey].flags & SDOT))
#ifndef NO_VISIBLE
		    && !V_from
#endif
		)
		{
			dotkey = key;
			dotpkey = prevkey;
			dotkey2 = '\0';
			dotcnt = count;

			/* remember the line before any changes are made */
			if (U_line != markline(cursor))
			{
				U_line = markline(cursor);
				strcpy(U_text, fetchline(U_line));
			}
		}

		/* if this is "." then set other vars from the "dot" vars */
		if (key == '.')
		{
			key = dotkey;
			keyptr = &vikeys[key];
			prevkey = dotpkey;
			if (prevkey)
			{
				range = cursor;
			}
			if (count == 0)
			{
				count = dotcnt;
			}
			doingdot = TRUE;

			/* remember the line before any changes are made */
			if (U_line != markline(cursor))
			{
				U_line = markline(cursor);
				strcpy(U_text, fetchline(U_line));
			}
		}
		else
		{
			doingdot = FALSE;
		}

		/* process the key as a command */
		tcurs = cursor;
		force_flags = NO_FLAGS;
		switch (keyptr->args & ARGSMASK)
		{
		  case ZERO:
			if (count == 0)
			{
				tcurs = cursor & ~(BLKSIZE - 1);
				break;
			}
			/* else fall through & treat like other digits... */

		  case DIGIT:
			count = count * 10 + key - '0';
			break;

		  case KEYWORD:
			/* if not on a keyword, fail */
			pfetch(markline(cursor));
			key = markidx(cursor);
			if (!isalnum(ptext[key]))
			{
				tcurs = MARK_UNSET;
				break;
			}

			/* find the start of the keyword */
			while (key > 0 && isalnum(ptext[key - 1]))
			{
				key--;
			}
			tcurs = (cursor & ~(BLKSIZE - 1)) + key;

			/* copy it into a buffer, and NUL-terminate it */
			i = 0;
			do
			{
				text[i++] = ptext[key++];
			} while (isalnum(ptext[key]));
			text[i] = '\0';

			/* call the function */
			tcurs = (*keyptr->func)(text, tcurs, count);
			count = 0L;
			break;

		  case NO_ARGS:
			if (keyptr->func)
			{
				(*keyptr->func)();
			}
			else
			{
				beep();
			}
			count = 0L;
			break;
	
		  case CURSOR:
			tcurs = (*keyptr->func)(cursor, count, key, prevkey);
			count = 0L;
			break;

		  case CURSOR_CNT_KEY:
			if (doingdot)
			{
				tcurs = (*keyptr->func)(cursor, count, dotkey2);
			}
			else
			{
				/* get a key */
				i = getkey(KEYMODE(keyptr->args));
				if (i == '\033') /* ESC */
				{
					count = 0;
					tcurs = MARK_UNSET;
					break; /* exit from "case CURSOR_CNT_KEY" */
				}
				else if (i == ctrl('V'))
				{
					i = getkey(0);
				}

				/* if part of an SDOT command, remember it */
				 if (keyptr->flags & SDOT
				 || (prevkey && vikeys[prevkey].flags & SDOT))
				{
					dotkey2 = i;
				}

				/* do it */
				tcurs = (*keyptr->func)(cursor, count, i);
			}
			count = 0L;
			break;
	
		  case CURSOR_MOVED:
#ifndef NO_VISIBLE
			if (V_from)
			{
				range = cursor;
				tcurs = V_from;
				count = 0L;
				prevkey = key;
				key = (V_linemd ? 'V' : 'v');
				keyptr = &vikeys[key];
			}
			else
#endif
			{
				prevkey = key;
				range = cursor;
				force_flags = LNMD|INCL;
			}
			break;

		  case CURSOR_EOL:
			prevkey = key;
			/* a zero-length line needs special treatment */
			pfetch(markline(cursor));
			if (plen == 0)
			{
				/* act on a zero-length section of text */
				range = tcurs = cursor;
				key = '0';
			}
			else
			{
				/* act like CURSOR_MOVED with '$' movement */
				range = cursor;
				tcurs = m_rear(cursor, 1L);
				key = '$';
			}
			count = 0L;
			keyptr = &vikeys[key];
			break;

		  case CURSOR_TEXT:
		  	do
		  	{	
				text[0] = key;
				text[1] = '\0';
				if (doingdot || vgets(key, text + 1, sizeof text - 1) >= 0)
				{
					/* reassure user that <CR> was hit */
					qaddch('\r');
					refresh();

					/* call the function with the text */
					tcurs = (*keyptr->func)(cursor, text);
				}
				else
				{
					if (exwrote || mode == MODE_COLON)
					{
						redraw(MARK_UNSET, FALSE);
					}
					mode = MODE_VI;
				}
			} while (mode == MODE_COLON);
			count = 0L;
			break;
		}

		/* if that command took us out of vi mode, then exit the loop
		 * NOW, without tweaking the cursor or anything.  This is very
		 * important when mode == MODE_QUIT.
		 */
		if (mode != MODE_VI)
		{
			break;
		}

		/* now move the cursor, as appropriate */
		if (prevkey && ((keyptr->flags & MVMT)
#ifndef NO_VISIBLE
					       || V_from
#endif
				) && count == 0L)
		{
			/* movements used as targets are less strict */
			tcurs = adjmove(cursor, tcurs, (int)(keyptr->flags | force_flags));
		}
		else if (keyptr->args == CURSOR_MOVED)
		{
			/* the < and > keys have FRNT,
			 * but it shouldn't be applied yet
			 */
			tcurs = adjmove(cursor, tcurs, FINL);
		}
		else
		{
			tcurs = adjmove(cursor, tcurs, (int)(keyptr->flags | force_flags | FINL));
		}

		/* was that the end of a d/c/y/</>/! command? */
		if (prevkey && ((keyptr->flags & MVMT)
#ifndef NO_VISIBLE
					       || V_from
#endif
				) && count == 0L)
		{
#ifndef NO_VISIBLE
			/* turn off the hilight */
			V_from = 0L;
#endif

			/* if the movement command failed, cancel operation */
			if (tcurs == MARK_UNSET)
			{
				prevkey = 0;
				count = 0;
				continue;
			}

			/* make sure range=front and tcurs=rear.  Either way,
			 * leave cursor=range since that's where we started.
			 */
			cursor = range;
			if (tcurs < range)
			{
				range = tcurs;
				tcurs = cursor;
			}

			/* The 'w' and 'W' destinations should never take us
			 * to the front of a line.  Instead, they should take
			 * us only to the end of the preceding line.
			 */
			if ((keyptr->flags & NWRP) == NWRP
			  && markline(range) < markline(tcurs)
			  && (markline(tcurs) > nlines || tcurs == m_front(tcurs, 0L)))
			{
				tcurs = (tcurs & ~(BLKSIZE - 1)) - BLKSIZE;
				pfetch(markline(tcurs));
				tcurs += plen;
			}

			/* adjust for line mode & inclusion of last char/line */
			i = (keyptr->flags | vikeys[prevkey].flags);
			switch ((i | force_flags) & (INCL|LNMD))
			{
			  case INCL:
				tcurs++;
				break;

			  case INCL|LNMD:
				tcurs += BLKSIZE;
				/* fall through... */

			  case LNMD:
				range &= ~(BLKSIZE - 1);
				tcurs &= ~(BLKSIZE - 1);
				break;
			}

			/* run the function */
			tcurs = (*vikeys[prevkey].func)(range, tcurs);
			if (mode == MODE_VI)
			{
				(void)adjmove(cursor, cursor, FINL);
				cursor = adjmove(cursor, tcurs, (int)(vikeys[prevkey].flags | FINL));
			}

			/* cleanup */
			prevkey = 0;
		}
		else if (!prevkey)
		{
			if (tcurs != MARK_UNSET)
				cursor = tcurs;
		}
	}
}
Beispiel #8
0
vi()
{
	register int		key;	/* keystroke from user */
	long			count;	/* numeric argument to some functions */
	register struct keystru	*keyptr;/* pointer to vikeys[] element */
	MARK			tcurs;	/* temporary cursor */
	int			prevkey;/* previous key, if d/c/y/</>/! */
	MARK			range;	/* start of range for d/c/y/</>/! */
	char			text[100];
	int			dotkey;	/* last "key" of a change */
	int			dotpkey;/* last "prevkey" of a change */
	int			dotkey2;/* last extra "getkey()" of a change */
	int			dotcnt;	/* last "count" of a change */
	register int		i;

	/* tell the redraw() function to start from scratch */
	redraw(MARK_UNSET, FALSE);
	msg((char *)0);

#ifdef lint
	/* lint says that "range" might be used before it is set.  This
	 * can't really happen due to the way "range" and "prevkey" are used,
	 * but lint doesn't know that.  This line is here ONLY to keep lint
	 * happy.
	 */
	range = 0L;
#endif

	/* safeguard against '.' with no previous command */
	dotkey = 0;

	/* Repeatedly handle VI commands */
	for (count = 0, prevkey = '\0'; mode == MODE_VI; )
	{
		/* if we've moved off the undoable line, then we can't undo it at all */
		if (markline(cursor) != U_line)
		{
			U_line = 0L;
		}

		/* report any changes from the previous command */
		if (rptlines >= *o_report)
		{
			redraw(cursor, FALSE);
			msg("%ld lines %s", rptlines, rptlabel);
		}
		rptlines = 0L;

		/* get the next command key.  It must be ASCII */
		do
		{
			key = getkey(WHEN_VICMD);
		} while (key < 0 || key > 127);

		/* change cw and cW commands to ce and cE, respectively */
		/* (Why?  because the real vi does it that way!) */
		if (prevkey == 'c')
		{
			if (key == 'w')
				key = 'e';
			else if (key == 'W')
				key = 'E';

			/* wouldn't work right at the end of a word unless we
			 * backspace one character before doing the move.  This
			 * will fix most cases.
			 */
			if (markidx(cursor) > 0 && (key == 'e' || key == 'E'))
			{
				cursor--;
			}
		}

		/* look up the structure describing this command */
		keyptr = &vikeys[key];

		/* if we're in the middle of a d/c/y/</>/! command, reject
		 * anything but movement or a doubled version like "dd".
		 */
		if (prevkey && key != prevkey && !(keyptr->flags & (MVMT|PTMV)))
		{
			beep();
			prevkey = 0;
			count = 0;
			continue;
		}

		/* set the "dot" variables, if we're supposed to */
		if ((keyptr->flags & SDOT)
		 || (prevkey && vikeys[prevkey].flags & SDOT))
		{
			dotkey = key;
			dotpkey = prevkey;
			dotkey2 = '\0';
			dotcnt = count;

			/* remember the line before any changes are made */
			if (U_line != markline(cursor))
			{
				U_line = markline(cursor);
				strcpy(U_text, fetchline(U_line));
			}
		}

		/* if this is "." then set other vars from the "dot" vars */
		if (key == '.')
		{
			key = dotkey;
			keyptr = &vikeys[key];
			prevkey = dotpkey;
			if (prevkey)
			{
				range = cursor;
			}
			if (count == 0)
			{
				count = dotcnt;
			}
			doingdot = TRUE;

			/* remember the line before any changes are made */
			if (U_line != markline(cursor))
			{
				U_line = markline(cursor);
				strcpy(U_text, fetchline(U_line));
			}
		}
		else
		{
			doingdot = FALSE;
		}

		/* process the key as a command */
		tcurs = cursor;
		switch (keyptr->args)
		{
		  case ZERO:
			if (count == 0)
			{
				tcurs = cursor & ~(BLKSIZE - 1);
				break;
			}
			/* else fall through & treat like other digits... */

		  case DIGIT:
			count = count * 10 + key - '0';
			break;

		  case KEYWORD:
			/* if not on a keyword, fail */
			pfetch(markline(cursor));
			key = markidx(cursor);
			if (!isalnum(ptext[key]) && ptext[key] != '_')
			{
				tcurs = MARK_UNSET;
				break;
			}

			/* find the start of the keyword */
			while (key > 0 && (isalnum(ptext[key - 1]) || ptext[key - 1] == '_'))
			{
				key--;
			}

			/* copy it into a buffer, and NUL-terminate it */
			i = 0;
			do
			{
				text[i++] = ptext[key++];
			} while (isalnum(ptext[key]) || ptext[key] == '_');
			text[i] = '\0';

			/* call the function */
			tcurs = (*keyptr->func)(text);
			count = 0L;
			break;

		  case NO_ARGS:
			if (keyptr->func)
			{
				(*keyptr->func)();
			}
			else
			{
				beep();
			}
			count = 0L;
			break;
	
		  case CURSOR_COUNT:
			tcurs = (*keyptr->func)(cursor, count);
			count = 0L;
			break;
	
		  case CURSOR:
			tcurs = (*keyptr->func)(cursor);
			count = 0L;
			break;

		  case CURSOR_CNT_KEY:
			if (doingdot)
			{
				tcurs = (*keyptr->func)(cursor, count, dotkey2);
			}
			else if (keyptr->flags & SDOT
			 || (prevkey && vikeys[prevkey].flags & SDOT))
			{
				dotkey2 = getkey(0);
				tcurs = (*keyptr->func)(cursor, count, dotkey2);
			}
			else
			{
				tcurs = (*keyptr->func)(cursor, count, getkey(0));
			}
			count = 0L;
			break;
	
		  case CURSOR_MOVED:
			/* uppercase keys always act like doubled */
			if (isupper(key))
			{
				prevkey = key;
				range = cursor;
			}

			if (prevkey)
			{
				/* doubling up a command, use complete lines */
				range &= ~(BLKSIZE - 1);
				if (count)
				{
					tcurs = range + MARK_AT_LINE(count);
					count = 0;
				}
				else
				{
					tcurs = range + BLKSIZE;
				}
			}
			else
			{
				prevkey = key;
				range = cursor;
				key = -1; /* so we don't think we doubled yet */
			}
			break;

		  case CURSOR_EOL:
			/* act like CURSOR_MOVED with '$' movement */
			range = cursor;
			tcurs = moverear(cursor, 1L);
			count = 0L;
			prevkey = key;
			key = '$';
			keyptr = &vikeys['$'];
			break;

		  case CURSOR_TEXT:
			if (vgets(key, text, sizeof text) >= 0)
			{
				/* reassure user that <CR> was hit */
				qaddch('\r');
				refresh();

				/* call the function with the text */
				tcurs = (*keyptr->func)(cursor, text);
			}
			count = 0L;
			break;

		  case CURSOR_CNT_CMD:
			tcurs = (*keyptr->func)(cursor, count, key);
			count = 0L;
			break;
		}

		/* if that command took us out of vi mode, then exit the loop
		 * NOW, without tweaking the cursor or anything.  This is very
		 * important when mode == MODE_QUIT.
		 */
		if (mode != MODE_VI)
		{
			break;
		}

		/* now move the cursor, as appropriate */
		if (prevkey && markline(tcurs) > nlines)
		{
			/* destination for operator may be nlines + 1 */
			cursor = MARK_AT_LINE(nlines + 1);
		}
		else if (keyptr->args == CURSOR_MOVED)
		{
			/* the < and > keys have FRNT,
			 * but it shouldn't be applied yet
			 */
			cursor = adjmove(cursor, tcurs, 0);
		}
		else
		{
			cursor = adjmove(cursor, tcurs, keyptr->flags);
		}

		/* was that the end of a d/c/y/</>/! command? */
		if (prevkey && (prevkey == key || (keyptr->flags & MVMT)))
		{
			/* if the movement command failed, cancel operation */
			if (tcurs == MARK_UNSET)
			{
				prevkey = 0;
				count = 0;
				continue;
			}

			/* make sure range=front and tcurs=rear */
			if (cursor < range)
			{
				tcurs = range;
				range = cursor;
			}
			else
			{
				tcurs = cursor;
			}

			/* adjust for line mode */
			if (keyptr->flags & LNMD)
			{
				range &= ~(BLKSIZE - 1);
				tcurs &= ~(BLKSIZE - 1);
				tcurs += BLKSIZE;
			}

			/* adjust for inclusion of last char */
			if (keyptr->flags & INCL)
			{
				tcurs++;
			}

			/* temporarily move the cursor to "range" so that
			 * beforedo() remembers the cursor's real location.
			 * This is important if the user later does undo()
			 */
			cursor = range;

			/* run the function */
			tcurs = (*vikeys[prevkey].func)(range, tcurs);
			cursor = adjmove(cursor, tcurs, vikeys[prevkey].flags);

			/* cleanup */
			prevkey = 0;
		}
	}
}
/**
 * load IMCs from a configuration file
 */
static bool load_imcs(char *filename)
{
	int fd, line_nr = 0;
	chunk_t src, line;
	struct stat sb;
	void *addr;

	DBG1(DBG_TNC, "loading IMCs from '%s'", filename);
	fd = open(filename, O_RDONLY);
	if (fd == -1)
	{
		DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
			 strerror(errno));
		return FALSE;
	}
	if (fstat(fd, &sb) == -1)
	{
		DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
			 strerror(errno));
		close(fd);
		return FALSE;
	}
	addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
	if (addr == MAP_FAILED)
	{
		DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
		close(fd);
		return FALSE;
	}
	src = chunk_create(addr, sb.st_size);

	while (fetchline(&src, &line))
	{
		char *name, *path;
		chunk_t token;
		imc_t *imc;

		line_nr++;

		/* skip comments or empty lines */
		if (*line.ptr == '#' || !eat_whitespace(&line))
		{
			continue;
		}

		/* determine keyword */
		if (!extract_token(&token, ' ', &line))
		{
			DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
						   line_nr);
			return FALSE;
		}

		/* only interested in IMCs */
		if (!match("IMC", &token))
		{
			continue;
		}

		/* advance to the IMC name and extract it */
		if (!extract_token(&token, '"', &line) ||
			!extract_token(&token, '"', &line))
		{
			DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes",
						   line_nr);
			return FALSE;
		}

		/* copy the IMC name */
		name = malloc(token.len + 1);
		memcpy(name, token.ptr, token.len);
		name[token.len] = '\0';

		/* advance to the IMC path and extract it */
		if (!eat_whitespace(&line))
		{
			DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr);
			free(name);
			return FALSE;
		}
		if (!extract_token(&token, ' ', &line))
		{
			token = line;
		}

		/* copy the IMC path */
		path = malloc(token.len + 1);
		memcpy(path, token.ptr, token.len);
		path[token.len] = '\0';

		/* load and register IMC instance */
		imc = tnc_imc_create(name, path);
		if (!imc)
		{
			free(name);
			free(path);
			return FALSE;
		}
		if (!charon->imcs->add(charon->imcs, imc))
		{
			if (imc->terminate &&
				imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
			{
				DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
							   imc->get_name(imc));
			}
			imc->destroy(imc);
			return FALSE;
		}
		DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc),
														name, path);
	}
	munmap(addr, sb.st_size);
	close(fd);
	return TRUE;
}
Beispiel #10
0
void command_loop(void)
{
    int c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
    char *input;
    char **v;
    const cmdinfo_t *ct;

    for (i = 0; !done && i < ncmdline; i++) {
        input = strdup(cmdline[i]);
        if (!input) {
            fprintf(stderr, _("cannot strdup command '%s': %s\n"),
                    cmdline[i], strerror(errno));
            exit(1);
        }
        v = breakline(input, &c);
        if (c) {
            ct = find_command(v[0]);
            if (ct) {
                if (ct->flags & CMD_FLAG_GLOBAL) {
                    done = command(ct, c, v);
                } else {
                    j = 0;
                    while (!done && (j = args_command(j))) {
                        done = command(ct, c, v);
                    }
                }
            } else {
                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
            }
	}
        doneline(input, v);
    }
    if (cmdline) {
        g_free(cmdline);
        return;
    }

    while (!done) {
        if (!prompted) {
            printf("%s", get_prompt());
            fflush(stdout);
            qemu_aio_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, NULL,
                                    NULL, &fetchable);
            prompted = 1;
        }

        qemu_aio_wait();

        if (!fetchable) {
            continue;
        }
        input = fetchline();
        if (input == NULL) {
            break;
        }
        v = breakline(input, &c);
        if (c) {
            ct = find_command(v[0]);
            if (ct) {
                done = command(ct, c, v);
            } else {
                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
            }
        }
        doneline(input, v);

        prompted = 0;
        fetchable = 0;
    }
    qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
}
Beispiel #11
0
/**
 * Converts a PEM encoded file into its binary form (RFC 1421, RFC 934)
 */
static status_t pem_to_bin(chunk_t *blob, bool *pgp)
{
	typedef enum {
		PEM_PRE    = 0,
		PEM_MSG    = 1,
		PEM_HEADER = 2,
		PEM_BODY   = 3,
		PEM_POST   = 4,
		PEM_ABORT  = 5
	} state_t;

	encryption_algorithm_t alg = ENCR_UNDEFINED;
	size_t key_size = 0;
	bool encrypted = FALSE;
	state_t state  = PEM_PRE;
	chunk_t src    = *blob;
	chunk_t dst    = *blob;
	chunk_t line   = chunk_empty;
	chunk_t iv     = chunk_empty;
	u_char iv_buf[HASH_SIZE_MD5];
	status_t status = NOT_FOUND;
	enumerator_t *enumerator;
	shared_key_t *shared;

	dst.len = 0;
	iv.ptr = iv_buf;
	iv.len = 0;

	while (fetchline(&src, &line))
	{
		if (state == PEM_PRE)
		{
			if (find_boundary("BEGIN", &line))
			{
				state = PEM_MSG;
			}
			continue;
		}
		else
		{
			if (find_boundary("END", &line))
			{
				state = PEM_POST;
				break;
			}
			if (state == PEM_MSG)
			{
				state = PEM_HEADER;
				if (memchr(line.ptr, ':', line.len) == NULL)
				{
					state = PEM_BODY;
				}
			}
			if (state == PEM_HEADER)
			{
				err_t ugh = NULL;
				chunk_t name  = chunk_empty;
				chunk_t value = chunk_empty;

				/* an empty line separates HEADER and BODY */
				if (line.len == 0)
				{
					state = PEM_BODY;
					continue;
				}

				/* we are looking for a parameter: value pair */
				DBG2(DBG_ASN, "  %.*s", (int)line.len, line.ptr);
				ugh = extract_parameter_value(&name, &value, &line);
				if (ugh != NULL)
				{
					continue;
				}
				if (match("Proc-Type", &name) && *value.ptr == '4')
				{
					encrypted = TRUE;
				}
				else if (match("DEK-Info", &name))
				{
					chunk_t dek;

					if (!extract_token(&dek, ',', &value))
					{
						dek = value;
					}
					if (match("DES-EDE3-CBC", &dek))
					{
						alg = ENCR_3DES;
						key_size = 24;
					}
					else if (match("AES-128-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 16;
					}
					else if (match("AES-192-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 24;
					}
					else if (match("AES-256-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 32;
					}
					else
					{
						DBG1(DBG_ASN, "  encryption algorithm '%.*s'"
							 " not supported", (int)dek.len, dek.ptr);
						return NOT_SUPPORTED;
					}
					if (!eat_whitespace(&value) || value.len > 2*sizeof(iv_buf))
					{
						return PARSE_ERROR;
					}
					iv = chunk_from_hex(value, iv_buf);
				}
			}
			else /* state is PEM_BODY */
			{
				chunk_t data;

				/* remove any trailing whitespace */
				if (!extract_token(&data ,' ', &line))
				{
					data = line;
				}

				/* check for PGP armor checksum */
				if (*data.ptr == '=')
				{
					*pgp = TRUE;
					data.ptr++;
					data.len--;
					DBG2(DBG_ASN, "  armor checksum: %.*s", (int)data.len,
						 data.ptr);
					continue;
				}

				if (blob->len - dst.len < data.len / 4 * 3)
				{
					state = PEM_ABORT;
				}
				data = chunk_from_base64(data, dst.ptr);

				dst.ptr += data.len;
				dst.len += data.len;
			}
		}
	}
	/* set length to size of binary blob */
	blob->len = dst.len;

	if (state != PEM_POST)
	{
		DBG1(DBG_LIB, "  file coded in unknown format, discarded");
		return PARSE_ERROR;
	}
	if (!encrypted)
	{
		return SUCCESS;
	}

	enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
											SHARED_PRIVATE_KEY_PASS, NULL, NULL);
	while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
	{
		chunk_t passphrase, chunk;

		passphrase = shared->get_key(shared);
		chunk = chunk_clone(*blob);
		status = pem_decrypt(&chunk, alg, key_size, iv, passphrase);
		if (status == SUCCESS)
		{
			memcpy(blob->ptr, chunk.ptr, chunk.len);
			blob->len = chunk.len;
		}
		free(chunk.ptr);
		if (status != INVALID_ARG)
		{	/* try again only if passphrase invalid */
			break;
		}
	}
	enumerator->destroy(enumerator);
	return status;
}
/**
 * Converts a PEM encoded file into its binary form (RFC 1421, RFC 934)
 */
static status_t pem_to_bin(chunk_t *blob, chunk_t(*cb)(void*,int), void *cb_data,
						   bool *pgp)
{
	typedef enum {
		PEM_PRE    = 0,
		PEM_MSG    = 1,
		PEM_HEADER = 2,
		PEM_BODY   = 3,
		PEM_POST   = 4,
		PEM_ABORT  = 5
	} state_t;

	encryption_algorithm_t alg = ENCR_UNDEFINED;
	size_t key_size = 0;
	bool encrypted = FALSE;
	state_t state  = PEM_PRE;
	chunk_t src    = *blob;
	chunk_t dst    = *blob;
	chunk_t line   = chunk_empty;
	chunk_t iv     = chunk_empty;
	chunk_t passphrase;
	int try = 0;
	u_char iv_buf[HASH_SIZE_MD5];

	dst.len = 0;
	iv.ptr = iv_buf;
	iv.len = 0;

	while (fetchline(&src, &line))
	{
		if (state == PEM_PRE)
		{
			if (find_boundary("BEGIN", &line))
			{
				state = PEM_MSG;
			}
			continue;
		}
		else
		{
			if (find_boundary("END", &line))
			{
				state = PEM_POST;
				break;
			}
			if (state == PEM_MSG)
			{
				state = PEM_HEADER;
				if (memchr(line.ptr, ':', line.len) == NULL)
				{
					state = PEM_BODY;
				}
			}
			if (state == PEM_HEADER)
			{
				err_t ugh = NULL;
				chunk_t name  = chunk_empty;
				chunk_t value = chunk_empty;

				/* an empty line separates HEADER and BODY */
				if (line.len == 0)
				{
					state = PEM_BODY;
					continue;
				}

				/* we are looking for a parameter: value pair */
				DBG2(DBG_LIB, "  %.*s", (int)line.len, line.ptr);
				ugh = extract_parameter_value(&name, &value, &line);
				if (ugh != NULL)
				{
					continue;
				}
				if (match("Proc-Type", &name) && *value.ptr == '4')
				{
					encrypted = TRUE;
				}
				else if (match("DEK-Info", &name))
				{
					chunk_t dek;

					if (!extract_token(&dek, ',', &value))
					{
						dek = value;
					}
					if (match("DES-EDE3-CBC", &dek))
					{
						alg = ENCR_3DES;
						key_size = 24;
					}
					else if (match("AES-128-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 16;
					}
					else if (match("AES-192-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 24;
					}
					else if (match("AES-256-CBC", &dek))
					{
						alg = ENCR_AES_CBC;
						key_size = 32;
					}
					else
					{
						DBG1(DBG_LIB, "  encryption algorithm '%.*s'"
							 " not supported", dek.len, dek.ptr);
						return NOT_SUPPORTED;
					}
					eat_whitespace(&value);
					iv = chunk_from_hex(value, iv.ptr);
				}
			}
			else /* state is PEM_BODY */
			{
				chunk_t data;

				/* remove any trailing whitespace */
				if (!extract_token(&data ,' ', &line))
				{
					data = line;
				}

				/* check for PGP armor checksum */
				if (*data.ptr == '=')
				{
					*pgp = TRUE;
					data.ptr++;
					data.len--;
					DBG2(DBG_LIB, "  armor checksum: %.*s", (int)data.len,
						 data.ptr);
					continue;
				}

				if (blob->len - dst.len < data.len / 4 * 3)
				{
					state = PEM_ABORT;
				}
				data = chunk_from_base64(data, dst.ptr);

				dst.ptr += data.len;
				dst.len += data.len;
			}
		}
	}
	/* set length to size of binary blob */
	blob->len = dst.len;

	if (state != PEM_POST)
	{
		DBG1(DBG_LIB, "  file coded in unknown format, discarded");
		return PARSE_ERROR;
	}
	if (!encrypted)
	{
		return SUCCESS;
	}
	if (!cb)
	{
		DBG1(DBG_LIB, "  missing passphrase");
		return INVALID_ARG;
	}
	while (TRUE)
	{
		passphrase = cb(cb_data, ++try);
		if (!passphrase.len || !passphrase.ptr)
		{
			return INVALID_ARG;
		}
		switch (pem_decrypt(blob, alg, key_size, iv, passphrase))
		{
			case INVALID_ARG:
				/* bad passphrase, retry */
				continue;
			case SUCCESS:
				return SUCCESS;
			default:
				return FAILED;
		}
	}
}
Beispiel #13
0
/*
 * Converts a PEM encoded file into its binary form
 *
 * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
 * RFC 934 Message Encapsulation, January 1985
 *
 * We no longer support decrypting PEM files - those can only come in via NSS
 */
err_t pemtobin(chunk_t *blob)
{
	typedef enum {
		PEM_PRE    = 0,
		PEM_MSG    = 1,
		PEM_HEADER = 2,
		PEM_BODY   = 3,
		PEM_POST   = 4,
		PEM_ABORT  = 5
	} state_t;

	state_t state  = PEM_PRE;

	chunk_t src    = *blob;
	chunk_t dst    = *blob;
	chunk_t line   = empty_chunk;

	/* zero size of converted blob */
	dst.len = 0;

	while (fetchline(&src, &line)) {
		if (state == PEM_PRE) {
			if (find_boundary("BEGIN", &line)) {
				state = PEM_MSG;
			}
			continue;
		} else {
			if (find_boundary("END", &line)) {
				state = PEM_POST;
				break;
			}
			if (state == PEM_MSG) {
				state = (memchr(line.ptr, ':',
						line.len) == NULL) ?
					PEM_BODY : PEM_HEADER;
			}
			if (state == PEM_HEADER) {
				chunk_t name  = empty_chunk;
				chunk_t value = empty_chunk;

				/* an empty line separates HEADER and BODY */
				if (line.len == 0) {
					state = PEM_BODY;
					continue;
				}

				/* we are looking for a name: value pair */
				if (!extract_parameter(&name, &value, &line))
					continue;

				if (match("Proc-Type",
						&name) && *value.ptr == '4')
					return "Proc-Type: encrypted files no longer supported outside of the NSS database, please import these into NSS";

				else if (match("DEK-Info", &name))
					return "DEK-Info: encrypted files no longer supported outside of the NSS database, please import these into NSS";

			} else {
				/* state is PEM_BODY */
				const char *ugh = NULL;
				size_t len = 0;
				chunk_t data;

				/* remove any trailing whitespace */
				if (!extract_token(&data, ' ', &line))
					data = line;

				ugh = ttodata((char *)data.ptr, data.len, 64,
					(char *)dst.ptr,
					blob->len - dst.len, &len);
				if (ugh) {
					DBG(DBG_PARSING,
						DBG_log("  %s", ugh));
					state = PEM_ABORT;
					break;
				} else {
					dst.ptr += len;
					dst.len += len;
				}
			}
		}
	}
	/* set length to size of binary blob */
	blob->len = dst.len;

	if (state != PEM_POST)
		return "file coded in unknown format, discarded";

	return NULL;
}
Beispiel #14
0
int main(int argc, char *argv[]) {
    xfs_mount_t	*mp;
    xfs_inode_t *inode = NULL;
    xfs_off_t ofs;
    struct filldir_data filldata;
    char *progname;
    char *source_name;
    int r, fd;
    char *line;
    char path[FILENAME_MAX] = "/";
    char newpath[FILENAME_MAX] = "/";
    char *buffer[BUFSIZE];
    off_t offset;

    if (argc != 2) {
        printf("Usage: xfs-cli raw_device\n");
        return 1;
    }
    progname = argv[0];
    source_name = argv[1];
    
    mp = mount_xfs(progname, source_name);
    
    if (mp == NULL) 
        return 1;
    
    while (line == fetchline(mp, path)) {
        inode = NULL;
        strip(line, ' ');
        if (strncmp(line, "cd ", 3) == 0) {
            if (strcmp(line+3, "..") == 0) {
                goto_parent(path);
            } else {
                strcpy(newpath, path);
                strcat(newpath, line+3);
                r = find_path(mp, newpath, &inode);
                if ((!r) && (xfs_is_dir(inode))) {
                    //TODO: check if it is a directory
                    strcpy(path, newpath);
                    strcat(path, "/");
                    printf("%s\n", path);
                } else {
                    if (r) {
                        printf("No such directory\n");
                    } else {
                        printf("Not a directory\n");
                    }
                }
            }
        }
        else if (strcmp(line, "ls") == 0) {
            r = find_path(mp, path, &inode);
            if (!r) {
                //TODO: check if it is a directory
                ofs=0;
                filldata.mp = mp;
                filldata.base = inode;
                r = xfs_readdir(inode, (void *)&filldata, 102400, &ofs, cli_ls_xfs_filldir);
                if (r != 0) {
                    printf("Not a directory\n");
                }
            } else {
                printf("No such directory\n");
            }
        }
        else if (strncmp(line, "cat ", 4) == 0) {
            strcpy(newpath, path);
            strcat(newpath, line+4);
            r = find_path(mp, newpath, &inode);
            if (r)
                printf("File not found\n");
            else if (xfs_is_regular(inode)) {
                //TODO: check if it is a file
                r = 10;
                offset = 0;
                while (r) {
                    r = xfs_readfile(inode, buffer, offset, BUFSIZE, NULL);
                    if (r) {
                        write(1, buffer, r);
                        offset += r;
                    }
                }
            } else if (xfs_is_link(inode)) {
                r = 10;
                offset = 0;
                while (r) {
                    r = xfs_readlink(inode, buffer, offset, BUFSIZE, NULL);
                    if (r) {
                        write(1, buffer, r);
                        offset += r;
                    }
                }
            } else {
                printf("Not a regular file\n");
            }
        }
        else if (strncmp(line, "get ", 4) == 0) {
            strcpy(newpath, path);
            strcat(newpath, line+4);
            r = find_path(mp, newpath, &inode);
            if ((!r) && (xfs_is_regular(inode))) {
                //TODO: check if it is a file
                r = 10;
                offset = 0;
                fd = open(line+4, O_WRONLY|O_CREAT, 0660);
                if (fd < 0) {
                    printf("Failed to open local file\n");
                } else {
                    while (r) {
                        r = xfs_readfile(inode, buffer, offset, BUFSIZE, NULL);
                        if (r) {
                            write(fd, buffer, r);
                            offset += r;
                        }
                    }
                    close(fd);
                    printf("Retrieved %ld bytes\n", offset);
                }
            } else {
                if (r) 
                    printf("File not found\n");
                else
                    printf("Not a regular file\n");
            }
        }
        else if (strcmp(line, "exit") == 0) {
            libxfs_umount(mp);
            return 0;
        }
        else if (strcmp(line, "pwd") == 0) {
            printf("%s\n", path);
        } else {
            printf("Unknown command\n");
        }
        free(line);
        if (inode) {
            libxfs_iput(inode, 0);
        }
    }
    libxfs_umount(mp);
    return 0;
}