/** * Locate next line * * @v image PEM image * @v offset Starting offset * @ret next Offset to next line */ static size_t pem_next ( struct image *image, size_t offset ) { off_t eol; /* Find and skip next newline character, if any */ eol = memchr_user ( image->data, offset, '\n', ( image->len - offset )); if ( eol < 0 ) return image->len; return ( eol + 1 ); }
/** * Execute script * * @v image Script * @ret rc Return status code */ static int script_exec ( struct image *image ) { size_t offset = 0; off_t eol; size_t len; int rc; /* Temporarily de-register image, so that a "boot" command * doesn't throw us into an execution loop. */ unregister_image ( image ); while ( offset < image->len ) { /* Find length of next line, excluding any terminating '\n' */ eol = memchr_user ( image->data, offset, '\n', ( image->len - offset ) ); if ( eol < 0 ) eol = image->len; len = ( eol - offset ); /* Copy line, terminate with NUL, and execute command */ { char cmdbuf[ len + 1 ]; copy_from_user ( cmdbuf, image->data, offset, len ); cmdbuf[len] = '\0'; DBG ( "$ %s\n", cmdbuf ); if ( ( rc = system ( cmdbuf ) ) != 0 ) { DBG ( "Command \"%s\" failed: %s\n", cmdbuf, strerror ( rc ) ); goto done; } } /* Move to next line */ offset += ( len + 1 ); } rc = 0; done: /* Re-register image and return */ register_image ( image ); return rc; }
/** * Process script lines * * @v image Script * @v process_line Line processor * @v terminate Termination check * @ret rc Return status code */ static int process_script ( struct image *image, int ( * process_line ) ( const char *line ), int ( * terminate ) ( int rc ) ) { off_t eol; size_t len; int rc; script_offset = 0; do { /* Find length of next line, excluding any terminating '\n' */ eol = memchr_user ( image->data, script_offset, '\n', ( image->len - script_offset ) ); if ( eol < 0 ) eol = image->len; len = ( eol - script_offset ); /* Copy line, terminate with NUL, and execute command */ { char cmdbuf[ len + 1 ]; copy_from_user ( cmdbuf, image->data, script_offset, len ); cmdbuf[len] = '\0'; DBG ( "$ %s\n", cmdbuf ); /* Move to next line */ script_offset += ( len + 1 ); /* Process line */ rc = process_line ( cmdbuf ); if ( terminate ( rc ) ) return rc; } } while ( script_offset < image->len ); return rc; }