argv@island.uu.net (Dan Heller) (04/01/89)
Submitted-by: Arthur Smith <arthur@helios.tn.cornell.edu> Posting-number: Volume 3, Issue 63 Archive-name: xmandel/part01 [ This runs on color suns -only- The makefile is very small and I didn't see a need for an Imake file. It is rather slow and it will almost certainly eat up your cpu. I compiled and ran this on my sun3/60 with 8M. I had "to make xmandel68881" because the default wouldn't work for me but your milage may vary. The README says "sit and wait" and it isn't kidding. The mandelbrot image overwrites your background on the root window it seems. I ran it as: "xmandel -display unix:0.1" --argv] # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by helios!arthur on Sun Mar 26 15:27:09 EST 1989 # Contents: Makefile README colors.h graphics.c graphics.h wrt.c xmandel.c echo x - Makefile sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//' CFLAGS = -O -ffpa wrt.o: colors.h xmandel: xmandel.o graphics.o wrt.o cc $(CFLAGS) xmandel.o graphics.o wrt.o -o xmandel -lX11 -lm xmandel6.o: xmandel.c; cc -O -f68881 xmandel.c -c -o xmandel6.o graphics6.o: graphics.c; cc -O -f68881 graphics.c -c -o graphics6.o wrt6.o: wrt.c colors.h; cc -O -f68881 wrt.c -c -o wrt6.o xmandel68881: xmandel6.o graphics6.o wrt6.o cc -O -f68881 xmandel6.o graphics6.o wrt6.o -o xmandel -lX11 -lm @//E*O*F Makefile// chmod u=rw,g=r,o=r Makefile echo x - README sed 's/^@//' > "README" <<'@//E*O*F README//' xmandel - A mandelbrot program for color suns, running under X11. This is a crude program which I am submitting simply because it actually works (under Release 2 at least). It generates the Mandelbrot set at desired coordinates, on the display you want, and with the resolution scale you want, and then the location and magnification can be interactively changed by using the mouse and the "Alternate" key. ALT-left button causes the scale to expand by a factor of 5, ALT-right button reduces by the same factor, ALT-middle causes the screen to shift to be centered on the point where the button is pressed. If you just let the thing sit and wait, it gradually produces a higher resolution picture, eventually reaching the maximum resolution possible on the screen. There are various defaults set, and maybe some other things that people will want to change. The graphics stuff is really quite general: for example somebody here just changed the function passed to produce Julia sets instead of the Mandelbrot set. So I hope other people find this useful! Arthur Smith (arthur@helios.tn.cornell.edu) @//E*O*F README// chmod u=rw,g=r,o=r README echo x - colors.h sed 's/^@//' > "colors.h" <<'@//E*O*F colors.h//' unsigned char colors[] = { 255, 255, 255, 0, 0, 0, 216, 216, 191, 84, 84, 84, 0, 255, 127, 255, 0, 255, 255, 0, 0, 79, 47, 79, 35, 142, 35, 35, 107, 142, 255, 127, 0, 79, 47, 47, 204, 50, 50, 112, 219, 147, 192, 32, 0, 224, 32, 0, 0, 64, 0, 32, 64, 0, 64, 64, 0, 96, 64, 0, 128, 64, 0, 160, 64, 0, 192, 64, 0, 224, 64, 0, 0, 96, 0, 32, 96, 0, 64, 96, 0, 96, 96, 0, 128, 96, 0, 160, 96, 0, 192, 96, 0, 224, 96, 0, 0, 128, 0, 32, 128, 0, 64, 128, 0, 96, 128, 0, 128, 128, 0, 160, 128, 0, 192, 128, 0, 224, 128, 0, 0, 160, 0, 32, 160, 0, 64, 160, 0, 96, 160, 0, 128, 160, 0, 160, 160, 0, 192, 160, 0, 224, 160, 0, 0, 192, 0, 32, 192, 0, 64, 192, 0, 96, 192, 0, 128, 192, 0, 160, 192, 0, 192, 192, 0, 224, 192, 0, 0, 224, 0, 32, 224, 0, 64, 224, 0, 96, 224, 0, 128, 224, 0, 160, 224, 0, 192, 224, 0, 224, 224, 0, 0, 0, 64, 32, 0, 64, 64, 0, 64, 96, 0, 64, 128, 0, 64, 160, 0, 64, 192, 0, 64, 224, 0, 64, 0, 32, 64, 32, 32, 64, 64, 32, 64, 96, 32, 64, 128, 32, 64, 160, 32, 64, 192, 32, 64, 224, 32, 64, 0, 64, 64, 32, 64, 64, 64, 64, 64, 96, 64, 64, 128, 64, 64, 160, 64, 64, 192, 64, 64, 224, 64, 64, 0, 96, 64, 32, 96, 64, 64, 96, 64, 96, 96, 64, 128, 96, 64, 160, 96, 64, 192, 96, 64, 224, 96, 64, 0, 128, 64, 32, 128, 64, 64, 128, 64, 96, 128, 64, 128, 128, 64, 160, 128, 64, 192, 128, 64, 224, 128, 64, 0, 160, 64, 32, 160, 64, 64, 160, 64, 96, 160, 64, 128, 160, 64, 160, 160, 64, 192, 160, 64, 224, 160, 64, 0, 192, 64, 32, 192, 64, 64, 192, 64, 96, 192, 64, 128, 192, 64, 160, 192, 64, 192, 192, 64, 224, 192, 64, 0, 224, 64, 32, 224, 64, 64, 224, 64, 96, 224, 64, 128, 224, 64, 160, 224, 64, 192, 224, 64, 224, 224, 64, 0, 0, 128, 32, 0, 128, 64, 0, 128, 96, 0, 128, 128, 0, 128, 160, 0, 128, 192, 0, 128, 224, 0, 128, 0, 32, 128, 32, 32, 128, 64, 32, 128, 96, 32, 128, 128, 32, 128, 160, 32, 128, 192, 32, 128, 224, 32, 128, 0, 64, 128, 32, 64, 128, 64, 64, 128, 96, 64, 128, 128, 64, 128, 160, 64, 128, 192, 64, 128, 224, 64, 128, 0, 96, 128, 32, 96, 128, 64, 96, 128, 96, 96, 128, 128, 96, 128, 160, 96, 128, 192, 96, 128, 224, 96, 128, 0, 128, 128, 32, 128, 128, 64, 128, 128, 96, 128, 128, 128, 128, 128, 160, 128, 128, 192, 128, 128, 224, 128, 128, 0, 160, 128, 32, 160, 128, 64, 160, 128, 96, 160, 128, 128, 160, 128, 160, 160, 128, 192, 160, 128, 224, 160, 128, 0, 192, 128, 32, 192, 128, 64, 192, 128, 96, 192, 128, 128, 192, 128, 160, 192, 128, 192, 192, 128, 224, 192, 128, 0, 224, 128, 32, 224, 128, 64, 224, 128, 96, 224, 128, 128, 224, 128, 160, 224, 128, 192, 224, 128, 224, 224, 128, 0, 0, 192, 32, 0, 192, 64, 0, 192, 96, 0, 192, 128, 0, 192, 160, 0, 192, 192, 0, 192, 224, 0, 192, 0, 32, 192, 32, 32, 192, 64, 32, 192, 96, 32, 192, 128, 32, 192, 160, 32, 192, 192, 32, 192, 224, 32, 192, 0, 64, 192, 32, 64, 192, 64, 64, 192, 96, 64, 192, 128, 64, 192, 160, 64, 192, 192, 64, 192, 224, 64, 192, 0, 96, 192, 32, 96, 192, 64, 96, 192, 96, 96, 192, 128, 96, 192, 160, 96, 192, 192, 96, 192, 224, 96, 192, 0, 128, 192, 32, 128, 192, 64, 128, 192, 96, 128, 192, 128, 128, 192, 160, 128, 192, 192, 128, 192, 224, 128, 192, 0, 160, 192, 32, 160, 192, 64, 160, 192, 96, 160, 192, 128, 160, 192, 160, 160, 192, 192, 160, 192, 224, 160, 192, 0, 192, 192, 32, 192, 192, 64, 192, 192, 96, 192, 192, 128, 192, 192, 160, 192, 192, 192, 192, 192, 224, 192, 192, 0, 224, 192, 32, 224, 192, 64, 224, 192, 96, 224, 192, 128, 224, 192, 160, 224, 192, 192, 224, 192, 224, 224, 192 }; @//E*O*F colors.h// chmod u=rw,g=r,o=r colors.h echo x - graphics.c sed 's/^@//' > "graphics.c" <<'@//E*O*F graphics.c//' #include <X11/Xos.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> #include <stdio.h> #include <math.h> #include <signal.h> #include "graphics.h" #define NMAX 256 #define SCFAC 5 #define FLOOR2(x) ((x)/2) #define CEIL2(x) ((x) - (x)/2) unsigned long pixellist[NMAX]; char *malloc(); int ntx,nrx,nty,nry; int nmaxt,nmint,numpix; int nomin = 1; int nomax = NMAX-1; char *display = NULL; double xin = 0; double yin = 0; double scale = 1; int rsiz = 12; double dx,dy; double pscale; int restartflag; int (*func)(); char *name = "XGraphics"; Rectangle root; int rscreen; Display *dpy; Colormap cid; Window rwindow,nwindow; Pixmap pixmap; Pixmap npixmap; GC gc; XGCValues gcv; graphics(display0,xin0,yin0,scale0,res,f) char *display0; double xin0,yin0,scale0; int res,(*f)(); { display = display0; xin = xin0; yin = yin0; scale = scale0; func = f; rsiz = res; root.x = root.y = 0; root.w = root.h = rsiz; rectinit(&root); init(); doplot(); finish(); } init() { int sigfin(); int i,width,height; XWindowAttributes war; XSetWindowAttributes setwa; XColor sdr; signal(SIGINT, sigfin); signal(SIGQUIT, sigfin); signal(SIGTERM, sigfin); if ((dpy = XOpenDisplay(display)) == 0) { fprintf(stderr, "Graphics: Can't open display \"%s\"\n", XDisplayName(display)); exit(1); } rwindow = XDefaultRootWindow(dpy); pointerinit(); rscreen = XDefaultScreen(dpy); XGetWindowAttributes(dpy,rwindow,&war); width = war.width; height = war.height; nrx = ceil(((double) width)/rsiz); ntx = nrx*rsiz; nry = ceil(((double) height)/rsiz); nty = nry*rsiz; nwindow = XCreateWindow(dpy, rwindow, 0, 0, (unsigned int) nrx, (unsigned int) nry, 0, 0, CopyFromParent, CopyFromParent, 0L, &setwa); /* Give the window a name */ XChangeProperty(dpy, nwindow, XA_WM_NAME, XA_STRING, 8, PropModeReplace, name, strlen(name)); XMapWindow(dpy,nwindow); XMoveWindow(dpy,nwindow,0,0); cid = XDefaultColormap(dpy,rscreen); numpix = 1<<war.depth; pixellist[0] = 1; for (i=1;i<NMAX;i++){ pixellist[i] = (i + 1) % numpix; } pixmap = XCreatePixmap(dpy,rwindow,ntx,nty,war.depth); if (pixmap==0){ fprintf(stderr, "Graphics: Unable to create Pixmap"); exit(1); } npixmap = XCreatePixmap(dpy,nwindow,nrx,nry,war.depth); if (npixmap==0){ fprintf(stderr, "Graphics: Unable to create Pixmap"); exit(1); } gc = XCreateGC(dpy,pixmap,0L,&gcv); } initpix() { int i; pixellist[0] = 1; nomax = nmaxt; nomin = nmint; for (i=1;i<NMAX;i++){ pixellist[i] = (2 + ((i - nomin)*(numpix-2)) / (nomax-nomin)) % numpix; } } pointerinit() { long event_mask; int mkpm; XModifierKeymap *modmap; KeyCode *mkdptr; modmap = XGetModifierMapping(dpy); mkpm = modmap->max_keypermod; mkdptr = modmap->modifiermap; mkdptr[4*mkpm] = (char) 26; /* This is the keycode for the Alt key, and Mod2 has position 4 */ XSetModifierMapping(dpy,modmap); event_mask = ButtonPressMask; XGrabButton(dpy,AnyButton,Mod2Mask,rwindow,True,event_mask, GrabModeAsync,GrabModeAsync,None,0); } int rescale(n) int n; { int i; i = abs(n)%NMAX; if (i>nmaxt) nmaxt = i; if ((i>0)&&(i<nmint)) nmint = i; return i; } plotpt(i,j,w,h,n) int i,j,w,h,n; { XSetForeground(dpy,gc,pixellist[n]); XFillRectangle(dpy,pixmap,gc,i,j,w,h); if ((i%rsiz==0)&&(j%rsiz==0)) XDrawPoint(dpy,npixmap,gc,i/rsiz,j/rsiz); } plotall() { XSetWindowBackgroundPixmap(dpy,rwindow,pixmap); XSetWindowBackgroundPixmap(dpy,nwindow,npixmap); XClearWindow(dpy,rwindow); XClearWindow(dpy,nwindow); XFlush(dpy); checkevent(); } checkevent() { long event_mask; XEvent evr; XButtonEvent xbevr; char *args = NULL; Bool checkb2(); event_mask = ButtonPressMask; if (XCheckIfEvent(dpy,&evr,checkb2,args)== True){ restartflag = 1; xbevr = evr.xbutton; xin += (-(nrx+1)*rsiz + 2*xbevr.x)/(pscale*rsiz); yin += (-(nry+1)*rsiz + 2*xbevr.y)/(pscale*rsiz); } while(XCheckMaskEvent(dpy,event_mask,&evr)==True){ restartflag = 1; xbevr = evr.xbutton; if (xbevr.button == Button1) scale /= SCFAC; if (xbevr.button == Button3) scale *= SCFAC; } printf("xin,yin: %g, %g, scale: %g\n",xin,yin,scale); } Bool checkb2(display,event,args) Display *display; XEvent *event; char *args; { XButtonEvent xbevr; xbevr = event->xbutton; if ((xbevr.button == Button2)&& (event->type==ButtonPress)) return True; else return False; } Rectangle *newrect() { Rectangle *t; t = (Rectangle *) malloc(sizeof(Rectangle)); return t; } rectinit(rptr) Rectangle *rptr; { Rectangle *nptr; int w,h; w = rptr->w; h = rptr->h; if ((h==1)&&(w==1)) rptr->ul = NULL; else { nptr = rptr->ul = newrect(); nptr->x = rptr->x; nptr->y = rptr->y; nptr->w = CEIL2(w); nptr->h = CEIL2(h); rectinit(nptr); } if (w==1) rptr->ur = NULL; else { nptr = rptr->ur = newrect(); nptr->x = rptr->x + CEIL2(w); nptr->y = rptr->y; nptr->w = FLOOR2(w); nptr->h = CEIL2(h); rectinit(nptr); } if (h == 1) rptr->ll = NULL; else { nptr = rptr->ll = newrect(); nptr->x = rptr->x; nptr->y = rptr->y + CEIL2(h); nptr->w = CEIL2(w); nptr->h = FLOOR2(h); rectinit(nptr); } if ((h == 1)||(w == 1)) rptr->lr = NULL; else { nptr = rptr->lr = newrect(); nptr->x = rptr->x + CEIL2(w); nptr->y = rptr->y + CEIL2(h); nptr->w = FLOOR2(w); nptr->h = FLOOR2(h); rectinit(nptr); } } doplot() { int dographics(); int l,maxl; maxl = 0; l = 1; while (l<rsiz){ l *=2; maxl++; } restart: restartflag = 0; pscale = nrx*scale; dx = 2/(pscale); dy = 2/(pscale); nmaxt = 0; nmint = NMAX; if (dographics(&root,0)==0) goto restart; initpix(); for (l=0;l<=maxl;l++){ if (dographics(&root,l)==0) goto restart; } } int dographics(rptr,level) Rectangle *rptr; int level; { int i,j,ii,jj,n; double xstart,ystart,x,y; if (rptr==NULL) return 1; if (level==0){ ii = rptr->x; jj = rptr->y; xstart = xin - nrx/pscale + (-rsiz+2*ii)/(pscale*rsiz); ystart = yin - nry/pscale + (-rsiz + 2*jj)/(pscale*rsiz); for (x = xstart,i=0;i<nrx;i++,x += dx) for (y = ystart, j=0;j<nry;j++,y += dy){ n = rescale((*func)(x,y)); plotpt(rsiz*i+ii,rsiz*j+jj,rptr->w,rptr->h,n); } plotall(); if (restartflag==1) return(0); return(1); } if (dographics2(rptr,level)==0) return 0; return 1; } int dographics2(rptr,level) Rectangle *rptr; int level; { if (rptr==NULL) return 1; if (dographics2(rptr->ul,level-1)==0) return 0; if (dographics(rptr->ur,level-1)==0) return 0; if (dographics(rptr->ll,level-1)==0) return 0; if (dographics(rptr->lr,level-1)==0) return 0; return 1; } finish() { XFreeGC(dpy,gc); XFreePixmap(dpy,pixmap); XFreePixmap(dpy,npixmap); XDestroyWindow(dpy,nwindow); } sigfin(sig,code,scp) int sig,code; struct sigcontext *scp; { finish(); exit(sig); } @//E*O*F graphics.c// chmod u=rw,g=r,o=r graphics.c echo x - graphics.h sed 's/^@//' > "graphics.h" <<'@//E*O*F graphics.h//' typedef struct rectangle{ int x,y,w,h; struct rectangle *ul,*ur,*ll,*lr; } Rectangle; @//E*O*F graphics.h// chmod u=rw,g=r,o=r graphics.h echo x - wrt.c sed 's/^@//' > "wrt.c" <<'@//E*O*F wrt.c//' #include <stdio.h> #include <sys/file.h> #include <math.h> #include <rasterfile.h> #define XSIZ 1152 #define YSIZ 900 #define TOTSIZ 1036800 #define LINE 80 #define MAXCHAR 256 extern double xin,yin,scale; extern int nomin,nomax; int head[] = { RAS_MAGIC, XSIZ, /* Width */ YSIZ, /* height */ 8, /* depth */ TOTSIZ, /* length - set later */ RT_STANDARD, /* type 1 rasterfile */ RMT_EQUAL_RGB, /* RGB vectors */ 768 /* Size of colormap = 3*256 */ }; writeman(func) int (*func)(); { char filename[LINE]; char instr[LINE]; unsigned char *buffer; unsigned char colormap[768]; int rsiz,fd; int nrx,nry; int i,j; unsigned char n; double x,xstart,y,ystart; double pscale,dx,dy; fprintf(stderr,"Name of file: "); fflush(stderr); fgets(instr, LINE, stdin); sscanf(instr,"%s",filename); rsiz = igetd("resolution scale", 1); if ((fd = open(filename,O_CREAT|O_WRONLY,0644))==-1){ fprintf(stderr,"Sorry, can't open file\n"); exit(-1); } if (fork()) exit(0); write(fd, head, sizeof(head)); putcolor(colormap); write(fd, colormap, 768); buffer = (unsigned char *) malloc(TOTSIZ*sizeof(char)); nrx = (int) ceil(((double) XSIZ)/rsiz); nry = (int) ceil(((double) YSIZ)/rsiz); /* write(fd, &nrx, sizeof(int)); write(fd, &nry, sizeof(int));*/ pscale = nrx*scale; dy = dx = 2/pscale; xstart = xin - nrx/pscale; ystart = yin - nry/pscale; for (y=ystart, j=0;j<nry;j++,y += dy) for (x = xstart,i=0;i<nrx;i++,x += dx){ n = abs((*func)(x,y))%MAXCHAR; if (n==0) n=1; else n = (2 + ((n - nomin)*(MAXCHAR-2)) / (nomax-nomin)) % MAXCHAR; writebuf(buffer, n, i, j, rsiz); } close(fd); } writebuf(buf, c, x, y, rsiz) unsigned char *buf, c; int x, y, rsiz; { int index,i,j,ind; index = x*rsiz + y*rsiz*XSIZ; for (i=0;i<rsiz;i++){ ind = index + i*XSIZ; for(j = 0;j<rsiz;j++){ if (ind >= TOTSIZ) break; buf[ind++] = c; } } } igetd(mesg,deflt) char *mesg; int deflt; { int i; char s[LINE]; fprintf(stderr,"*Enter %s [%d]: ",mesg,deflt); fflush(stderr); if (!fgets(s,LINE,stdin)) exit(-1); if(sscanf(s,"%d%>",&i)==EOF) return(deflt); else return(i); } #include "colors.h" putcolor(cm) unsigned char *cm; { int i, j; for (i=0;i<3;i++) for (j=0;j<256;j++) *cm++ = colors[3*j + i]; } @//E*O*F wrt.c// chmod u=rw,g=r,o=r wrt.c echo x - xmandel.c sed 's/^@//' > "xmandel.c" <<'@//E*O*F xmandel.c//' #include <stdio.h> #include <signal.h> #include <math.h> #include <string.h> #include <ctype.h> #define NMAX 200 #define LINE 80 #define SCFAC 5 typedef struct complx{ double re; double im; } Cmplx; char *argv0; int rsiz0 = 12; double xin0 = 0; double yin0 = 0; double scale0 = 1; char *display0 = NULL; char *malloc(); double xo,yo; FILE *fp = stderr; FILE *fpin = stdin; main(argc,argv) int argc; char **argv; { int nmand(), length; void exithandler(); argv0 = argv[0]; again: if (argc > 2 && strcmp(argv[1], "-display") == 0) { argv++; argc--; length = strlen(argv[1]); display0 = malloc(length + 5); strcpy(display0,argv[1]); if ((length < 4) || (argv[1][length - 4] != ':')) strcat(display0,":0.0"); argv++; argc--; goto again; } if (argc > 2 && strcmp(argv[1], "-x") == 0) { argv++; argc--; if (sscanf(argv[1], "%F", &xin0) !=1) usage(); argv++; argc--; goto again; } if (argc > 2 && strcmp(argv[1], "-y") == 0) { argv++; argc--; if (sscanf(argv[1], "%F", &yin0) !=1) usage(); argv++; argc--; goto again; } if (argc > 2 && strcmp(argv[1], "-s") == 0) { argv++; argc--; if (sscanf(argv[1], "%F", &scale0) !=1) usage(); argv++; argc--; goto again; } if (argc > 2 && strcmp(argv[1], "-r") == 0) { argv++; argc--; if (sscanf(argv[1], "%d", &rsiz0) !=1) usage(); argv++; argc--; goto again; } if (argc > 1) usage(); on_exit(exithandler); graphics(display0,xin0,yin0,scale0,rsiz0,nmand,NMAX); } int nmand(x,y) double x,y; { Cmplx map(),z; int n; n = 1; xo = z.re = x; yo = z.im = y; for(;z.re*z.re+z.im*z.im < 4;z = map(z)) if (++n>=NMAX) break; return NMAX - n; } Cmplx map(z) Cmplx z; { Cmplx t; t.re = z.re*z.re - z.im*z.im + xo; t.im = 2*z.re*z.im + yo; return t; } usage() { fprintf(stderr, "usage: %s [-display host] [-x x0] [-y y0] [-s scale]\n",argv0); fprintf(stderr," [-r resolution]\n"); exit(1); } void exithandler(status) int status; { int wtf,nmand(); if (status != SIGINT) exit(0); wtf = lgetd("Write to file",0); if (wtf == 0) exit(0); writeman(nmand); } lgetd(mesg,deflt) char *mesg; int deflt; { char s[LINE], *sptr; for(;;) { fprintf(fp,"*%s [%c]: ",mesg,(deflt ? 'y' : 'n')); fflush(fp); sptr = fgets(s,LINE,fpin); if (!sptr) exit(-1); while(isspace(*sptr)) sptr++; if(*sptr=='\0') return(deflt); if(isupper(*sptr)) *sptr = tolower(*sptr); if(*sptr == 'y') return(1); else if(*sptr == 'n') return(0); else fprintf(fp," Say what? Enter y or n.\n"); } } @//E*O*F xmandel.c// chmod u=rw,g=r,o=r xmandel.c echo Inspecting for damage in transit... temp=/tmp/shar$$; dtemp=/tmp/.shar$$ trap "rm -f $temp $dtemp; exit" 0 1 2 3 15 cat > $temp <<\!!! 9 61 431 Makefile 27 181 1131 README 258 774 3643 colors.h 359 802 6833 graphics.c 4 10 88 graphics.h 118 297 2300 wrt.c 154 365 2666 xmandel.c 929 2490 17092 total !!! wc Makefile README colors.h graphics.c graphics.h wrt.c xmandel.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp if [ -s $dtemp ] then echo "Ouch [diff of wc output]:" ; cat $dtemp else echo "No problems found." fi exit 0