Updating to version 0.20.2
[wmaker-crm.git] / util / wxcopy.c
blobce43a1be83c45f71540934d28c43d763361738dd
1 /* wxcopy.c- copy stdin or file into cutbuffer
2 *
3 * Copyright (c) 1997 Alfredo K. Kojima
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <X11/Xlib.h>
25 #include <X11/Xatom.h>
28 #define LINESIZE (4*1024)
29 #define MAXDATA (64*1024)
31 void
32 help(char *progn)
34 fprintf
36 stderr,
37 "usage: %s [options] [filename]\n"
38 " -display display\n"
39 " -cutbuffer number\n"
40 " -nolimit\n"
41 " -clearselection\n",
42 progn
46 static int
47 errorHandler(Display *dpy, XErrorEvent *err)
49 /* ignore all errors */
50 return 0;
53 int
54 main(int argc, char **argv)
56 Display *dpy;
57 int i;
58 int buffer=-1;
59 char *filename=NULL;
60 FILE *file=stdin;
61 char *buf=NULL;
62 char *display_name="";
63 int l=0;
64 int buf_len = 0;
65 int limit_check = 1;
66 int clear_selection = 0;
68 for (i=1; i<argc; i++) {
69 if (argv[i][0]=='-') {
70 if (argv[i][1]=='h') {
71 help(argv[0]);
72 exit(0);
73 } else if (strcmp(argv[i],"-cutbuffer")==0) {
74 if (i<argc-1) {
75 i++;
76 if (sscanf(argv[i],"%i", &buffer)!=1) {
77 fprintf(stderr, "%s: could not convert \"%s\" to int\n",
78 argv[0], argv[i]);
79 exit(1);
81 if (buffer<0 || buffer > 7) {
82 fprintf(stderr, "%s: invalid buffer number %i\n",
83 argv[0], buffer);
84 exit(1);
86 } else {
87 help(argv[0]);
88 exit(1);
90 } else if (strcmp(argv[i], "-display")==0) {
91 if (i < argc-1) {
92 display_name = argv[++i];
93 } else {
94 help(argv[0]);
95 exit(1);
97 } else if (strcmp(argv[i],"-clearselection")==0) {
98 clear_selection = 1;
99 } else if (strcmp(argv[i],"-nolimit")==0) {
100 limit_check = 0;
101 } else {
102 help(argv[0]);
103 exit(1);
105 } else {
106 filename = argv[i];
109 if (filename) {
110 file = fopen(filename, "r");
111 if (!file) {
112 char line[1024];
113 sprintf(line, "%s: could not open \"%s\"", argv[0], filename);
114 perror(line);
115 exit(1);
119 dpy = XOpenDisplay(display_name);
120 XSetErrorHandler(errorHandler);
121 if (!dpy) {
122 fprintf(stderr, "%s: could not open display \"%s\"\n", argv[0],
123 XDisplayName(display_name));
124 exit(1);
126 if (buffer<0) {
127 XRotateBuffers(dpy, 1);
128 buffer=0;
130 while (!feof(file)) {
131 char *nbuf;
132 char tmp[LINESIZE+2];
133 int nl=0;
136 * Use read() instead of fgets() to preserve NULs, since
137 * especially since there's no reason to read one line at a time.
139 if ((nl = fread(tmp, 1, LINESIZE, file)) <= 0) {
140 break;
142 if (buf_len == 0) {
143 nbuf = malloc(buf_len = l+nl+1);
145 else {
146 if (buf_len < l+nl+1) {
148 * To avoid terrible performance on big input buffers,
149 * grow by doubling, not by the minimum needed for the
150 * current line.
152 buf_len = 2 * buf_len + nl + 1;
153 nbuf = realloc(buf, buf_len);
155 else {
156 nbuf = buf;
159 if (!nbuf) {
160 fprintf(stderr, "%s: out of memory\n", argv[0]);
161 exit(1);
163 buf=nbuf;
165 * Don't strcat, since it would make the algorithm n-squared.
166 * Don't use strcpy, since it stops on a NUL.
168 memcpy(buf+l, tmp, nl);
169 l+=nl;
170 if (limit_check && l>=MAXDATA) {
171 fprintf
173 stderr,
174 "%s: too much data in input - more than %d bytes\n"
175 " use the -nolimit argument to remove the limit check.\n",
176 argv[0], MAXDATA
178 exit(1);
182 if (clear_selection) {
183 XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime);
185 if (buf) {
186 XStoreBuffer(dpy, buf, l, buffer);
188 XFlush(dpy);
189 XCloseDisplay(dpy);
190 exit(buf == NULL || errno != 0);