Exemplo n.º 1
0
/*
 * ex_edit --	:e[dit][!] [+cmd] [file]
 *		:ex[!] [+cmd] [file]
 *		:vi[sual][!] [+cmd] [file]
 *
 * Edit a file; if none specified, re-edit the current file.  The third
 * form of the command can only be executed while in vi mode.  See the
 * hack in ex.c:ex_cmd().
 *
 * !!!
 * Historic vi didn't permit the '+' command form without specifying
 * a file name as well.  This seems unreasonable, so we support it
 * regardless.
 *
 * PUBLIC: int ex_edit __P((SCR *, EXCMD *));
 */
int
ex_edit(SCR *sp, EXCMD *cmdp)
{
	FREF *frp;
	int attach, setalt;
	const char *np;
	size_t nlen;

	switch (cmdp->argc) {
	case 0:
		/*
		 * If the name has been changed, we edit that file, not the
		 * original name.  If the user was editing a temporary file
		 * (or wasn't editing any file), create another one.  The
		 * reason for not reusing temporary files is that there is
		 * special exit processing of them, and reuse is tricky.
		 */
		frp = sp->frp;
		if (sp->ep == NULL || F_ISSET(frp, FR_TMPFILE)) {
			if ((frp = file_add(sp, NULL)) == NULL)
				return (1);
			attach = 0;
		} else
			attach = 1;
		setalt = 0;
		break;
	case 1:
		INT2CHAR(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len + 1, 
			 np, nlen);
		if ((frp = file_add(sp, np)) == NULL)
			return (1);
		attach = 0;
		setalt = 1;
		set_alt_name(sp, np);
		break;
	default:
		abort();
	}

	if (F_ISSET(cmdp, E_NEWSCREEN) || cmdp->cmd == &cmds[C_VSPLIT])
		return (ex_N_edit(sp, cmdp, frp, attach));

	/*
	 * Check for modifications.
	 *
	 * !!!
	 * Contrary to POSIX 1003.2-1992, autowrite did not affect :edit.
	 */
	if (file_m2(sp, FL_ISSET(cmdp->iflags, E_C_FORCE)))
		return (1);

	/* Switch files. */
	if (file_init(sp, frp, NULL, (setalt ? FS_SETALT : 0) |
	    (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0)))
		return (1);

	F_SET(sp, SC_FSWITCH);
	return (0);
}
Exemplo n.º 2
0
/*
 * ex_tag_nswitch --
 *	Switch context to the specified TAG.
 *
 * PUBLIC: int ex_tag_nswitch __P((SCR *, TAG *, int));
 */
int
ex_tag_nswitch(SCR *sp, TAG *tp, int force)
{
	/* Get a file structure. */
	if (tp->frp == NULL && (tp->frp = file_add(sp, tp->fname)) == NULL)
		return (1);

	/* If not changing files, return, we're done. */
	if (tp->frp == sp->frp)
		return (0);

	/* Check for permission to leave. */
	if (file_m1(sp, force, FS_ALL | FS_POSSIBLE))
		return (1);

	/* Initialize the new file. */
	if (file_init(sp, tp->frp, NULL, FS_SETALT))
		return (1);

	/* Display tags in the center of the screen. */
	F_CLR(sp, SC_SCR_TOP);
	F_SET(sp, SC_SCR_CENTER);

	/* Switch. */
	F_SET(sp, SC_FSWITCH);
	return (0);
}
Exemplo n.º 3
0
void
extract_files(struct tailq *queue, char *infile)
{
    char html_fname[MAX_FILENAME];
    char *file;
    int newLineIndex = 0, length = 0;
    unsigned long fileLen;
    
    file = mmap_file(infile);
    
    if (!file)
        return;
    
    fileLen = strlen(file);
    
    // Read each line into the queue
    for (int i = 0; i<fileLen+1; i++) {
        if (file[i] == '\n' || (i > 0 && file[i] == '\0' && file[i-1] != '\n')) {
            length = i-newLineIndex;
            strncpy(html_fname, file+newLineIndex, length);
            html_fname[length] = '\0';
            file_add(queue, html_fname);
            newLineIndex = i+1;
        }
    }
}
Exemplo n.º 4
0
int
main(int argc, char **argv)
{
    char infile[MAX_FILENAME];
    struct tailq        queue;
    struct tailq_node   *node;
    
    if (argc == 1) {
        file_add(&queue, "index.html");
    } else if (argc == 2) {
        strncpy(infile, argv[1], MAX_FILENAME-1);
        extract_files(&queue, infile);
    } else {
        printf("usage: ./cr [in file]\n");
        exit(-1);
    }
    
    node = queue.head;
    for (int i = 0; node; i++) {
        if (!populate_ref(&queue, node))
            tailq_remove(&queue, node);
        node = node->next;
    }
    print_results(&queue);
    
    getchar();
    printf("Bye!\n");
    
    return 0;
}
Exemplo n.º 5
0
Arquivo: main.c Projeto: lichray/nvi2
/*
 * editor --
 *	Main editor routine.
 *
 * PUBLIC: int editor(GS *, int, char *[]);
 */
