/* TOCLIP.C */ /* Compile: Turbo C 1.5 or 2.0. Small memory model. */ /* tcc -LC:\TC\LIB -IC:\TC\INCLUDE -ms toclip.c */ /* Written by GBG, gustafso@math.utah.edu, August 1998 */ /* Copyright: GNU Public license */ /* Append or copy text to the windows clipboard */ /* Limitations: 64k segment of data */ #define _BORLANDC_SOURCE #include #include #include #include #include /* Warning: selecting BUFsize too large will result in failure of fopen */ #define BUFsize (unsigned)1024*58 /* 59k limit on file size */ /* changed to 58 KiB to succeed in gcc ia16 build */ void help(void){ fprintf(stderr,"toclip 1.0 (9-Sept-1998)\n"); fprintf(stderr,"Manipulate the windows clipboard from a DOS box.\n"); fprintf(stderr,"Usage:\n"); fprintf(stderr," toclip infile - Append infile to clipboard\n"); fprintf(stderr," toclip -c infile - Copy infile to clipboard\n"); fprintf(stderr," program | toclip - Append program output to clipboard\n"); fprintf(stderr," program | toclip -c - Copy program output to clipboard\n"); fprintf(stderr," toclip -e - Erase clipboard\n"); fprintf(stderr," toclip -p - Print clipboard to stdout\n"); fprintf(stderr," toclip -p >outfile - Print clipboard to outfile\n"); fprintf(stderr," toclip -p >>outfile - Append clipboard to outfile\n"); fprintf(stderr," toclip -p | program - Pipe clipboard binary to program\n"); fprintf(stderr," toclip -p outfile - Copy clipboard binary to outfile\n"); fprintf(stderr," Change -p to -u to translate CRLF->LF (unix outfile)\n"); fprintf(stderr,"Limitations: %u bytes of OEM text\n",BUFsize); } int getclipboard(char * pastebuf, unsigned *sizebuf); int append2Windows(char * pastebuf, unsigned sizebuf); int eraseclipboard(void); char *buf; int main(int argc, char **argv){ FILE *fp; FILE *fo; unsigned int i=0; unsigned int j=0; unsigned int clip; int x=0,sw,xlat; buf=(char *)malloc(BUFsize); if(buf == (char *)0){ fprintf(stderr,"Couldn't allocate %u bytes of conventional memory\n",BUFsize); fprintf(stderr,"Change BUFsize in toclip.c and recompile.\n"); help(); exit(1); } if(argc>3){ help(); exit(0);} sw='a'; fp=fo=0; if(argc>1 && (argv[1][0]=='-' || argv[1][0]=='/')){ if(argc==2) fp=stdin; if(argc==2) fo=stdout; switch(argv[1][1]){ case 'C': case 'c': sw='c'; break; case 'E': case 'e': sw='e'; break; case 'P': case 'p': sw='p'; break; case 'U': case 'u': sw='u'; break; default: help(); exit(0); } } if(sw == 'e') goto killclip; if(sw == 'p' || sw == 'u') goto getclip; if(fp == 0 && argc>1){ fp=fopen(argv[argc-1],"rb"); if(fp == (FILE *)0){ fprintf(stderr,"File %s not found.\n",argv[argc-1]); help(); exit(1); } } if(fp == 0 && argc == 1) fp=stdin; /* Pipe or user error */ getclip: if(sw == 'a' || sw == 'p' || sw == 'u'){ if(getclipboard(buf,&i)){ fprintf(stderr,"Couldn't get clipboard data. Aborting.\n"); help(); exit(1); } } else {buf[0]=0; i=0;} /* Trim any extra junk at end of OEM text */ for(j=i;j>0;--j) { if((int)buf[j-1]== -1 || (int)buf[j-1]== 0) continue; else break; } clip=j; if(sw == 'p' || sw == 'u'){ if(fo == 0 && argc>1){ fo=fopen(argv[argc-1],"r"); if(fo != (FILE *)0){ fclose(fo); fprintf(stderr,"Output file %s exists.\n",argv[argc-1]); fprintf(stderr,"Erase it (Y/N)? "); x=bioskey(0); /* See bios.h */ fprintf(stderr,"\n"); /* debug */ /* fprintf(stderr,"Key =%u\n",x); */ if(x != 5465 && x != 5497){ fprintf(stderr,"Output file not erased. Aborting.\n"); help(); exit(1); } } fo=fopen(argv[argc-1],"wb"); if(fo == (FILE *)0){ fprintf(stderr,"Couldn't open output file %s\n",argv[argc-1]); help(); exit(1); } } if(fo == 0 && argc == 1) fo=stdout; /* Pipe or user error */ #if 0 #define O_BINARY 0x8000 /* no translation */ if(fo == stdout) setmode(fileno(stdout),O_BINARY); #else if(fo == stdout) _binmode(fileno(stdout)); #endif for(xlat=j=0;jLF on output: %d\n",xlat); return(0); } killclip: if(eraseclipboard()){ fprintf(stderr,"Clipboard erase failed. Aborted.\n"); help(); exit(1); } if(sw == 'e'){ fprintf(stderr,"Clipboard erased\n"); return(0);} /* Get chars from the file or from stdin */ /* Convert buffer to OEM text, if the file was STDIN. */ /* But for disk files, do no translation */ j=clip; i=(fp == stdin); if(sw != 'e'){ xlat=0; while(feof(fp)==0){ if(j >= BUFsize-1) break; x=fgetc(fp); if(x == -1) break; /* end of file */ if(i){ if(x == 'Z'-'@') break; /* Act on ctrl-z */ if(x == '\n' && (j==0 || buf[j-1] != '\r')){ buf[j++]='\r'; ++xlat; if(j >= BUFsize-1) break; } } buf[j++]=x; } if(i) fprintf(stderr,"Number of translations of LF->CRLF on input: %d\n",xlat); } if(feof(fp)==0){ if(i!=0 && x == 'Z'-'@') ; else { fprintf(stderr,"Partial read of data: %u bytes\n",j-clip); } if(j >= BUFsize-1){ fprintf(stderr,"Exceeded internal size limit of %u bytes.\n",BUFsize); fprintf(stderr,"Clipboard has incomplete contents.\n"); } } fclose(fp); /* Trim any extra junk at end of OEM text */ for(i=j;i>0;--i) { if((int)buf[i-1]== -1 || (int)buf[i-1]== 0) continue; else break; } #if 0 /* DEBUG: print the buffer to stderr */ for(j=0;jBUFsize)goto dataerror; /* Too much data for us. */ sizebuf[0]=r.x.ax; /* Amount to read to buffer */ if(r.x.ax==0) goto closeclip; /* No data to read */ segread(&sr); sr.es=sr.ds; r.x.bx=(unsigned)pastebuf; /* ES:BX ptr to data */ r.x.ax=0x1705; /* Get clipboard data */ r.x.dx=7; /* Data format is OEM text */ int2fx(); if(RAX == 0) err=1; closeclip: r.x.ax=0x1708; /* Close clipboard */ int2f(); if(RAX == 0){ fprintf(stderr,"Close clip failed\n"); err=1;} return(err); dataerror: fprintf(stderr,"Clipboard data set too large. Aborted.\n"); err=1; goto closeclip; exitError: fprintf(stderr,"Open clip failed\n"); return(1); } /* Erase windows clipboard */ int eraseclipboard(void){ int err=0; r.x.dx=1; /* Check API */ r.x.ax=0x1700; int2f(); if(RAX == 0x1700){ fprintf(stderr,"API not implemented for clipboard\n"); goto exitError; } r.x.ax=0x1701; /* Open Windows Clipboard */ int2f(); if(RAX == 0) goto exitError; r.x.ax=0x1702; /* Clear Windows Clipboard */ int2f(); if(RAX == 0) {fprintf(stderr,"Clear clip failed\n"); err=1;} r.x.ax=0x1708; /* Close clipboard */ int2f(); if(RAX == 0) {fprintf(stderr,"Close clip failed\n"); err=1;} return(err); exitError: fprintf(stderr,"Open clip failed\n"); return(1); }