forked from bonsai/harakit
		
	dj(1): refactor to build again and to get rid of globals
This commit is contained in:
		
							parent
							
								
									95f7992e0f
								
							
						
					
					
						commit
						45a880455d
					
				
							
								
								
									
										81
									
								
								src/dj.c
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								src/dj.c
									
									
									
									
									
								
							@ -25,6 +25,8 @@
 | 
			
		||||
#include <sysexits.h> /* EX_OK, EX_USAGE */
 | 
			
		||||
#include <unistd.h> /* close(2), getopt(3), lseek(2), read(2), write(2),
 | 
			
		||||
                     * optarg, optind, STDIN_FILENO, STDOUT_FILENO */
 | 
			
		||||
#include <sys/stat.h> /* S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH,
 | 
			
		||||
                         S_IWUSR */
 | 
			
		||||
extern int errno;
 | 
			
		||||
 | 
			
		||||
/* dj uses two structures that respectively correspond to the reading and
 | 
			
		||||
@ -41,47 +43,17 @@ struct Io{
 | 
			
		||||
	int prec;		/* partial records processed */
 | 
			
		||||
	int rec;		/* records processed */
 | 
			
		||||
	long seek;		/* bytes to seek/skip (will be 0 after skippage) (-sS) */
 | 
			
		||||
} ep[2]; /* "engineered pipe"; also "extended play", for the deejay */
 | 
			
		||||
}; 
 | 
			
		||||
 | 
			
		||||
/* Additionally, the following global variables are used to store user options.
 | 
			
		||||
 */
 | 
			
		||||
/* To be assigned to main:fmt_output and used with output(). */
 | 
			
		||||
static char *fmt_asv   = "%d\037%d\036%d\037%d\035%d\036%d\034";
 | 
			
		||||
static char *fmt_human = "%d+%d > %d+%d; %d > %d\n";
 | 
			
		||||
 | 
			
		||||
/* (-a)  */ static int align; /* Only the lower 8b are used but align is
 | 
			
		||||
                               * negative if no alignment is being done. */
 | 
			
		||||
 | 
			
		||||
/* (-c)  */ static int count; /* 0 if dj(1) runs until no more reads are
 | 
			
		||||
                               * possible. */
 | 
			
		||||
 | 
			
		||||
/* ASCII field separator delimited statistics */
 | 
			
		||||
            static char *fmt_asv   = "%d\037%d\036%d\037%d\035%d\036%d\034";
 | 
			
		||||
/* human-readable statistics */
 | 
			
		||||
            static char *fmt_human = "%d+%d > %d+%d; %d > %d\n";
 | 
			
		||||
/* pointer to chosen formatting */
 | 
			
		||||
/* (-H)  */ static char *fmt_output; /* fmt_asv (default) or fmt_human (-H) */
 | 
			
		||||
 | 
			
		||||
/* (-n)  */ static char noerror;     /* 0 - exits on partial reads or writes
 | 
			
		||||
                                      *     (default)
 | 
			
		||||
                                      * 1 - retries on partial reads/writes
 | 
			
		||||
                                      *     (-n) */
 | 
			
		||||
 | 
			
		||||
/* Non-configurable defaults. */
 | 
			
		||||
#define bs_default 1024 /* GNU dd(1) default; twice POSIX but a neat 2^10 */
 | 
			
		||||
static char *program_name = "<no argv[0]>";
 | 
			
		||||
static char *stdin_name = "<stdin>";
 | 
			
		||||
static char *stdout_name = "<stdout>";
 | 
			
		||||
static int read_flags = O_RDONLY; /* These flags are consistent with Busybox */
 | 
			
		||||
static int write_flags = O_WRONLY | O_CREAT; /* dd(1). */
 | 
			
		||||
 | 
			
		||||
/* Macro to set defaults for user-configurable options. */
 | 
			
		||||
#define setdefaults do{ \
 | 
			
		||||
	align = -1; \
 | 
			
		||||
	count = 0; \
 | 
			
		||||
	fmt_output = fmt_asv; \
 | 
			
		||||
	noerror = 0; \
 | 
			
		||||
	ep[0].fl = read_flags; \
 | 
			
		||||
	Io_setdefaults(&ep[0]); \
 | 
			
		||||
	ep[1].fl = write_flags; \
 | 
			
		||||
	Io_setdefaults(&ep[1]); }while(0)
 | 
			
		||||
static int read_flags = O_RDONLY; /* Consistent with Busybox dd(1). */
 | 
			
		||||
static int write_flags = O_WRONLY | O_CREAT;
 | 
			
		||||
 | 
			
		||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
 | 
			
		||||
 | 
			
		||||
