/* exec_global: apply command list in the command buffer to the active lines in a range; return command status */ int exec_global(int interact, int gflag) { static char *ocmd = NULL; static int ocmdsz = 0; line_t *lp = NULL; int status; int n; char *cmd = NULL; if (!interact) { if (!strcmp(ibufp, "\n")) cmd = "p\n"; /* null cmd-list == `p' */ else if ((cmd = get_extended_line(&n, 0)) == NULL) return ERR; } clear_undo_stack(); while ((lp = next_active_node()) != NULL) { if ((current_addr = get_line_node_addr(lp)) < 0) return ERR; if (interact) { /* print current_addr; get a command in global syntax */ if (display_lines(current_addr, current_addr, gflag) < 0) return ERR; while ((n = get_tty_line()) > 0 && ibuf[n - 1] != '\n') clearerr(stdin); if (n < 0) return ERR; else if (n == 0) { seterrmsg("unexpected end-of-file"); return ERR; } else if (n == 1 && !strcmp(ibuf, "\n")) continue; else if (n == 2 && !strcmp(ibuf, "&\n")) { if (cmd == NULL) { seterrmsg("no previous command"); return ERR; } else cmd = ocmd; } else if ((cmd = get_extended_line(&n, 0)) == NULL) return ERR; else { REALLOC(ocmd, ocmdsz, n + 1, ERR); memcpy(ocmd, cmd, n + 1); cmd = ocmd; } } ibufp = cmd; for (; *ibufp;) if ((status = extract_addr_range()) < 0 || (status = exec_command()) < 0 || (status > 0 && (status = display_lines( current_addr, current_addr, status)) < 0)) return status; } return 0; }
/* apply command list in the command buffer to the active lines in a range; return false if error */ static bool exec_global( const char ** const ibufpp, const int gflags, const bool interactive ) { static char * buf = 0; static int bufsz = 0; const char * cmd = 0; if( !interactive ) { if( traditional() && !strcmp( *ibufpp, "\n" ) ) cmd = "p\n"; /* null cmd_list == 'p' */ else { if( !get_extended_line( ibufpp, 0, false ) ) return false; cmd = *ibufpp; } } clear_undo_stack(); while( true ) { const line_t * const lp = next_active_node(); if( !lp ) break; set_current_addr( get_line_node_addr( lp ) ); if( current_addr() < 0 ) return false; if( interactive ) { /* print current_addr; get a command in global syntax */ int len; if( !display_lines( current_addr(), current_addr(), gflags ) ) return false; do { *ibufpp = get_tty_line( &len ); } while( *ibufpp && len > 0 && (*ibufpp)[len-1] != '\n' ); if( !*ibufpp ) return false; if( len == 0 ) { set_error_msg( "Unexpected end-of-file" ); return false; } if( len == 1 && !strcmp( *ibufpp, "\n" ) ) continue; if( len == 2 && !strcmp( *ibufpp, "&\n" ) ) { if( !cmd ) { set_error_msg( "No previous command" ); return false; } } else { if( !get_extended_line( ibufpp, &len, false ) || !resize_buffer( &buf, &bufsz, len + 1 ) ) return false; memcpy( buf, *ibufpp, len + 1 ); cmd = buf; } } *ibufpp = cmd; while( **ibufpp ) if( exec_command( ibufpp, 0, true ) < 0 ) return false; } return true; }
/* Return pointer to copy of filename in the command buffer */ static const char * get_filename( const char ** const ibufpp ) { static char * buf = 0; static int bufsz = 0; const int pmax = path_max( 0 ); int n; *ibufpp = skip_blanks( *ibufpp ); if( **ibufpp != '\n' ) { int size = 0; if( !get_extended_line( ibufpp, &size, true ) ) return 0; if( **ibufpp == '!' ) { ++*ibufpp; return get_shell_command( ibufpp ); } else if( size > pmax ) { set_error_msg( "Filename too long" ); return 0; } } else if( !traditional() && !def_filename[0] ) { set_error_msg( "No current filename" ); return 0; } if( !resize_buffer( &buf, &bufsz, pmax + 1 ) ) return 0; for( n = 0; **ibufpp != '\n'; ++n, ++*ibufpp ) buf[n] = **ibufpp; buf[n] = 0; while( **ibufpp == '\n' ) ++*ibufpp; /* skip newline */ return ( may_access_filename( buf ) ? buf : 0 ); }
/* Return pointer to copy of shell command in the command buffer */ static const char * get_shell_command( const char ** const ibufpp ) { static char * buf = 0; static int bufsz = 0; static char * shcmd = 0; /* shell command buffer */ static int shcmdsz = 0; /* shell command buffer size */ static int shcmdlen = 0; /* shell command length */ const char * p; /* substitution char pointer */ int i = 0, len; if( restricted() ) { set_error_msg( "Shell access restricted" ); return 0; } if( !get_extended_line( ibufpp, &len, true ) ) return 0; p = *ibufpp; if( !resize_buffer( &buf, &bufsz, len + 1 ) ) return 0; buf[i++] = '!'; /* prefix command w/ bang */ while( **ibufpp != '\n' ) { if( **ibufpp == '!' ) { if( p != *ibufpp ) { if( !resize_buffer( &buf, &bufsz, i + 1 ) ) return 0; buf[i++] = *(*ibufpp)++; } else if( !shcmd || ( traditional() && !*( shcmd + 1 ) ) ) { set_error_msg( "No previous command" ); return 0; } else { if( !resize_buffer( &buf, &bufsz, i + shcmdlen ) ) return 0; for( p = shcmd + 1; p < shcmd + shcmdlen; ) buf[i++] = *p++; p = (*ibufpp)++; } } else if( **ibufpp == '%' ) { if( !def_filename[0] ) { set_error_msg( "No current filename" ); return 0; } p = strip_escapes( def_filename ); len = strlen( p ); if( !resize_buffer( &buf, &bufsz, i + len ) ) return 0; while( len-- ) buf[i++] = *p++; p = (*ibufpp)++; } else { if( !resize_buffer( &buf, &bufsz, i + 2 ) ) return 0; buf[i++] = **ibufpp; if( *(*ibufpp)++ == '\\' ) buf[i++] = *(*ibufpp)++; } } while( **ibufpp == '\n' ) ++*ibufpp; /* skip newline */ if( !resize_buffer( &shcmd, &shcmdsz, i + 1 ) ) return 0; memcpy( shcmd, buf, i ); shcmdlen = i; shcmd[i] = 0; if( *p == '!' || *p == '%' ) printf( "%s\n", shcmd + 1 ); return shcmd; }
/* * exec_global: Apply command list to lines in a range in global * queue. Return command status. */ int exec_global (ed_buffer_t *ed) { static char *gcb = NULL; /* global command buffer */ static size_t gcb_size = 0; /* buffer size */ ed_line_node_t *lp = NULL; size_t len; int first_time = 1; int interactive = ed->exec->global & GLBI; int saved_io_f = ed->display->io_f; int status; reset_undo_queue (ed); /* * If non-interactive, read command before entering loop in the * event of empty global queue. */ if (!interactive && !(ed->input = get_extended_line (&len, 0, 1, ed))) { status = ERR; clearerr (stdin); return status; } /* Empty command list equivalent to `p' command per SUSv4. */ if (strlen (ed->input) == 1 && *ed->input == '\n') ed->input = "p\n"; for (ed->exec->first_pass = 1; (lp = next_global_node (ed)); ed->input = gcb, ed->exec->first_pass = 0) { if ((status = get_line_node_address (lp, &ed->state->dot, ed)) < 0) return status; else if (interactive) { ed->display->io_f = PRNT; if ((status = display_lines (ed->state->dot, ed->state->dot, ed)) < 0) return status; else if (!(ed->input = get_stdin_line (&len, ed)) || !(ed->input = get_extended_line (&len, 0, 1, ed))) { /* For an interactive global command, permit EOF to cancel. */ status = feof (stdin) ? 0 : ERR; clearerr (stdin); return status; } } /* Global non-interactive command already set. */ if (ed->input == gcb) ; /* Skip to next line */ else if (len == 1 && interactive) continue; /* Repeat previous command. */ else if (len == 2 && *ed->input == '&' && interactive) { if (first_time) { ed->exec->err = _("No previous command"); return ERR; } } else { /* get_extended_line () isn't reentrant, so save ed->input. */ REALLOC_THROW (gcb, gcb_size, len + 1, ERR, ed); /* Assert: ed->input is NUL-terminated! */ strcpy (gcb, ed->input); first_time = 0; } for (ed->input = gcb; *ed->input;) if ((status = address_range (ed)) < 0 || (status = exec_command (ed)) < 0 || ((ed->display->io_f = status) > 0 && (status = display_lines (ed->state->dot, ed->state->dot, ed)) < 0)) return status; } return saved_io_f; }