int
editor(GS *gp, int argc, char *argv[])
{
	extern int optind;
	extern char *optarg;
	const char *p;
	EVENT ev;
	FREF *frp;
	SCR *sp;
	size_t len;
	u_int flags;
	int ch, flagchk, lflag, secure, startup, readonly, rval, silent;
	char *tag_f, *wsizearg, path[256];
	CHAR_T *w;
	size_t wlen;

	/* Initialize the busy routine, if not defined by the screen. */
	if (gp->scr_busy == NULL)
		gp->scr_busy = vs_busy;
	/* Initialize the message routine, if not defined by the screen. */
	if (gp->scr_msg == NULL)
		gp->scr_msg = vs_msg;
	gp->catd = (nl_catd)-1;

	/* Common global structure initialization. */
	TAILQ_INIT(gp->dq);
	TAILQ_INIT(gp->hq);
	SLIST_INIT(gp->ecq);
	SLIST_INSERT_HEAD(gp->ecq, &gp->excmd, q);
	gp->noprint = DEFAULT_NOPRINT;

	/* Structures shared by screens so stored in the GS structure. */
	TAILQ_INIT(gp->frefq);
	TAILQ_INIT(gp->dcb_store.textq);
	SLIST_INIT(gp->cutq);
	SLIST_INIT(gp->seqq);

	/* Set initial screen type and mode based on the program name. */
	readonly = 0;
	if (!strcmp(getprogname(), "ex") || !strcmp(getprogname(), "nex"))
		LF_INIT(SC_EX);
	else {
		/* Nview, view are readonly. */
		if (!strcmp(getprogname(), "nview") ||
		    !strcmp(getprogname(), "view"))
			readonly = 1;
		
		/* Vi is the default. */
		LF_INIT(SC_VI);
	}

	/* Convert old-style arguments into new-style ones. */
	if (v_obsolete(argv))
		return (1);

	/* Parse the arguments. */
	flagchk = '\0';
	tag_f = wsizearg = NULL;
	lflag = secure = silent = 0;
	startup = 1;

	/* Set the file snapshot flag. */
	F_SET(gp, G_SNAPSHOT);

#ifdef DEBUG
	while ((ch = getopt(argc, argv, "c:D:eFlRrSsT:t:vw:")) != EOF)
#else
	while ((ch = getopt(argc, argv, "c:eFlRrSst:vw:")) != EOF)
#endif
		switch (ch) {
		case 'c':		/* Run the command. */
			/*
			 * XXX
			 * We should support multiple -c options.
			 */
			if (gp->c_option != NULL) {
				warnx("only one -c command may be specified.");
				return (1);
			}
			gp->c_option = optarg;
			break;
#ifdef DEBUG
		case 'D':
			switch (optarg[0]) {
			case 's':
				startup = 0;
				break;
			case 'w':
				attach(gp);
				break;
			default:
				warnx("usage: -D requires s or w argument.");
				return (1);
			}
			break;
#endif
		case 'e':		/* Ex mode. */
			LF_CLR(SC_VI);
			LF_SET(SC_EX);
			break;
		case 'F':		/* No snapshot. */
			F_CLR(gp, G_SNAPSHOT);
			break;
		case 'l':		/* Set lisp, showmatch options. */
			lflag = 1;
			break;
		case 'R':		/* Readonly. */
			readonly = 1;
			break;
		case 'r':		/* Recover. */
			if (flagchk == 't') {
				warnx("only one of -r and -t may be specified.");
				return (1);
			}
			flagchk = 'r';
			break;
		case 'S':
			secure = 1;
			break;
		case 's':
			silent = 1;
			break;
#ifdef DEBUG
		case 'T':		/* Trace. */
			if ((gp->tracefp = fopen(optarg, "w")) == NULL) {
				warn("%s", optarg);
				goto err;
			}
			(void)fprintf(gp->tracefp,
			    "\n===\ntrace: open %s\n", optarg);
			break;
#endif
		case 't':		/* Tag. */
			if (flagchk == 'r') {
				warnx("only one of -r and -t may be specified.");
				return (1);
			}
			if (flagchk == 't') {
				warnx("only one tag file may be specified.");
				return (1);
			}
			flagchk = 't';
			tag_f = optarg;
			break;
		case 'v':		/* Vi mode. */
			LF_CLR(SC_EX);
			LF_SET(SC_VI);
			break;
		case 'w':
			wsizearg = optarg;
			break;
		case '?':
		default:
			(void)gp->scr_usage();
			return (1);
		}
	argc -= optind;
	argv += optind;

	/*
	 * -s option is only meaningful to ex.
	 *
	 * If not reading from a terminal, it's like -s was specified.
	 */
	if (silent && !LF_ISSET(SC_EX)) {
		warnx("-s option is only applicable to ex.");
		goto err;
	}
	if (LF_ISSET(SC_EX) && F_ISSET(gp, G_SCRIPTED))
		silent = 1;

	/*
	 * Build and initialize the first/current screen.  This is a bit
	 * tricky.  If an error is returned, we may or may not have a
	 * screen structure.  If we have a screen structure, put it on a
	 * display queue so that the error messages get displayed.
	 *
	 * !!!
	 * Everything we do until we go interactive is done in ex mode.
	 */
	if (screen_init(gp, NULL, &sp)) {
		if (sp != NULL)
			TAILQ_INSERT_HEAD(gp->dq, sp, q);
		goto err;
	}
	F_SET(sp, SC_EX);
	TAILQ_INSERT_HEAD(gp->dq, sp, q);

	if (v_key_init(sp))		/* Special key initialization. */
		goto err;

	{ int oargs[5], *oargp = oargs;
	if (lflag) {			/* Command-line options. */
		*oargp++ = O_LISP;
		*oargp++ = O_SHOWMATCH;
	}
	if (readonly)
		*oargp++ = O_READONLY;
	if (secure)
		*oargp++ = O_SECURE;
	*oargp = -1;			/* Options initialization. */
	if (opts_init(sp, oargs))
		goto err;
	}
	if (wsizearg != NULL) {
		ARGS *av[2], a, b;
		(void)snprintf(path, sizeof(path), "window=%s", wsizearg);
		a.bp = (CHAR_T *)path;
		a.len = strlen(path);
		b.bp = NULL;
		b.len = 0;
		av[0] = &a;
		av[1] = &b;
		(void)opts_set(sp, av, NULL);
	}
	if (silent) {			/* Ex batch mode option values. */
		O_CLR(sp, O_AUTOPRINT);
		O_CLR(sp, O_PROMPT);
		O_CLR(sp, O_VERBOSE);
		O_CLR(sp, O_WARN);
		F_SET(sp, SC_EX_SILENT);
	}

	sp->rows = O_VAL(sp, O_LINES);	/* Make ex formatting work. */
	sp->cols = O_VAL(sp, O_COLUMNS);

	if (!silent && startup) {	/* Read EXINIT, exrc files. */
		if (ex_exrc(sp))
			goto err;
		if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) {
			if (screen_end(sp))
				goto err;
			goto done;
		}
	}

	/*
	 * List recovery files if -r specified without file arguments.
	 * Note, options must be initialized and startup information
	 * read before doing this.
	 */
	if (flagchk == 'r' && argv[0] == NULL) {
		if (rcv_list(sp))
			goto err;
		if (screen_end(sp))
			goto err;
		goto done;
	}

	/*
	 * !!!
	 * Initialize the default ^D, ^U scrolling value here, after the
	 * user has had every opportunity to set the window option.
	 *
	 * It's historic practice that changing the value of the window
	 * option did not alter the default scrolling value, only giving
	 * a count to ^D/^U did that.
	 */
	sp->defscroll = (O_VAL(sp, O_WINDOW) + 1) / 2;

	/*
	 * If we don't have a command-line option, switch into the right
	 * editor now, so that we position default files correctly, and
	 * so that any tags file file-already-locked messages are in the
	 * vi screen, not the ex screen.
	 *
	 * XXX
	 * If we have a command-line option, the error message can end
	 * up in the wrong place, but I think that the combination is
	 * unlikely.
	 */
	if (gp->c_option == NULL) {
		F_CLR(sp, SC_EX | SC_VI);
		F_SET(sp, LF_ISSET(SC_EX | SC_VI));
	}

	/* Open a tag file if specified. */
	if (tag_f != NULL) {
		CHAR2INT(sp, tag_f, strlen(tag_f) + 1, w, wlen);
		if (ex_tag_first(sp, w))
			goto err;
	}

	/*
	 * Append any remaining arguments as file names.  Files are recovery
	 * files if -r specified.  If the tag option or ex startup commands
	 * loaded a file, then any file arguments are going to come after it.
	 */
	if (*argv != NULL) {
		if (sp->frp != NULL) {
			/* Cheat -- we know we have an extra argv slot. */
			*--argv = strdup(sp->frp->name);
			if (*argv == NULL) {
				warn(NULL);
				goto err;
			}
		}
		sp->argv = sp->cargv = argv;
		F_SET(sp, SC_ARGNOFREE);
		if (flagchk == 'r')
			F_SET(sp, SC_ARGRECOVER);
	}

	/*
	 * If the ex startup commands and or/the tag option haven't already
	 * created a file, create one.  If no command-line files were given,
	 * use a temporary file.
	 */
	if (sp->frp == NULL) {
		if (sp->argv == NULL) {
			if ((frp = file_add(sp, NULL)) == NULL)
				goto err;
		} else  {
			if ((frp = file_add(sp, sp->argv[0])) == NULL)
				goto err;
			if (F_ISSET(sp, SC_ARGRECOVER))
				F_SET(frp, FR_RECOVER);
		}

		if (file_init(sp, frp, NULL, 0))
			goto err;
		if (EXCMD_RUNNING(gp)) {
			(void)ex_cmd(sp);
			if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) {
				if (screen_end(sp))
					goto err;
				goto done;
			}
		}
	}

	/*
	 * Check to see if we need to wait for ex.  If SC_SCR_EX is set, ex
	 * was forced to initialize the screen during startup.  We'd like to
	 * wait for a single character from the user, but we can't because
	 * we're not in raw mode.  We can't switch to raw mode because the
	 * vi initialization will switch to xterm's alternate screen, causing
	 * us to lose the messages we're pausing to make sure the user read.
	 * So, wait for a complete line.  
	 */
	if (F_ISSET(sp, SC_SCR_EX)) {
		p = msg_cmsg(sp, CMSG_CONT_R, &len);
		(void)write(STDOUT_FILENO, p, len);
		for (;;) {
			if (v_event_get(sp, &ev, 0, 0))
				goto err;
			if (ev.e_event == E_INTERRUPT ||
			    (ev.e_event == E_CHARACTER &&
			     (ev.e_value == K_CR || ev.e_value == K_NL)))
				break;
			(void)gp->scr_bell(sp);
		}
	}

	/* Switch into the right editor, regardless. */
	F_CLR(sp, SC_EX | SC_VI);
	F_SET(sp, LF_ISSET(SC_EX | SC_VI) | SC_STATUS_CNT);

	/*
	 * Main edit loop.  Vi handles split screens itself, we only return
	 * here when switching editor modes or restarting the screen.
	 */
	while (sp != NULL)
		if (F_ISSET(sp, SC_EX) ? ex(&sp) : vi(&sp))
			goto err;

