diff options
| author | B. Watson <urchlay@slackware.uk> | 2024-05-19 05:11:11 -0400 | 
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2024-05-19 05:11:11 -0400 | 
| commit | ffeba14c10e1cf7f2936cd9249a352474c0e9526 (patch) | |
| tree | 6a2e70e91f458ce758a397223140f35448bf36a7 | |
| parent | 8ea53b7cae9fedf9432e9c83008597dbdb34f8d3 (diff) | |
| download | bw-atari8-tools-ffeba14c10e1cf7f2936cd9249a352474c0e9526.tar.gz | |
unprotbas: exit status 2 for unprotected program; add -c (check only).
| -rw-r--r-- | unprotbas.1 | 33 | ||||
| -rw-r--r-- | unprotbas.c | 47 | ||||
| -rw-r--r-- | unprotbas.rst | 27 | 
3 files changed, 78 insertions, 29 deletions
| diff --git a/unprotbas.1 b/unprotbas.1 index 3b8b832..0036a30 100644 --- a/unprotbas.1 +++ b/unprotbas.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]  .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]  .in \\n[rst2man-indent\\n[rst2man-indent-level]]u  .. -.TH "UNPROTBAS" 1 "2024-05-18" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "UNPROTBAS" 1 "2024-05-19" "0.2.1" "Urchlay's Atari 8-bit Tools"  .SH NAME  unprotbas \- Unprotect LIST-protected Atari 8-bit BASIC programs  .SH SYNOPSIS @@ -51,7 +51,7 @@ the terminal).  .INDENT 0.0  .TP  .B \fB\-v\fP -Verbose operation. +Verbose operation. TODO: it\(aqs always verbose right now...  .TP  .B \fB\-f\fP  Force the variable name table to be rebuilt, even if it looks OK. @@ -63,10 +63,24 @@ needed).  .B \fB\-g\fP  Remove any "garbage" data from the end of the file. By default,  it\(aqs left as\-is, in case it\(aqs actually data used by the program. +.TP +.B \fB\-c\fP +Check only. Does a dry run. Loads the program, unprotects it in +memory, but doesn\(aqt write the result anywhere. In this mode, there +is no \fBoutput\-file\fP\&.  .UNINDENT  .SH EXIT STATUS -.sp -Exit status is zero for success, non\-zero for failure. +.INDENT 0.0 +.TP +.B 0 +\fBinput\-file\fP was protected, unprotection was successful. +.TP +.B 1 +I/O error, or \fBinput\-file\fP isn\(aqt a valid BASIC program. +.TP +.B 2 +\fBinput\-file\fP is already an unprotected BASIC program. +.UNINDENT  .SH DETAILS  .sp  In the Atari BASIC world, it\(aqs possible to create a SAVEd (tokenized) @@ -123,10 +137,13 @@ named A through Z, A1 through A9, B1 through B9, etc, etc. It\(aqll  require human intelligence to figure out what each variable is for,  since the names are meaningless.  .sp -The \fBoutput\-file\fP may be larger than the \fBinput\-file\fP was, since -some types of variable\-name scrambling shrink the variable name -table to the minimum size (one byte per name); the rebuilt table -will be larger. +The \fBoutput\-file\fP may not be the exact size that the +\fBinput\-file\fP was. Some types of variable\-name scrambling shrink +the variable name table to the minimum size (one byte per name), so +the rebuilt table will be larger. Other types of scrambling leave +the variable name table at its original size, but \fBunprotbas\fP +generates only one\- and two\-character variable names, so the rebuilt +table might be smaller.  .TP  .B Bad next\-line pointer  Generally, this is done with line number 32768. Yes, this line diff --git a/unprotbas.c b/unprotbas.c index 8dc6844..845c75b 100644 --- a/unprotbas.c +++ b/unprotbas.c @@ -42,6 +42,8 @@ char *self;  int keepvars = 0;  int forcevars = 0;  int keepgarbage = 1; +int checkonly = 0; +int was_protected = 0;  int verbose = 0;  /* file handles */ @@ -57,6 +59,7 @@ void die(const char *msg) {  int readfile(void) {  	int got = fread(data, 1, 65535, input_file);  	fprintf(stderr, "read %d bytes\n", got); +	fclose(input_file);  	return got;  } @@ -369,6 +372,7 @@ void print_help(void) {  	fprintf(stderr, "-f: force variable name table rebuild\n");  	fprintf(stderr, "-n: do not rebuild variable name table, even if it's invalid\n");  	fprintf(stderr, "-g: remove trailing garbage, if present\n"); +	fprintf(stderr, "-c: check only; no output file\n");  	fprintf(stderr, "Use - as a filename to read from stdin and/or write to stdout\n");  } @@ -432,6 +436,7 @@ void parse_args(int argc, char **argv) {  				case 'f': forcevars++; break;  				case 'n': keepvars++; break;  				case 'g': keepgarbage = 0; break; +				case 'c': checkonly = 1; break;  				case 0:  							 if(!input_file)  								 open_input(NULL); @@ -445,7 +450,7 @@ void parse_args(int argc, char **argv) {  		} else {  			if(!input_file)  				open_input(*argv); -			else if(!output_file) +			else if(!checkonly && !output_file)  				open_output(*argv);  			else  				invalid_args(*argv); @@ -453,7 +458,7 @@ void parse_args(int argc, char **argv) {  	}  	if(!input_file) die("no input file given (use - for stdin)"); -	if(!output_file) die("no output file given (use - for stdout)"); +	if(!checkonly && !output_file) die("no output file given (use - for stdout)");  	if(keepvars && forcevars) die("-f and -n are mutually exclusive");  } @@ -465,26 +470,38 @@ int main(int argc, char **argv) {  	if(lomem) die("This doesn't look like an Atari BASIC program (no $0000 signature)"); -	/* -	fprintf(stderr, "data at STMTAB (we hope):\n"); -	for(int i=codestart; i<filelen; i++) { -		fprintf(stderr, "%02x ", data[i]); -	} -	fprintf(stderr, "\n"); -	*/ -  	if(!keepvars) { -		if(fixvars()) +		if(fixvars()) { +			was_protected = 1;  			fprintf(stderr, "Variable names replaced\n"); -		else +		} else {  			fprintf(stderr, "Variable names were already OK\n"); +		}  	} -	if(fixcode()) +	if(fixcode()) {  		fprintf(stderr, "Fixed invalid offset in code\n"); -	else +		was_protected = 1; +	} else {  		fprintf(stderr, "No invalid offsets\n"); +	} + +	if(was_protected) +		fprintf(stderr, "Program was protected.\n"); +	else +		fprintf(stderr, "Program was not protected.\n"); + +	if(checkonly) { +		fprintf(stderr, "Check-only mode; no output written.\n"); +		if(was_protected) +			return 0; +		else +			return 2; +	} + +	int got = fwrite(data, 1, filelen, output_file); +	fclose(output_file); +	fprintf(stderr, "wrote %d bytes\n", got); -	fwrite(data, filelen, 1, output_file);  	return 0;  } diff --git a/unprotbas.rst b/unprotbas.rst index 557d27d..b3a9926 100644 --- a/unprotbas.rst +++ b/unprotbas.rst @@ -33,7 +33,7 @@ OPTIONS  =======  **-v** -  Verbose operation. +  Verbose operation. TODO: it's always verbose right now...  **-f**    Force the variable name table to be rebuilt, even if it looks OK. @@ -46,10 +46,22 @@ OPTIONS    Remove any "garbage" data from the end of the file. By default,    it's left as-is, in case it's actually data used by the program. +**-c** +  Check only. Does a dry run. Loads the program, unprotects it in +  memory, but doesn't write the result anywhere. In this mode, there +  is no **output-file**. +  EXIT STATUS  =========== -Exit status is zero for success, non-zero for failure. +0 +  **input-file** was protected, unprotection was successful. + +1 +  I/O error, or **input-file** isn't a valid BASIC program. + +2 +  **input-file** is already an unprotected BASIC program.  DETAILS  ======= @@ -99,10 +111,13 @@ Variable name table scrambling    require human intelligence to figure out what each variable is for,    since the names are meaningless. -  The **output-file** may be larger than the **input-file** was, since -  some types of variable-name scrambling shrink the variable name -  table to the minimum size (one byte per name); the rebuilt table -  will be larger. +  The **output-file** may not be the exact size that the +  **input-file** was. Some types of variable-name scrambling shrink +  the variable name table to the minimum size (one byte per name), so +  the rebuilt table will be larger. Other types of scrambling leave +  the variable name table at its original size, but **unprotbas** +  generates only one- and two-character variable names, so the rebuilt +  table might be smaller.  Bad next-line pointer    Generally, this is done with line number 32768. Yes, this line | 
