comparison loadtools/tpinterf.c @ 21:67a39d8914a8

starting work on loadtool
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sat, 04 May 2013 03:47:40 +0000
parents
children aca1948e9713
comparison
equal deleted inserted replaced
20:be293e656a6f 21:67a39d8914a8
1 /*
2 * Target program interface - this module provides some primitives
3 * for communicating programmatically with loadagent and possibly
4 * other target-utils.
5 */
6
7 #include <sys/types.h>
8 #include <sys/time.h>
9 #include <sys/errno.h>
10 #include <string.h>
11 #include <strings.h>
12 #include <stdlib.h>
13
14 extern int errno;
15
16 extern int target_fd;
17
18 /* definition matches ../target-utils/libcommon/cmdentry.c */
19 #define MAXCMD 527
20
21 /*
22 * static buffer between tpinterf_make_cmd and tpinterf_send_cmd
23 *
24 * We store the command with an ending \r\n so we can use it for
25 * matching the received echo as well, hence the sizing of the
26 * buffer.
27 */
28 static char cmdbuf[MAXCMD+2];
29 static int cmdlen;
30
31 static int
32 arg_chars_valid(arg)
33 char *arg;
34 {
35 char *cp;
36
37 for (cp = arg; *cp; cp++)
38 if (*cp < ' ' || *cp > '~')
39 return(0);
40 return(1);
41 }
42
43 /*
44 * This function takes a command for the target in argv form and
45 * converts it to a space-separated continuous string which can be
46 * passed as tty "keyboard" input to the target, enforcing length
47 * and character validity limits in the process. The output is
48 * stored in an internal static buffer for subsequent
49 * tpinterf_send_cmd().
50 *
51 * Return value: 0 if everything OK, or -1 if some constraint is
52 * violated.
53 */
54 tpinterf_make_cmd(argv)
55 char **argv;
56 {
57 int arglen;
58 char **ap, *dp;
59
60 dp = cmdbuf;
61 cmdlen = 0;
62 for (ap = argv; *ap; ap++) {
63 arglen = strlen(*ap);
64 if (ap != argv)
65 arglen++; /* separating space */
66 if (arglen > MAXCMD - cmdlen)
67 return(-1);
68 if (!arg_chars_valid(*ap))
69 return(-1);
70 if (ap != argv)
71 *dp++ = ' ';
72 strcpy(dp, *ap);
73 dp += strlen(*ap);
74 cmdlen += arglen;
75 }
76 *dp++ = '\r';
77 *dp = '\n';
78 return(0);
79 }
80
81 /*
82 * This function sends the previously-constructed command to the target,
83 * and collects the expected response.
84 *
85 * Return value: 0 if successful, -1 on errors (timeout or wrong response)
86 */
87 tpinterf_send_cmd()
88 {
89 char echobuf[MAXCMD+2];
90 fd_set fds;
91 struct timeval tv;
92 int rcvd, cc;
93
94 write(target_fd, cmdbuf, cmdlen + 1);
95 for (rcvd = 0; rcvd < cmdlen + 2; ) {
96 FD_ZERO(&fds);
97 FD_SET(target_fd, &fds);
98 tv.tv_sec = 1;
99 tv.tv_usec = 0;
100 cc = select(target_fd+1, &fds, NULL, NULL, &tv);
101 if (cc < 0) {
102 if (errno == EINTR)
103 continue;
104 perror("select");
105 exit(1);
106 }
107 if (cc < 1)
108 return(-1);
109 cc = read(target_fd, echobuf + rcvd, cmdlen + 2 - rcvd);
110 if (cc <= 0) {
111 perror("read after successful select");
112 exit(1);
113 }
114 rcvd += cc;
115 }
116 if (bcmp(echobuf, cmdbuf, cmdlen + 2))
117 return(-1);
118 else
119 return(0);
120 }
121
122 /*
123 * This functions reads the serial output from the target until a
124 * '=' prompt is received. All intermediate output is passed to
125 * stdout.
126 *
127 * Return value: 0 if '=' prompt received, -1 otherwise (timeout)
128 */
129 tpinterf_pass_output()
130 {
131 char buf[512], *cp;
132 fd_set fds;
133 struct timeval tv;
134 int cc, newline = 1;
135
136 for (;;) {
137 FD_ZERO(&fds);
138 FD_SET(target_fd, &fds);
139 tv.tv_sec = 1;
140 tv.tv_usec = 0;
141 cc = select(target_fd+1, &fds, NULL, NULL, &tv);
142 if (cc < 0) {
143 if (errno == EINTR)
144 continue;
145 perror("select");
146 exit(1);
147 }
148 if (cc < 1)
149 return(-1);
150 cc = read(target_fd, buf, sizeof buf);
151 if (cc <= 0) {
152 perror("read after successful select");
153 exit(1);
154 }
155 for (cp = buf; cc; cp++) {
156 cc--;
157 if (*cp == '=' && newline && !cc)
158 return(0);
159 putchar(*cp);
160 if (*cp == '\n')
161 newline = 1;
162 else
163 newline = 0;
164 }
165 }
166 }