done:	rval = 0;
	if (0)
err:		rval = 1;

	/* Clean out the global structure. */
	v_end(gp);

	return (rval);
}
Exemplo n.º 6
0
void vm_process(VM *vm) {
  int a, b, opcode;
  opcode = vm->image[vm->ip];

  switch(opcode) {
    case VM_NOP:
         break;
    case VM_LIT:
         vm->sp++;
         vm->ip++;
         TOS = vm->image[vm->ip];
         break;
    case VM_DUP:
         vm->sp++;
         vm->data[vm->sp] = NOS;
         break;
    case VM_DROP:
         DROP
         break;
    case VM_SWAP:
         a = TOS;
         TOS = NOS;
         NOS = a;
         break;
    case VM_PUSH:
         vm->rsp++;
         TORS = TOS;
         DROP
         break;
    case VM_POP:
         vm->sp++;
         TOS = TORS;
         vm->rsp--;
         break;
    case VM_CALL:
         vm->ip++;
         vm->rsp++;
         TORS = vm->ip;
         vm->ip = vm->image[vm->ip] - 1;
         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
    case VM_JUMP:
         vm->ip++;
         vm->ip = vm->image[vm->ip] - 1;
         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
    case VM_RETURN:
         vm->ip = TORS;
         vm->rsp--;
         break;
    case VM_GT_JUMP:
         vm->ip++;
         if(NOS > TOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_LT_JUMP:
         vm->ip++;
         if(NOS < TOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_NE_JUMP:
         vm->ip++;
         if(TOS != NOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_EQ_JUMP:
         vm->ip++;
         if(TOS == NOS)
           vm->ip = vm->image[vm->ip] - 1;
         DROP DROP
         break;
    case VM_FETCH:
         TOS = vm->image[TOS];
         break;
    case VM_STORE:
         vm->image[TOS] = NOS;
         DROP DROP
         break;
    case VM_ADD:
         NOS += TOS;
         DROP
         break;
    case VM_SUB:
         NOS -= TOS;
         DROP
         break;
    case VM_MUL:
         NOS *= TOS;
         DROP
         break;
    case VM_DIVMOD:
         a = TOS;
         b = NOS;
         TOS = b / a;
         NOS = b % a;
         break;
    case VM_AND:
         a = TOS;
         b = NOS;
         DROP
         TOS = a & b;
         break;
    case VM_OR:
         a = TOS;
         b = NOS;
         DROP
         TOS = a | b;
         break;
    case VM_XOR:
         a = TOS;
         b = NOS;
         DROP
         TOS = a ^ b;
         break;
    case VM_SHL:
         a = TOS;
         b = NOS;
         DROP
         TOS = b << a;
         break;
    case VM_SHR:
         a = TOS;
         b = NOS;
         DROP
         TOS = b >>= a;
         break;
    case VM_ZERO_EXIT:
         if (TOS == 0) {
           DROP
           vm->ip = TORS;
           vm->rsp--;
         }
         break;
    case VM_INC:
         TOS += 1;
         break;
    case VM_DEC:
         TOS -= 1;
         break;
    case VM_IN:
         a = TOS;
         TOS = vm->ports[a];
         vm->ports[a] = 0;
         break;
    case VM_OUT:
         vm->ports[0] = 0;
         vm->ports[TOS] = NOS;
         DROP DROP
         break;
    case VM_WAIT:
         if (vm->ports[0] == 1)
           break;

         /* Input */
         if (vm->ports[0] == 0 && vm->ports[1] == 1) {
           vm->ports[1] = dev_getch();
           vm->ports[0] = 1;
         }

         /* Output (character generator) */
         if (vm->ports[2] == 1) {
           dev_putch(TOS); DROP
           vm->ports[2] = 0;
           vm->ports[0] = 1;
         }

         if (vm->ports[4] != 0) {
           vm->ports[0] = 1;
           switch (vm->ports[4]) {
             case  1: vm_save_image(vm, vm->filename);
                      vm->ports[4] = 0;
                      break;
             case  2: file_add(vm);
                      vm->ports[4] = 0;
                      break;
             case -1: vm->ports[4] = file_handle(vm);
                      break;
             case -2: vm->ports[4] = file_readc(vm);
                      break;
             case -3: vm->ports[4] = file_writec(vm);
                      break;
             case -4: vm->ports[4] = file_closehandle(vm);
                      break;
             case -5: vm->ports[4] = file_getpos(vm);
                      break;
             case -6: vm->ports[4] = file_seek(vm);
                      break;
             case -7: vm->ports[4] = file_size(vm);
                      break;
             default: vm->ports[4] = 0;
           }
         }

         /* Capabilities */
         if (vm->ports[5] != 0) {
           vm->ports[0] = 1;
           switch(vm->ports[5]) {
             case -1:  vm->ports[5] = IMAGE_SIZE;
                       break;
             case -2:  vm->ports[5] = 0;
                       break;
             case -3:  vm->ports[5] = 0;
                       break;
             case -4:  vm->ports[5] = 0;
                       break;
             case -5:  vm->ports[5] = vm->sp;
                       break;
             case -6:  vm->ports[5] = vm->rsp;
                       break;
             case -7:  vm->ports[5] = 0;
                       break;
             case -8:  vm->ports[5] = time(NULL);
                       break;
             case -9:  vm->ports[5] = 0;
                       vm->ip = IMAGE_SIZE;
                       break;
             default:  vm->ports[5] = 0;
           }
         }

         if (vm->ports[8] != 0) {
           vm->ports[0] = 1;
           switch (vm->ports[8]) {
             case -1: rsocket(vm);
                      vm->ports[8] = 0;
                      break;
             case -2: rbind(vm);
                      vm->ports[8] = 0;
                      break;
             case -3: rlisten(vm);
                      vm->ports[8] = 0;
                      break;
             case -4: raccept(vm);
                      vm->ports[8] = 0;
                      break;
             case -5: rclose(vm);
                      vm->ports[8] = 0;
                      break;
             case -6: rsend(vm);
                      vm->ports[8] = 0;
                      break;
             case -7: rrecv(vm);
                      vm->ports[8] = 0;
                      break;
             case -8: rconnect(vm);
                      vm->ports[8] = 0;
                      break;
             default: vm->ports[8] = 0;
           }
           vm->ports[8] = 0;
         }
         break;
    default:
         vm->rsp++;
         TORS = vm->ip;
         vm->ip = vm->image[vm->ip] - 1;

         if (vm->ip < 0)
           vm->ip = IMAGE_SIZE;
         else {
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
           if (vm->image[vm->ip+1] == 0)
             vm->ip++;
         }
         break;
  }
  vm->ports[3] = 1;
}
Exemplo n.º 7
0
/*
 * ex_read --	:read [file]
 *		:read [!cmd]
 *	Read from a file or utility.
 *
 * !!!
 * Historical vi wouldn't undo a filter read, for no apparent reason.
 *
 * PUBLIC: int ex_read __P((SCR *, EXCMD *));
 */
int
ex_read(SCR *sp, EXCMD *cmdp)
{
	enum { R_ARG, R_EXPANDARG, R_FILTER } which;
	struct stat sb;
	CHAR_T *arg;
	char *name;
	size_t nlen;
	EX_PRIVATE *exp;
	FILE *fp;
	FREF *frp;
	GS *gp;
	MARK rm;
	db_recno_t nlines;
	size_t arglen;
	int argc, rval;
	char *p;
	char *np;

	gp = sp->gp;

	/*
	 * 0 args: read the current pathname.
	 * 1 args: check for "read !arg".
	 */
	switch (cmdp->argc) {
	case 0:
		which = R_ARG;
		break;
	case 1:
		arg = cmdp->argv[0]->bp;
		arglen = cmdp->argv[0]->len;
		if (*arg == '!') {
			++arg;
			--arglen;
			which = R_FILTER;

			/* Secure means no shell access. */
			if (O_ISSET(sp, O_SECURE)) {
				ex_wemsg(sp, cmdp->cmd->name, EXM_SECURE_F);
				return (1);
			}
		} else
			which = R_EXPANDARG;
		break;
	default:
		abort();
		/* NOTREACHED */
	}

	/* Load a temporary file if no file being edited. */
	if (sp->ep == NULL) {
		if ((frp = file_add(sp, NULL)) == NULL)
			return (1);
		if (file_init(sp, frp, NULL, 0))
			return (1);
	}

	switch (which) {
	case R_FILTER:
		/*
		 * File name and bang expand the user's argument.  If
		 * we don't get an additional argument, it's illegal.
		 */
		argc = cmdp->argc;
		if (argv_exp1(sp, cmdp, arg, arglen, 1))
			return (1);
		if (argc == cmdp->argc) {
			ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE);
			return (1);
		}
		argc = cmdp->argc - 1;

		/* Set the last bang command. */
		exp = EXP(sp);
		if (exp->lastbcomm != NULL)
			free(exp->lastbcomm);
		if ((exp->lastbcomm =
		    v_wstrdup(sp, cmdp->argv[argc]->bp,
				cmdp->argv[argc]->len)) == NULL) {
			msgq(sp, M_SYSERR, NULL);
			return (1);
		}

		/*
		 * Vi redisplayed the user's argument if it changed, ex
		 * always displayed a !, plus the user's argument if it
		 * changed.
		 */
		if (F_ISSET(sp, SC_VI)) {
			if (F_ISSET(cmdp, E_MODIFY))
				(void)vs_update(sp, "!", cmdp->argv[argc]->bp);
		} else {
			if (F_ISSET(cmdp, E_MODIFY))
				(void)ex_printf(sp,
				    "!%s\n", cmdp->argv[argc]->bp);
			else
				(void)ex_puts(sp, "!\n");
			(void)ex_fflush(sp);
		}

		/*
		 * Historically, filter reads as the first ex command didn't
		 * wait for the user. If SC_SCR_EXWROTE not already set, set
		 * the don't-wait flag.
		 */
		if (!F_ISSET(sp, SC_SCR_EXWROTE))
			F_SET(sp, SC_EX_WAIT_NO);

		/*
		 * Switch into ex canonical mode.  The reason to restore the
		 * original terminal modes for read filters is so that users
		 * can do things like ":r! cat /dev/tty".
		 *
		 * !!!
		 * We do not output an extra <newline>, so that we don't touch
		 * the screen on a normal read.
		 */
		if (F_ISSET(sp, SC_VI)) {
			if (gp->scr_screen(sp, SC_EX)) {
				ex_wemsg(sp, cmdp->cmd->name, EXM_NOCANON_F);
				return (1);
			}
			/*
			 * !!!
			 * Historically, the read command doesn't switch to
			 * the alternate X11 xterm screen, if doing a filter
			 * read -- don't set SA_ALTERNATE.
			 */
			F_SET(sp, SC_SCR_EX | SC_SCR_EXWROTE);
		}

		if (ex_filter(sp, cmdp, &cmdp->addr1,
		    NULL, &rm, cmdp->argv[argc]->bp, FILTER_READ))
			return (1);

		/* The filter version of read set the autoprint flag. */
		F_SET(cmdp, E_AUTOPRINT);

		/*
		 * If in vi mode, move to the first nonblank.  Might have
		 * switched into ex mode, so saved the original SC_VI value.
		 */
		sp->lno = rm.lno;
		if (F_ISSET(sp, SC_VI)) {
			sp->cno = 0;
			(void)nonblank(sp, sp->lno, &sp->cno);
		}
		return (0);
	case R_ARG:
		name = sp->frp->name;
		break;
	case R_EXPANDARG:
		if (argv_exp2(sp, cmdp, arg, arglen))
			return (1);
		/*
		 *  0 args: impossible.
		 *  1 args: impossible (I hope).
		 *  2 args: read it.
		 * >2 args: object, too many args.
		 *
		 * The 1 args case depends on the argv_sexp() function refusing
		 * to return success without at least one non-blank character.
		 */
		switch (cmdp->argc) {
		case 0:
		case 1:
			abort();
			/* NOTREACHED */
		case 2:
			INT2CHAR(sp, cmdp->argv[1]->bp, cmdp->argv[1]->len + 1, 
				 name, nlen);
			/*
			 * !!!
			 * Historically, the read and write commands renamed
			 * "unnamed" files, or, if the file had a name, set
			 * the alternate file name.
			 */
			if (F_ISSET(sp->frp, FR_TMPFILE) &&
			    !F_ISSET(sp->frp, FR_EXNAMED)) {
				if ((p = strdup(name)) != NULL) {
					free(sp->frp->name);
					sp->frp->name = p;
				}
				/*
				 * The file has a real name, it's no longer a
				 * temporary, clear the temporary file flags.
				 */
				F_CLR(sp->frp, FR_TMPEXIT | FR_TMPFILE);
				F_SET(sp->frp, FR_NAMECHANGE | FR_EXNAMED);

				/* Notify the screen. */
				(void)sp->gp->scr_rename(sp, sp->frp->name, 1);
				name = sp->frp->name;
			} else {
				set_alt_name(sp, name);
				name = sp->alt_name;
			}
			break;
		default:
			ex_wemsg(sp, cmdp->argv[0]->bp, EXM_FILECOUNT);
			return (1);
		
		}
		break;
	}

	/*
	 * !!!
	 * Historically, vi did not permit reads from non-regular files, nor
	 * did it distinguish between "read !" and "read!", so there was no
	 * way to "force" it.  We permit reading from named pipes too, since
	 * they didn't exist when the original implementation of vi was done
	 * and they seem a reasonable addition.
	 */
	if ((fp = fopen(name, "r")) == NULL || fstat(fileno(fp), &sb)) {
		msgq_str(sp, M_SYSERR, name, "%s");
		return (1);
	}
	if (!S_ISFIFO(sb.st_mode) && !S_ISREG(sb.st_mode)) {
		(void)fclose(fp);
		msgq(sp, M_ERR,
		    "145|Only regular files and named pipes may be read");
		return (1);
	}

	/* Try and get a lock. */
	if (file_lock(sp, NULL, NULL, fileno(fp), 0) == LOCK_UNAVAIL)
		msgq(sp, M_ERR, "146|%s: read lock was unavailable", name);

	rval = ex_readfp(sp, name, fp, &cmdp->addr1, &nlines, 0);

	/*
	 * In vi, set the cursor to the first line read in, if anything read
	 * in, otherwise, the address.  (Historic vi set it to the line after
	 * the address regardless, but since that line may not exist we don't
	 * bother.)
	 *
	 * In ex, set the cursor to the last line read in, if anything read in,
	 * otherwise, the address.
	 */
	if (F_ISSET(sp, SC_VI)) {
		sp->lno = cmdp->addr1.lno;
		if (nlines)
			++sp->lno;
	} else
		sp->lno = cmdp->addr1.lno + nlines;
	return (rval);
}
Exemplo n.º 8
0
/*
 * ex_next -- :next [+cmd] [files]
 *	Edit the next file, optionally setting the list of files.
 *
 * !!!
 * The :next command behaved differently from the :rewind command in
 * historic vi.  See nvi/docs/autowrite for details, but the basic
 * idea was that it ignored the force flag if the autowrite flag was
 * set.  This implementation handles them all identically.
 *
 * PUBLIC: int ex_next __P((SCR *, EXCMD *));
 */
int
ex_next(SCR *sp, EXCMD *cmdp)
{
	ARGS **argv;
	FREF *frp;
	int noargs;
	char **ap;
	const CHAR_T *wp;
	size_t wlen;
	const char *np;
	size_t nlen;

	/* Check for file to move to. */
	if (cmdp->argc == 0 && (sp->cargv == NULL || sp->cargv[1] == NULL)) {
		msgq(sp, M_ERR, "111|No more files to edit");
		return (1);
	}

	if (F_ISSET(cmdp, E_NEWSCREEN)) {
		/* By default, edit the next file in the old argument list. */
		if (cmdp->argc == 0) {
			CHAR2INT(sp, sp->cargv[1], strlen(sp->cargv[1]) + 1,
					   wp, wlen);
			if (argv_exp0(sp, cmdp, wp, wlen - 1))
				return (1);
			return (ex_edit(sp, cmdp));
		}
		return (ex_N_next(sp, cmdp));
	}

	/* Check modification. */
	if (file_m1(sp,
	    FL_ISSET(cmdp->iflags, E_C_FORCE), FS_ALL | FS_POSSIBLE))
		return (1);

	/* Any arguments are a replacement file list. */
	if (cmdp->argc) {
		/* Free the current list. */
		if (!F_ISSET(sp, SC_ARGNOFREE) && sp->argv != NULL) {
			for (ap = sp->argv; *ap != NULL; ++ap)
				free(*ap);
			free(sp->argv);
		}
		F_CLR(sp, SC_ARGNOFREE | SC_ARGRECOVER);
		sp->cargv = NULL;

		/* Create a new list. */
		CALLOC_RET(sp,
		    sp->argv, char **, cmdp->argc + 1, sizeof(char *));
		for (ap = sp->argv,
		    argv = cmdp->argv; argv[0]->len != 0; ++ap, ++argv) {
			INT2CHAR(sp, argv[0]->bp, argv[0]->len, np, nlen);
			if ((*ap = v_strdup(sp, np, nlen)) == NULL)
				return (1);
		}
		*ap = NULL;

		/* Switch to the first file. */
		sp->cargv = sp->argv;
		if ((frp = file_add(sp, *sp->cargv)) == NULL)
			return (1);
		noargs = 0;

		/* Display a file count with the welcome message. */
		F_SET(sp, SC_STATUS_CNT);
	} else {
		if ((frp = file_add(sp, sp->cargv[1])) == NULL)
Exemplo n.º 9
0
int main(int argc, char **argv)
{
    DOS_FS fs;
    int salvage_files, verify, c;
    uint32_t free_clusters = 0;

    memset(&fs, 0, sizeof(fs));
    salvage_files = verify = 0;
    rw = interactive = 1;
    check_atari();

    while ((c = getopt(argc, argv, "Aac:d:bflnprtu:vVwy")) != -1)
	switch (c) {
	case 'A':		/* toggle Atari format */
	    atari_format = !atari_format;
	    break;
	case 'a':
	case 'p':
	case 'y':
	    rw = 1;
	    interactive = 0;
	    salvage_files = 1;
	    break;
	case 'b':
	    rw = 0;
	    interactive = 0;
	    boot_only = 1;
	    break;
	case 'c':
	    set_dos_codepage(atoi(optarg));
	    break;
	case 'd':
	    file_add(optarg, fdt_drop);
	    break;
	case 'f':
	    salvage_files = 1;
	    break;
	case 'l':
	    list = 1;
	    break;
	case 'n':
	    rw = 0;
	    interactive = 0;
	    break;
	case 'r':
	    rw = 1;
	    interactive = 1;
	    break;
	case 't':
	    test = 1;
	    break;
	case 'u':
	    file_add(optarg, fdt_undelete);
	    break;
	case 'v':
	    verbose = 1;
	    break;
	case 'V':
	    verify = 1;
	    break;
	case 'w':
	    write_immed = 1;
	    break;
	default:
	    usage(argv[0]);
	}
    set_dos_codepage(-1);	/* set default codepage if none was given in command line */
    if ((test || write_immed) && !rw) {
	fprintf(stderr, "-t and -w can not be used in read only mode\n");
	exit(2);
    }
    if (optind != argc - 1)
	usage(argv[0]);

    printf("fsck.fat " VERSION " (" VERSION_DATE ")\n");
    fs_open(argv[optind], rw);

    read_boot(&fs);
    if (boot_only)
	goto exit;

    if (verify)
	printf("Starting check/repair pass.\n");
    while (read_fat(&fs), scan_root(&fs))
	qfree(&mem_queue);
    if (test)
	fix_bad(&fs);
    if (salvage_files)
	reclaim_file(&fs);
    else
	reclaim_free(&fs);
    free_clusters = update_free(&fs);
    file_unused();
    qfree(&mem_queue);
    if (verify) {
	n_files = 0;
	printf("Starting verification pass.\n");
	read_fat(&fs);
	scan_root(&fs);
	reclaim_free(&fs);
	qfree(&mem_queue);
    }

exit:
    if (fs_changed()) {
	if (rw) {
	    if (interactive)
		rw = get_key("yn", "Perform changes ? (y/n)") == 'y';
	    else
		printf("Performing changes.\n");
	} else
	    printf("Leaving filesystem unchanged.\n");
    }

    if (!boot_only)
	printf("%s: %u files, %lu/%lu clusters\n", argv[optind],
	       n_files, (unsigned long)fs.clusters - free_clusters, (unsigned long)fs.clusters);

    return fs_close(rw) ? 1 : 0;
}
Exemplo n.º 10
0
Arquivo: file.c Projeto: nrhtr/genesis
cList *open_file(cStr * name, cStr * smode, Obj * obj)
{
    char mode[4];
    Int rw = 0;
    char *s = NULL;
    filec_t *fnew = file_new();
    struct stat sbuf;

    /* parse the mode first, if the string pointer is NULL, set it readable */
    if (smode != NULL) {
        s = smode->s;
        if (*s == '+') {
            rw = 1;
            fnew->f.readable = fnew->f.writable = 1;
            s++;
        }

        if (*s == '>') {
            s++;
            if (*s == '>') {
                s++;
                mode[0] = 'a';
            } else {
                mode[0] = 'w';
            }
            fnew->f.writable = 1;
        } else {
            if (*s == '<')
                s++;
            mode[0] = 'r';
            fnew->f.readable = 1;
        }

        /* here is where we branch from perl, '-' is used to specify it as
           a 'binary' file (i.e. use buffers not cold strings) */
        if (*s == '-') {
            s++;
            fnew->f.binary = 1;
        }

    } else {
        mode[0] = 'r';
        fnew->f.readable = 1;
    }

    /* most systems ignore this, some need it */
    mode[1] = 'b';

    if (rw) {
        mode[2] = '+';
        mode[3] = '\0';
    } else {
        mode[2] = '\0';
    }

    fnew->path = build_path(name->s, NULL, DISALLOW_DIR);
    if (fnew->path == NULL)
        return NULL;

    /* redundant, as build_path could have done this, but we
       have a special case which we need to handle differently */

    if (stat(fnew->path->s, &sbuf) == F_SUCCESS) {
        /* Patch #6 -- Bruce Mitchener */
        if (S_ISDIR(sbuf.st_mode)) {
            cthrow(directory_id, "\"%s\" is a directory.", fnew->path->s);
            file_discard(fnew, NULL);
            return NULL;
        }
    }

    fnew->fp = fopen(fnew->path->s, mode);

    if (fnew->fp == NULL) {
        if (GETERR() == ERR_NOMEM)
            panic("open_file(): %s", strerror(GETERR()));
        cthrow(file_id, "%s (%s)", strerror(GETERR()), name->s);
        file_discard(fnew, NULL);
        return NULL;
    }

    file_add(fnew);
    obj->file = fnew;
    fnew->objnum = obj->objnum;

    return statbuf_to_list(&sbuf);
}
Exemplo n.º 11
0
int main(int argc,char **argv)
{
    DOS_FS fs;
    int rw,salvage_files,verify,c;
	unsigned n_files_check=0, n_files_verify=0;
    unsigned long free_clusters;

    rw = salvage_files = verify = 0;
    interactive = 1;
    check_atari();

    while ((c = getopt(argc,argv,"Aad:flnprtu:vVwy")) != EOF)
	switch (c) {
	    case 'A': /* toggle Atari format */
	  	atari_format = !atari_format;
		break;
	    case 'a':
	    case 'p':
	    case 'y':
		rw = 1;
		interactive = 0;
		salvage_files = 1;
		break;
	    case 'd':
		file_add(optarg,fdt_drop);
		break;
	    case 'f':
		salvage_files = 1;
		break;
	    case 'l':
		list = 1;
		break;
	    case 'n':
		rw = 0;
		interactive = 0;
		break;
	    case 'r':
		rw = 1;
		interactive = 1;
		break;
	    case 't':
		test = 1;
		break;
	    case 'u':
		file_add(optarg,fdt_undelete);
		break;
	    case 'v':
		verbose = 1;
		printf("dosfsck " VERSION " (" VERSION_DATE ")\n");
		break;
	    case 'V':
		verify = 1;
		break;
	    case 'w':
		write_immed = 1;
		break;
	    default:
		usage(argv[0]);
	}
    if ((test || write_immed) && !rw) {
	fprintf(stderr,"-t and -w require -a or -r\n");
	exit(2);
    }
    if (optind != argc-1) usage(argv[0]);

    printf( "dosfsck " VERSION ", " VERSION_DATE ", FAT32, LFN\n" );
    fs_open(argv[optind],rw);
    read_boot(&fs);
    if (verify) printf("Starting check/repair pass.\n");
    while (read_fat(&fs), scan_root(&fs)) qfree(&mem_queue);
    if (test) fix_bad(&fs);
    if (salvage_files) reclaim_file(&fs);
    else reclaim_free(&fs);
    free_clusters = update_free(&fs);
    file_unused();
    qfree(&mem_queue);
	n_files_check = n_files;
    if (verify) {
		n_files = 0;
		printf("Starting verification pass.\n");
		read_fat(&fs);
		scan_root(&fs);
		reclaim_free(&fs);
		qfree(&mem_queue);
		n_files_verify = n_files;
    }

    if (fs_changed()) {
	if (rw) {
	    if (interactive)
		rw = get_key("yn","Perform changes ? (y/n)") == 'y';
	    else printf("Performing changes.\n");
	}
	else
	    printf("Leaving file system unchanged.\n");
    }

    printf( "%s: %u files, %lu/%lu clusters\n", argv[optind],
	    n_files, fs.clusters - free_clusters, fs.clusters );

    return fs_close(rw) ? 1 : 0;
}
Exemplo n.º 12
0
/* Open the file, load metadata and so on */
bg_db_file_t *
bg_db_file_create_from_object(bg_db_t * db, bg_db_object_t * obj, int scan_flags,
                              bg_db_scan_item_t * item,
                              int64_t scan_dir_id)
  {
  int i;
  bg_track_info_t * ti;
  bg_plugin_handle_t * h = NULL;
  bg_input_plugin_t * plugin = NULL;
  bg_db_file_t * file;
  bg_db_object_type_t type;
  
  gavl_time_t duration;
  
  bg_db_object_set_type(obj, BG_DB_OBJECT_FILE);

  file = (bg_db_file_t *)obj;
  file->path = item->path;
  item->path = NULL;

  file->mtime = item->mtime;
  file->scan_dir_id = scan_dir_id;
  
  bg_db_object_update_size(db, file, item->size);
  bg_db_object_set_label_nocpy(file, bg_db_path_to_label(file->path));
  
  /* Load all infos */  
  if(!bg_input_plugin_load(db->plugin_reg, file->path, NULL, &h, NULL, 0))
    goto fail;
  plugin = (bg_input_plugin_t *)h->plugin;
  
  /* Only one track supported */
  if(plugin->get_num_tracks && (plugin->get_num_tracks(h->priv) < 1))
    goto fail;

  ti = plugin->get_track_info(h->priv, 0);
  
  /* Detect file type */
  if((ti->num_audio_streams == 1) && !ti->num_video_streams)
    type = BG_DB_OBJECT_AUDIO_FILE;
  else if(ti->num_video_streams == 1)
    {
    if(!ti->num_audio_streams && (ti->num_video_streams == 1) &&
       (ti->video_streams[0].format.framerate_mode = GAVL_FRAMERATE_STILL))
      type = BG_DB_OBJECT_IMAGE_FILE;
    else
      type = BG_DB_OBJECT_VIDEO_FILE;
    }
  
  file->mimetype =
    gavl_strdup(gavl_metadata_get(&ti->metadata, GAVL_META_MIMETYPE));

  /* Check if we want to add this file */
  switch(type)
    {
    case BG_DB_OBJECT_AUDIO_FILE:
      if(!(scan_flags & BG_DB_SCAN_AUDIO))
        goto fail;
      break;
    case BG_DB_OBJECT_VIDEO_FILE:
      if(!(scan_flags & BG_DB_SCAN_VIDEO))
        goto fail;
      break;
    case BG_DB_OBJECT_IMAGE_FILE: // Images can also be movie poster and album covers
      break;
    default:
      break;
    }

  /* */
  
  if(plugin->set_track && !plugin->set_track(h->priv, 0))
    goto fail;
  
  /* Start everything */
  if(plugin->set_audio_stream)
    {
    for(i = 0; i < ti->num_audio_streams; i++)
      plugin->set_audio_stream(h->priv, i, BG_STREAM_ACTION_DECODE);
    }
  if(plugin->set_video_stream)
    {
    for(i = 0; i < ti->num_video_streams; i++)
      plugin->set_video_stream(h->priv, i, BG_STREAM_ACTION_DECODE);
    }
  if(plugin->set_text_stream)
    {
    for(i = 0; i < ti->num_text_streams; i++)
      plugin->set_text_stream(h->priv, i, BG_STREAM_ACTION_DECODE);
    }
  if(plugin->set_overlay_stream)
    {
    for(i = 0; i < ti->num_overlay_streams; i++)
      plugin->set_overlay_stream(h->priv, i, BG_STREAM_ACTION_DECODE);
    }
  if(plugin->start && !plugin->start(h->priv))
    goto fail;

  if(gavl_metadata_get_long(&ti->metadata, GAVL_META_APPROX_DURATION,
                             &duration))
    bg_db_object_update_duration(db, file, duration);
    
  
  /* Create derived type */
  switch(type)
    {
    case BG_DB_OBJECT_AUDIO_FILE:
      bg_db_audio_file_create(db, file, ti);
      break;
    case BG_DB_OBJECT_VIDEO_FILE:
      break;
    case BG_DB_OBJECT_IMAGE_FILE:
      bg_db_image_file_create_from_ti(db, file, ti);
      break;
    default:
      break;
    }
  
  fail:

  if(plugin)
    plugin->close(h->priv);

  if(h)
    bg_plugin_unref(h);

  file_add(db, file);
  return file; 
  }