-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.c
160 lines (134 loc) · 3.97 KB
/
lib.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <sgtty.h>
#include <stdio.h>
#include <unistd.h>
#include <varargs.h>
#include <sys/select.h>
#include <sys/time.h>
#include "lib.h"
/*
* In 2.11BSD K&R C on the PDP-11, vsscanf() is missing. This version is implemented exactly the
* way I think it would have been based on the implementation of scanf, fscanf and sscanf in stdio.
* As is the case in the stdio-supplied sscanf, the actual work is done by a library-internal
* _doscan() function. Its first argument is a pointer to a FILE structure, in which the string to
* read from is loaded.
*/
int vsscanf(str, fmt, args)
char *str, *fmt;
va_list args;
{
FILE _strbuf;
_strbuf._flag = _IOREAD|_IOSTRG;
_strbuf._ptr = _strbuf._base = str;
_strbuf._cnt = 0;
while (*str++)
_strbuf._cnt++;
_strbuf._bufsiz = _strbuf._cnt;
return _doscan(&_strbuf, fmt, args);
}
#define TIMEOUT 100000
/* Function to figure out what is really going on when getkeypress() reads Escape (ASCII 27).
Basically meant for use by getkeypress only. */
int _handle_escape_key()
{
int ch;
struct timeval tv;
struct fd_set readfds;
/* Set up the timeout */
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
tv.tv_sec = 0;
tv.tv_usec = TIMEOUT;
/* Check if more input is available within the timeout */
ch = select(1, &readfds, NULL, NULL, &tv);
if (!ch) return KEY_ESCAPE;
switch (getchar())
{
case '[':
ch = getchar();
/* Arrow keys */
if (ch >= 'A' && ch <= 'D')
return 'A' - ch - 1;
if (ch == 'H') return KEY_HOME;
if (ch == 'Z') return KEY_STAB;
if (ch >= '1' && ch <= '9')
{
if (getchar() == '~')
{
/* Home, Insert, Delete, End, PgUp, PgDn */
if (ch >= '1' && ch <= '6')
return '1' - ch + KEY_HOME;
return KEY_UNHANDLED;
}
/* Numeric escape codes always end with ~ */
while (getchar() != '~');
}
break;
case 'O': /* We can get this after an Escape, but we don't handle these.
So, we pull the next character that inevitably follows and move on.*/
getchar();
break;
}
return KEY_UNHANDLED;
}
/*
* Slightly more useable version of getchar() that understands Escape and certain
* escape key sequences as generated in the context of vt320. It responds to
* Ctrl-C by exiting the program with a friendly message.
*/
int getkeypress()
{
int ch;
struct sgttyb old_term, new_term;
/* Set up terminal for non-blocking input */
ioctl(STDIN_FILENO, TIOCGETP, &old_term);
new_term = old_term;
new_term.sg_flags |= RAW;
new_term.sg_flags &= ~ECHO;
ioctl(STDIN_FILENO, TIOCSETP, &new_term);
ch = getchar();
if (ch == 27)
ch = _handle_escape_key();
if (ch == 3) /* Ctrl-C */
{
puts("Bye!");
exit(0);
}
/* Reset terminal to normal mode */
ioctl(STDIN_FILENO, TIOCSETP, &old_term);
return ch;
}
/*
* Simple version of memmove(), which is missing in 2.11BSD K&R C. Specifically
* meant to copy memory when source and destination overlap.
*/
void memshift(dest, src, len)
char *dest, *src;
int len;
{
if (dest == src || len == 0)
return;
if (dest < src)
while (len--)
*dest++ = *src++;
else
{
dest += len;
src += len;
while (len--)
*--dest = *--src;
}
}
/*
* VERY simple text obfuscation function. It's not meant to be secure, just
* to make it a bit harder to read the strings in the data files that come
* with the game. It basically inverts each character in the ASCII printable
* range within the boundaries of that range (32-126, or "space" to ~).
* Problems are likely if the input string contains characters outside that
* range, but none of the game strings do.
*/
void fuzzle(str)
char *str;
{
for (; *str && *str != '\n'; str++)
*str = 158 - *str;
}