rev |
line source |
nuclear@2
|
1 #include <stdio.h>
|
nuclear@2
|
2 #include <string.h>
|
nuclear@2
|
3 #include <errno.h>
|
nuclear@2
|
4 #include <signal.h>
|
nuclear@2
|
5 #include <limits.h>
|
nuclear@2
|
6 #include <string>
|
nuclear@2
|
7 #include <unistd.h>
|
nuclear@2
|
8 #include <sys/stat.h>
|
nuclear@2
|
9 #include <sys/wait.h>
|
nuclear@2
|
10 #include <fcntl.h>
|
nuclear@2
|
11 #include <termios.h>
|
nuclear@2
|
12 #include "dev.h"
|
nuclear@2
|
13 #include "timer.h"
|
nuclear@2
|
14
|
nuclear@2
|
15 int customer, ticket;
|
nuclear@2
|
16 static int report_inputs, cmd_echo;
|
nuclear@2
|
17 static long last_ticket_msec = LONG_MIN;
|
nuclear@2
|
18
|
nuclear@2
|
19 static void runcmd(const char *cmd);
|
nuclear@2
|
20
|
nuclear@2
|
21 static int fd = -1;
|
nuclear@2
|
22 static FILE *fp;
|
nuclear@2
|
23 static std::string cur_line;
|
nuclear@2
|
24
|
nuclear@2
|
25 int start_dev(const char *devpath)
|
nuclear@2
|
26 {
|
nuclear@2
|
27 if((fd = open(devpath, O_RDWR | O_NONBLOCK)) == -1) {
|
nuclear@2
|
28 fprintf(stderr, "failed to open device: %s: %s\n", devpath, strerror(errno));
|
nuclear@2
|
29 return -1;
|
nuclear@2
|
30 }
|
nuclear@2
|
31 if(isatty(fd)) {
|
nuclear@2
|
32 struct termios term;
|
nuclear@2
|
33
|
nuclear@2
|
34 if(tcgetattr(fd, &term) == -1) {
|
nuclear@2
|
35 perror("failed to retrieve terminal attributes");
|
nuclear@2
|
36 stop_dev();
|
nuclear@2
|
37 return -1;
|
nuclear@2
|
38 }
|
nuclear@2
|
39 term.c_cflag = CS8 | CLOCAL;
|
nuclear@2
|
40 term.c_iflag &= ~(IXON | IXOFF);
|
nuclear@2
|
41 term.c_lflag = 0;
|
nuclear@2
|
42
|
nuclear@2
|
43 cfsetispeed(&term, B38400);
|
nuclear@2
|
44 cfsetospeed(&term, B38400);
|
nuclear@2
|
45
|
nuclear@2
|
46 if(tcsetattr(fd, TCSANOW, &term) == -1) {
|
nuclear@2
|
47 perror("failed to set terminal attributes");
|
nuclear@2
|
48 stop_dev();
|
nuclear@2
|
49 return -1;
|
nuclear@2
|
50 }
|
nuclear@2
|
51 }
|
nuclear@2
|
52
|
nuclear@2
|
53 if(!(fp = fdopen(fd, "r+"))) {
|
nuclear@2
|
54 perror("failed to attach an I/O stream to the device file\n");
|
nuclear@2
|
55 stop_dev();
|
nuclear@2
|
56 return -1;
|
nuclear@2
|
57 }
|
nuclear@2
|
58 setvbuf(fp, 0, _IONBF, 0);
|
nuclear@2
|
59
|
nuclear@2
|
60 return fd;
|
nuclear@2
|
61 }
|
nuclear@2
|
62
|
nuclear@2
|
63 void stop_dev()
|
nuclear@2
|
64 {
|
nuclear@2
|
65 if(fp)
|
nuclear@2
|
66 fclose(fp);
|
nuclear@2
|
67 else if(fd >= 0)
|
nuclear@2
|
68 close(fd);
|
nuclear@2
|
69 }
|
nuclear@2
|
70
|
nuclear@2
|
71
|
nuclear@2
|
72 void proc_dev_input()
|
nuclear@2
|
73 {
|
nuclear@2
|
74 int rdbytes;
|
nuclear@2
|
75 char buf[256];
|
nuclear@2
|
76 static bool skip_line;
|
nuclear@2
|
77
|
nuclear@2
|
78 while((rdbytes = read(fd, buf, sizeof buf - 1)) > 0) {
|
nuclear@2
|
79 buf[rdbytes] = 0;
|
nuclear@2
|
80
|
nuclear@2
|
81 /* ignore our own crap */
|
nuclear@2
|
82 if(memcmp(buf, "OK,", 3) == 0 || memcmp(buf, "ERR,", 4) == 0) {
|
nuclear@2
|
83 skip_line = true;
|
nuclear@2
|
84 }
|
nuclear@2
|
85
|
nuclear@2
|
86 for(int i=0; i<rdbytes; i++) {
|
nuclear@2
|
87 if(buf[i] == '\n' || buf[i] == '\r') {
|
nuclear@2
|
88 if(!cur_line.empty()) {
|
nuclear@2
|
89 runcmd(cur_line.c_str());
|
nuclear@2
|
90 cur_line.clear();
|
nuclear@2
|
91 }
|
nuclear@2
|
92 skip_line = false;
|
nuclear@2
|
93 } else {
|
nuclear@2
|
94 if(!skip_line) {
|
nuclear@2
|
95 cur_line.push_back(buf[i]);
|
nuclear@2
|
96 }
|
nuclear@2
|
97 }
|
nuclear@2
|
98 }
|
nuclear@2
|
99 }
|
nuclear@2
|
100 }
|
nuclear@2
|
101
|
nuclear@2
|
102 void issue_ticket()
|
nuclear@2
|
103 {
|
nuclear@2
|
104 ticket++;
|
nuclear@2
|
105 last_ticket_msec = get_msec();
|
nuclear@2
|
106 if(report_inputs) {
|
nuclear@2
|
107 fprintf(fp, "ticket: %d\n", ticket);
|
nuclear@2
|
108 }
|
nuclear@2
|
109 }
|
nuclear@2
|
110
|
nuclear@2
|
111 void next_customer()
|
nuclear@2
|
112 {
|
nuclear@2
|
113 if(customer < ticket) {
|
nuclear@2
|
114 customer++;
|
nuclear@2
|
115 last_ticket_msec = LONG_MIN;
|
nuclear@2
|
116 if(report_inputs) {
|
nuclear@2
|
117 fprintf(fp, "customer: %d\n", customer);
|
nuclear@2
|
118 }
|
nuclear@2
|
119 }
|
nuclear@2
|
120 }
|
nuclear@2
|
121
|
nuclear@2
|
122 #define VERSTR \
|
nuclear@2
|
123 "Queue system emulator v0.1 by John Tsiombikas <nuclear@member.fsf.org>"
|
nuclear@2
|
124
|
nuclear@2
|
125 static void runcmd(const char *cmd)
|
nuclear@2
|
126 {
|
nuclear@2
|
127 printf("DBG: runcmd(\"%s\")\n", cmd);
|
nuclear@2
|
128
|
nuclear@2
|
129 switch(cmd[0]) {
|
nuclear@2
|
130 case 'e':
|
nuclear@2
|
131 cmd_echo = !cmd_echo;
|
nuclear@2
|
132 fprintf(fp, "OK,turning echo %s\n", cmd_echo ? "on" : "off");
|
nuclear@2
|
133 break;
|
nuclear@2
|
134
|
nuclear@2
|
135 case 'i':
|
nuclear@2
|
136 report_inputs = !report_inputs;
|
nuclear@2
|
137 fprintf(fp, "OK,turning input reports %s\n", report_inputs ? "on" : "off");
|
nuclear@2
|
138 break;
|
nuclear@2
|
139
|
nuclear@2
|
140 case 'v':
|
nuclear@2
|
141 fprintf(fp, "OK,%s\n", VERSTR);
|
nuclear@2
|
142 break;
|
nuclear@2
|
143
|
nuclear@2
|
144 case 'r':
|
nuclear@2
|
145 fprintf(fp, "OK,reseting queues\n");
|
nuclear@2
|
146 customer = 0;
|
nuclear@2
|
147 ticket = 0;
|
nuclear@2
|
148 last_ticket_msec = LONG_MIN;
|
nuclear@2
|
149 break;
|
nuclear@2
|
150
|
nuclear@2
|
151 case 't':
|
nuclear@2
|
152 fprintf(fp, "OK,ticket: %d\r\n", ticket);
|
nuclear@2
|
153 break;
|
nuclear@2
|
154
|
nuclear@2
|
155 case 'c':
|
nuclear@2
|
156 fprintf(fp, "OK,customer: %d\r\n", customer);
|
nuclear@2
|
157 break;
|
nuclear@2
|
158
|
nuclear@2
|
159 case 'q':
|
nuclear@2
|
160 fprintf(fp, "OK,issuing queue ticket\n");
|
nuclear@2
|
161 issue_ticket();
|
nuclear@2
|
162 break;
|
nuclear@2
|
163
|
nuclear@2
|
164 case 'n':
|
nuclear@2
|
165 fprintf(fp, "OK,next customer\n");
|
nuclear@2
|
166 next_customer();
|
nuclear@2
|
167 break;
|
nuclear@2
|
168
|
nuclear@2
|
169 case 'h':
|
nuclear@2
|
170 fprintf(fp, "OK,commands: (e)cho, (v)ersion, (t)icket, (c)ustomer, "
|
nuclear@2
|
171 "(n)ext, (q)ueue, (r)eset, (i)nput-reports, (h)elp.\n");
|
nuclear@2
|
172 break;
|
nuclear@2
|
173
|
nuclear@2
|
174 default:
|
nuclear@2
|
175 fprintf(fp, "ERR,unknown command: %s\n", cmd);
|
nuclear@2
|
176 }
|
nuclear@2
|
177 }
|