Small bug fixes over 0.20.2 -Dan
[wmaker-crm.git] / util / wxcopy.c
blob8e95cd46b6e0cfbb26eab24f65c8a9f5f513ea06
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 <errno.h>
25 #include <X11/Xlib.h>
26 #include <X11/Xatom.h>
29 #define LINESIZE (4*1024)
30 #define MAXDATA (64*1024)
32 void
33 help(char *progn)
35 fprintf
37 stderr,
38 "usage: %s [options] [filename]\n"
39 " -display display\n"
40 " -cutbuffer number\n"
41 " -nolimit\n"
42 " -clearselection\n",
43 progn
47 static int
48 errorHandler(Display *dpy, XErrorEvent *err)
50 /* ignore all errors */
51 return 0;
54 int
55 main(int argc, char **argv)
57 Display *dpy;
58 int i;
59 int buffer=-1;
60 char *filename=NULL;
61 FILE *file=stdin;
62 char *buf=NULL;
63 char *display_name="";
64 int l=0;
65 int buf_len = 0;
66 int limit_check = 1;
67 int clear_selection = 0;
69 for (i=1; i<argc; i++) {
70 if (argv[i][0]=='-') {
71 if (argv[i][1]=='h') {
72 help(argv[0]);
73 exit(0);
74 } else if (strcmp(argv[i],"-cutbuffer")==0) {
75 if (i<argc-1) {
76 i++;
77 if (sscanf(argv[i],"%i", &buffer)!=1) {
78 fprintf(stderr, "%s: could not convert \"%s\" to int\n",
79 argv[0], argv[i]);
80 exit(1);
82 if (buffer<0 || buffer > 7) {
83 fprintf(stderr, "%s: invalid buffer number %i\n",
84 argv[0], buffer);
85 exit(1);
87 } else {
88 help(argv[0]);
89 exit(1);
91 } else if (strcmp(argv[i], "-display")==0) {
92 if (i < argc-1) {
93 display_name = argv[++i];
94 } else {
95 help(argv[0]);
96 exit(1);
98 } else if (strcmp(argv[i],"-clearselection")==0) {
99 clear_selection = 1;
100 } else if (strcmp(argv[i],"-nolimit")==0) {
101 limit_check = 0;
102 } else {
103 help(argv[0]);
104 exit(1);
106 } else {
107 filename = argv[i];
110 if (filename) {
111 file = fopen(filename, "r");
112 if (!file) {
113 char line[1024];
114 sprintf(line, "%s: could not open \"%s\"", argv[0], filename);
115 perror(line);
116 exit(1);
120 dpy = XOpenDisplay(display_name);
121 XSetErrorHandler(errorHandler);
122 if (!dpy) {
123 fprintf(stderr, "%s: could not open display \"%s\"\n", argv[0],
124 XDisplayName(display_name));
125 exit(1);
127 if (buffer<0) {
128 XRotateBuffers(dpy, 1);
129 buffer=0;
131 while (!feof(file)) {
132 char *nbuf;
133 char tmp[LINESIZE+2];
134 int nl=0;
137 * Use read() instead of fgets() to preserve NULs, since
138 * especially since there's no reason to read one line at a time.
140 if ((nl = fread(tmp, 1, LINESIZE, file)) <= 0) {
141 break;
143 if (buf_len == 0) {
144 nbuf = malloc(buf_len = l+nl+1);
146 else {
147 if (buf_len < l+nl+1) {
149 * To avoid terrible performance on big input buffers,
150 * grow by doubling, not by the minimum needed for the
151 * current line.
153 buf_len = 2 * buf_len + nl + 1;
154 nbuf = realloc(buf, buf_len);
156 else {
157 nbuf = buf;
160 if (!nbuf) {
161 fprintf(stderr, "%s: out of memory\n", argv[0]);
162 exit(1);
164 buf=nbuf;
166 * Don't strcat, since it would make the algorithm n-squared.
167 * Don't use strcpy, since it stops on a NUL.
169 memcpy(buf+l, tmp, nl);
170 l+=nl;
171 if (limit_check && l>=MAXDATA) {
172 fprintf
174 stderr,
175 "%s: too much data in input - more than %d bytes\n"
176 " use the -nolimit argument to remove the limit check.\n",
177 argv[0], MAXDATA
179 exit(1);
183 if (clear_selection) {
184 XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime);
186 if (buf) {
187 XStoreBuffer(dpy, buf, l, buffer);
189 XFlush(dpy);
190 XCloseDisplay(dpy);
191 exit(buf == NULL || errno != 0);