xsendkey
maintainer swiftgeek
· 6 votes
· scanned 2026-08-03 00:08:14.047287
LOW
View on AUR ↗
Why flagged
The source is a C file from a web archive hosting a historical copy of a legitimate project; building from this source is normal AUR packaging, and the code is visible and non-malicious, so the non-standard host does not constitute a significant risk.
Triggered rules
LOW
AI review downgraded a static finding
llm_review
The static rules flagged this MEDIUM, but an AI model (qwen/qwen3-235b-a22b-07-25) reviewed the full PKGBUILD and judged it LOW (confidence 95%): The source is a C file from a web archive hosting a historical copy of a legitimate project; building from this source is normal AUR packaging, and the code is visible and non-malicious, so the non-standard host does not constitute a significant risk.
1 higher static finding superseded - not the current verdict (shown for transparency)
MEDIUM
source=() URL on a non-standard host
source_untrusted_domain
One or more source=() URLs point to a host outside the trusted allowlist (github.com, gitlab.com, codeberg.org, pypi.org, …).
-
PKGBUILD:10
source=('http://web.archive.org/web/20130528093333/http://people.csail.mit.edu/adonovan/hacks/xsendkey.c')
PKGBUILD
1 offending line(s) highlighted
1
pkgname=xsendkey
2
pkgver=0.0
3
pkgrel=1
4
pkgdesc="A simple tool for generating keypresses in X"
5
arch=('i686' 'x86_64')
6
url="http://people.csail.mit.edu/adonovan/hacks/xsendkey.html"
7
license=('GPL')
8
depends=('glibc' 'libx11')
9
#source=('http://people.csail.mit.edu/adonovan/hacks/xsendkey.c')
10
source=('http://web.archive.org/web/20130528093333/http://people.csail.mit.edu/adonovan/hacks/xsendkey.c')
11
md5sums=('e7a5538a11c33449c88caa8b901a13eb')
12
13
build() {
14
cd "$srcdir"
15
gcc -o xsendkey -lX11 xsendkey.c
16
}
17
18
package ()
19
{
20
cd "$srcdir"
21
install -Dm 755 xsendkey "$pkgdir/usr/bin/xsendkey"
22
}
23
24
# Backup below because site is rly rly old ;)
25
# In case of emergency paste it as xsendkey.c
26
backupfile ()
27
{
28
echo "backup in PKGBUILD" <<BACKUPFILE
29
/*
30
* (C) 2000-2004 Alan Donovan
31
*
32
* Author: Alan Donovan <adonovan@lcs.mit.edu>
33
*
34
* With thanks to: T.Sato <VEF00200@nifty.ne.jp>.
35
* http://member.nifty.ne.jp/tsato/tools/xvkbd-e.html
36
* and: Derek Martin (derek_martin at agilent dot com)
37
* (for -count and XGetInputFocus)
38
* and: Hanno Hecker <h.hecker@bee.de>
39
* (for symbolic keysym and modifier lookup.)
40
*
41
* xsendkey.cxx -- General purpose keypress generator
42
*
43
* This program is free software; you can redistribute it and/or
44
* modify it under the terms of the GNU General Public License
45
* as published by the Free Software Foundation; either version 2
46
* of the License, or any later version.
47
*
48
* This program is distributed in the hope that it will be useful,
49
* but WITHOUT ANY WARRANTY; without even the implied warranty of
50
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
51
* See the GNU General Public License for more details.
52
* <http://www.gnu.org/copyleft/gpl.html>.
53
*
54
* $Id: xsendkey.c,v 1.3 2004/11/11 16:10:01 adonovan Exp $
55
*
56
*/
57
58
#include <stdio.h>
59
#include <stdlib.h>
60
#include <string.h>
61
62
#ifdef WIN32
63
# include "windows_x11.h"
64
#else
65
# define NeedFunctionPrototypes 1
66
# include <X11/Xlib.h>
67
# include <X11/keysym.h>
68
# if XlibSpecificationRelease != 6
69
# error Requires X11R6
70
# endif
71
#endif
72
73
static char *progname = NULL;
74
static char *displayname = NULL;
75
static Window window = 0;
76
static Display *display = NULL;
77
static char keyname[1024];
78
static int shift = 0;
79
static int keysym = 0;
80
81
int MyErrorHandler(Display *my_display, XErrorEvent *event)
82
{
83
fprintf(stderr, "%s: XSendEvent(0x%lx) failed.\n", progname, window);
84
return 1;
85
}
86
87
void SendEvent(XKeyEvent *event)
88
{
89
XSync(display, False);
90
XSetErrorHandler(MyErrorHandler);
91
XSendEvent(display, window, True, KeyPressMask, (XEvent*)event);
92
XSync(display, False);
93
XSetErrorHandler(NULL);
94
}
95
96
void SendKeyPressedEvent(KeySym keysym, unsigned int shift)
97
{
98
XKeyEvent event;
99
100
// Meta not yet implemented (Alt used instead ;->)
101
int meta_mask=0;
102
103
event.display = display;
104
event.window = window;
105
event.root = RootWindow(display, 0); // XXX nonzero screens?
106
event.subwindow = None;
107
event.time = CurrentTime;
108
event.x = 1;
109
event.y = 1;
110
event.x_root = 1;
111
event.y_root = 1;
112
event.same_screen = True;
113
event.type = KeyPress;
114
event.state = 0;
115
116
//
117
// press down shift keys one at a time...
118
//
119
120
if (shift & ShiftMask) {
121
event.keycode = XKeysymToKeycode(display, XK_Shift_L);
122
SendEvent(&event);
123
event.state |= ShiftMask;
124
}
125
if (shift & ControlMask) {
126
event.keycode = XKeysymToKeycode(display, XK_Control_L);
127
SendEvent(&event);
128
event.state |= ControlMask;
129
}
130
131
if (shift & Mod1Mask) {
132
event.keycode = XKeysymToKeycode(display, XK_Alt_L);
133
SendEvent(&event);
134
event.state |= Mod1Mask;
135
}
136
if (shift & meta_mask) {
137
event.keycode = XKeysymToKeycode(display, XK_Meta_L);
138
SendEvent(&event);
139
event.state |= meta_mask;
140
}
141
142
//
143
// Now with shift keys held down, send event for the key itself...
144
//
145
146
147
// fprintf(stderr, "sym: 0x%x, name: %s\n", keysym, keyname);
148
if (keysym != NoSymbol) {
149
event.keycode = XKeysymToKeycode(display, keysym);
150
// fprintf(stderr, "code: 0x%x, %d\n", event.keycode, event.keycode );
151
SendEvent(&event);
152
153
event.type = KeyRelease;
154
SendEvent(&event);
155
}
156
157
//
158
// Now release all the shift keys...
159
//
160
161
if (shift & ShiftMask) {
162
event.keycode = XKeysymToKeycode(display, XK_Shift_L);
163
SendEvent(&event);
164
event.state &= ~ShiftMask;
165
}
166
if (shift & ControlMask) {
167
event.keycode = XKeysymToKeycode(display, XK_Control_L);
168
SendEvent(&event);
169
event.state &= ~ControlMask;
170
}
171
if (shift & Mod1Mask) {
172
event.keycode = XKeysymToKeycode(display, XK_Alt_L);
173
SendEvent(&event);
174
event.state &= ~Mod1Mask;
175
}
176
if (shift & meta_mask) {
177
event.keycode = XKeysymToKeycode(display, XK_Meta_L);
178
SendEvent(&event);
179
event.state &= ~meta_mask;
180
}
181
}
182
183
void usage()
184
{
185
fprintf(stderr,
186
"usage: %s [-window <id>|root]\n"
187
" [-count <count>]\n"
188
" [-display <name>] [Modifier+[Modifier+]]Key\n"
189
"(looks up keysyms in <X11/keysymdef.h>)\n"
190
"'Alt', 'Control', 'Shift' are replaced by\n"
191
"'Alt_L', 'Control_L', 'Shift_L'...\n"
192
" example:\n"
193
" %s Control+Alt+Right\n", progname, progname);
194
exit(1);
195
}
196
197
int main(int argc, char **argv)
198
{
199
int ii, Junk;
200
int c;
201
char *temp;
202
unsigned long count = 1;
203
progname = argv[0];
204
205
for(ii=1; ii<argc; ii++) {
206
if(strcmp(argv[ii], "-display") == 0) {
207
if(++ii == argc)
208
usage();
209
210
displayname = argv[ii];
211
}
212
else if(strcmp(argv[ii], "-count") == 0) {
213
if(++ii == argc)
214
usage();
215
216
count = strtoul(argv[ii],NULL,0);
217
}
218
else if(strcmp(argv[ii], "-window") == 0) {
219
if(++ii == argc)
220
usage();
221
222
if(strcmp(argv[ii], "root") == 0)
223
window = (Window)-1;
224
else
225
window = (Window)strtoul(argv[ii], NULL, 0);
226
}
227
else if(argv[ii][0] == '-') {
228
fprintf(stderr, "%s: bad option `%s'.\n",
229
progname, argv[ii]);
230
usage();
231
}
232
else {
233
strncpy(keyname, argv[ii], 1023);
234
keysym = 0;
235
shift = 0;
236
// fprintf(stderr, "keyname: %s\n", keyname);
237
temp = strtok((char *)keyname, "+");
238
while (temp != NULL) {
239
// fprintf(stderr, "temp: %s\n", temp);
240
if (strcmp(temp, "Alt") == 0)
241
c = XK_Alt_L;
242
else if (strcmp(temp, "Control") == 0)
243
c = XK_Control_L;
244
else if (strcmp(temp, "Shift") == 0)
245
c = XK_Shift_L;
246
else
247
c = XStringToKeysym(temp);
248
249
if (c == 0) {
250
fprintf(stderr, "unknown: %s\n", temp);
251
usage();
252
}
253
254
switch (c) {
255
case XK_Shift_L:
256
case XK_Shift_R:
257
shift |= ShiftMask;
258
break;
259
case XK_Control_L:
260
case XK_Control_R:
261
shift |= ControlMask;
262
break;
263
case XK_Caps_Lock:
264
case XK_Shift_Lock:
265
shift |= LockMask;
266
break;
267
case XK_Meta_L:
268
case XK_Meta_R:
269
case XK_Alt_L:
270
case XK_Alt_R:
271
shift |= Mod1Mask;
272
break;
273
case XK_Super_L:
274
case XK_Super_R:
275
case XK_Hyper_L:
276
case XK_Hyper_R:
277
break;
278
default:
279
keysym = c;
280
}
281
// fprintf(stderr, "keysym: 0x%x, shift: %d\n", keysym, shift);
282
temp = strtok(NULL, "+");
283
}
284
/* keysym = strtoul(argv[ii], NULL, 0); */
285
}
286
}
287
if (keyname[0] == 0) {
288
fprintf(stderr, "%s: you must specify a keyname.\n", progname);
289
exit(1);
290
}
291
292
if(displayname == NULL)
293
displayname = getenv("DISPLAY");
294
295
if(displayname == NULL)
296
displayname = ":0.0";
297
298
display = XOpenDisplay(displayname);
299
300
if(display == NULL)
301
{
302
fprintf(stderr, "%s: can't open display `%s'.\n",
303
progname, displayname);
304
exit(1);
305
}
306
307
if(window == 0)
308
XGetInputFocus(display, &window, &Junk);
309
310
if(window == (Window)-1)
311
{
312
window = RootWindow(display, 0); // XXX nonzero screens?
313
}
314
315
// now do the work:
316
for (ii=0;ii<(int)count;ii++)
317
SendKeyPressedEvent(keysym, shift);
318
319
XCloseDisplay(display);
320
321
return 0;
322
}
323
324
BACKUPFILE
325
}
326
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-08-03 00:08:14 | LOW | 2 |
| 2026-08-02 00:16:08 | LOW | 2 |
| 2026-08-01 00:11:18 | LOW | 2 |
| 2026-07-31 00:14:10 | LOW | 2 |
| 2026-07-30 00:17:23 | LOW | 2 |
| 2026-07-29 00:25:53 | LOW | 2 |
| 2026-07-28 00:07:28 | LOW | 2 |
| 2026-07-27 00:24:32 | LOW | 2 |
| 2026-07-26 00:07:32 | LOW | 2 |
| 2026-07-25 00:13:44 | LOW | 2 |
| 2026-07-24 00:02:28 | LOW | 2 |
| 2026-07-23 00:14:47 | LOW | 2 |
| 2026-07-22 00:29:32 | LOW | 2 |
| 2026-07-21 00:24:15 | LOW | 2 |
| 2026-07-20 00:19:49 | LOW | 2 |
| 2026-07-19 00:17:08 | LOW | 2 |
| 2026-07-18 00:14:48 | LOW | 2 |
| 2026-07-17 00:06:16 | LOW | 2 |
| 2026-07-16 00:05:41 | LOW | 2 |
| 2026-07-15 00:09:25 | LOW | 2 |