@ -238,7 +210,7 @@ Io_read(struct Io *io){
 | 
			
		||||
static struct Io *
 | 
			
		||||
Io_setdefaults(struct Io *io){
 | 
			
		||||
 | 
			
		||||
	io->bs = bs_default;
 | 
			
		||||
	io->bs = 1024 /* bytes; 1 KiB */; /* GNU dd(1) default; POSIX says 512B */
 | 
			
		||||
	io->buf = NULL;
 | 
			
		||||
	io->bytes = 0;
 | 
			
		||||
	io->fd = (io->fl == read_flags) ? STDIN_FILENO : STDOUT_FILENO;
 | 
			
		||||
@ -275,13 +247,13 @@ oserr(char *s){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Prints statistics regarding the use of dj, particularly partially and
 | 
			
		||||
 * completely read and written records, accessing ep and fmt_output. */
 | 
			
		||||
 * completely read and written records. */
 | 
			
		||||
static void
 | 
			
		||||
output(void){
 | 
			
		||||
output(struct Io io[2], char *fmt){
 | 
			
		||||
 | 
			
		||||
	fprintf(stderr, fmt_output,
 | 
			
		||||
		ep[0].rec, ep[0].prec, ep[1].rec, ep[1].prec,
 | 
			
		||||
		ep[0].bytes, ep[1].bytes);
 | 
			
		||||
	fprintf(stderr, fmt,
 | 
			
		||||
		io[0].rec, io[0].prec, io[1].rec, io[1].prec,
 | 
			
		||||
		io[0].bytes, io[1].bytes);
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
}
 | 
			
		||||
@ -312,14 +284,27 @@ usage(void){
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]){
 | 
			
		||||
	int align; /* low 8b used, negative if no alignment is being done */
 | 
			
		||||
	int count; /* 0 if dj(1) runs until no more reads are possible */
 | 
			
		||||
	struct Io ep[2]; /* "engineered pipe"; also "extended play", for the DJ */
 | 
			
		||||
	char *fmt_output; /* fmt_asv (default) or fmt_human (-H) */
 | 
			
		||||
	char noerror; /* 0=exits (default) 1=retries on partial reads or writes */
 | 
			
		||||
	int c;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	setdefaults;
 | 
			
		||||
	/* Set defaults. */
 | 
			
		||||
	align = -1;
 | 
			
		||||
	count = 0;
 | 
			
		||||
	fmt_output = fmt_asv;
 | 
			
		||||
	noerror = 0;
 | 
			
		||||
	ep[0].fl = read_flags;
 | 
			
		||||
	Io_setdefaults(&ep[0]);
 | 
			
		||||
	ep[1].fl = write_flags;
 | 
			
		||||
	Io_setdefaults(&ep[1]);
 | 
			
		||||
 | 
			
		||||
	if(argc > 0){
 | 
			
		||||
		program_name = argv[0];
 | 
			
		||||
		while((c = getopt(argc, argv, "a:Ab:B:c:di:hHnqs:S:o:")) != -1)
 | 
			
		||||
		while((c = getopt(argc, argv, "a:Ab:B:c:i:hHns:S:o:")) != -1)
 | 
			
		||||
			switch(c){
 | 
			
		||||
			case 'i': case 'o':
 | 
			
		||||
				i = (c == 'o');
 | 
			
		||||
@ -369,7 +354,7 @@ int main(int argc, char *argv[]){
 | 
			
		||||
		}else if(ep[i].seek > 0)
 | 
			
		||||
			switch(Io_fdseek(&ep[i])){
 | 
			
		||||
			case EX_OK:
 | 
			
		||||
				output();
 | 
			
		||||
				output(ep, fmt_output);
 | 
			
		||||
				terminate(ep);
 | 
			
		||||
				return EX_OK;
 | 
			
		||||
			}
 | 
			
		||||
@ -384,7 +369,7 @@ int main(int argc, char *argv[]){
 | 
			
		||||
		else if(ep[0].bufuse < ep[0].bs){
 | 
			
		||||
			++ep[0].prec;
 | 
			
		||||
			fprintf(stderr, "%s: Partial read:\n\t", program_name);
 | 
			
		||||
			output();
 | 
			
		||||
			output(ep, fmt_output);
 | 
			
		||||
			if(!noerror)
 | 
			
		||||
				count = 1;
 | 
			
		||||
			if(align >= 0)
 | 
			
		||||
@ -410,7 +395,7 @@ int main(int argc, char *argv[]){
 | 
			
		||||
			}else if(c > ep[1].bufuse && ep[1].bufuse > 0){
 | 
			
		||||
				ep[1].prec += 1;
 | 
			
		||||
				fprintf(stderr, "%s: Partial write:\n\t", program_name);
 | 
			
		||||
				output();
 | 
			
		||||
				output(ep, fmt_output);
 | 
			
		||||
				if(!noerror)
 | 
			
		||||
					count = 1;
 | 
			
		||||
			}else if(ep[1].bufuse == 0 && c < ep[1].bs)
 | 
			
		||||
@ -420,7 +405,7 @@ int main(int argc, char *argv[]){
 | 
			
		||||
		}while(ep[0].bufuse > 0);
 | 
			
		||||
	}while(count == 0 || --count > 0);
 | 
			
		||||
 | 
			
		||||
	output();
 | 
			
		||||
	output(ep, fmt_output);
 | 
			
		||||
	terminate(ep);
 | 
			
		||||
 | 
			
		||||
	return EX_OK;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user