00001
00002
00003
00004 #define nil 0
00005 #include <sys/types.h>
00006 #include <stdarg.h>
00007 #include <stdlib.h>
00008 #include <unistd.h>
00009 #include <fcntl.h>
00010 #include <string.h>
00011 #include <errno.h>
00012 #include <sys/asynchio.h>
00013
00014 #if __minix && !__minix_vmd
00015 #define HAS_ASYN 0
00016 #else
00017 #define HAS_ASYN 1
00018 #endif
00019
00020 #if !HAS_ASYN
00021 #include <signal.h>
00022 #endif
00023
00024 #define END 0300
00025 #define ESC 0333
00026 #define ESC_END 0334
00027 #define ESC_ESC 0335
00028
00029 #define PACKLEN 2048
00030 #define SLIPLEN (1 + 2*PACKLEN + 1)
00031
00032
00033 static int fprintf(int fd, const char *format, ...);
00034 #define stderr 2
00035
00036 int main(int argc, char **argv)
00037 {
00038 char *ps_device;
00039 int ps_fd;
00040 int doing[2], discard;
00041 ssize_t r;
00042 #if !HAS_ASYN
00043 pid_t other_pid;
00044 #endif
00045 size_t ps_len[2], sl_len[2];
00046 unsigned char *sl_end;
00047 unsigned char ps_buf[2][PACKLEN];
00048 unsigned char sl_buf[2][SLIPLEN];
00049 asynchio_t asyn;
00050
00051 if (argc != 2) {
00052 fprintf(stderr, "Usage: slip psip-device\n");
00053 exit(1);
00054 }
00055 ps_device= argv[1];
00056
00057 if ((ps_fd= open(ps_device, O_RDWR)) < 0) {
00058 fprintf(stderr, "slip: can't open %s: %s\n",
00059 ps_device, strerror(errno));
00060 exit(1);
00061 }
00062
00063 doing[0]= 1;
00064 discard= 0;
00065 sl_len[0]= 0;
00066 sl_end= nil;
00067 ps_len[0]= 0;
00068
00069 doing[1]= 1;
00070 sl_len[1]= 0;
00071 ps_len[1]= 0;
00072
00073 #if !HAS_ASYN
00074
00075
00076
00077
00078
00079
00080 switch ((other_pid= fork())) {
00081 case -1:
00082 fprintf(stderr, "slip: can't fork: %s\n", strerror(errno));
00083 exit(1);
00084 case 0:
00085
00086 doing[0]= 0;
00087 other_pid= getppid();
00088 break;
00089 default:
00090
00091 doing[1]= 0;
00092 }
00093 #endif
00094
00095 asyn_init(&asyn);
00096
00097 for (;;) {
00098 if (doing[0]) {
00099
00100
00101
00102 while (sl_end != nil && ps_len[0] == 0) {
00103 unsigned char *sp= sl_buf[0];
00104 unsigned char *pp= ps_buf[0];
00105
00106 while (sp < sl_end) {
00107 int c= *sp++;
00108
00109 if (c == ESC) {
00110 switch (*sp++) {
00111 case ESC_ESC:
00112 c= ESC;
00113 break;
00114 case ESC_END:
00115 c= END;
00116 break;
00117 default:
00118
00119 discard= 1;
00120 }
00121 }
00122 if (pp < ps_buf[0] + PACKLEN) {
00123 *pp++ = c;
00124 } else {
00125
00126 discard= 1;
00127 }
00128 }
00129 if (discard) {
00130 discard= 0;
00131 } else {
00132
00133 ps_len[0]= (pp - ps_buf[0]);
00134 }
00135
00136 sl_end++;
00137 sl_len[0] -= (sl_end - sl_buf[0]);
00138 memmove(sl_buf[0], sl_end, sl_len[0]);
00139 sl_end= memchr(sl_buf[0], END, sl_len[0]);
00140 }
00141
00142
00143 if (sl_end == nil && (HAS_ASYN || ps_len[0] == 0)) {
00144 r= asyn_read(&asyn, 0, sl_buf[0] + sl_len[0],
00145 SLIPLEN - sl_len[0]);
00146 if (r > 0) {
00147 sl_end= memchr(sl_buf[0] + sl_len[0], END, r);
00148 sl_len[0]+= r;
00149 if (sl_end == nil && sl_len[0] == SLIPLEN) {
00150
00151 sl_len[0]= 0;
00152 discard= 1;
00153 }
00154 } else
00155 if (r == 0) {
00156 fprintf(stderr, "slip: EOF on serial input\n");
00157 break;
00158 } else
00159 if (errno != ASYN_INPROGRESS) {
00160 fprintf(stderr, "slip: serial input error: %s\n",
00161 strerror(errno));
00162 break;
00163 }
00164 }
00165
00166
00167 if (ps_len[0] > 0) {
00168 r= asyn_write(&asyn, ps_fd, ps_buf[0], ps_len[0]);
00169 if (r == ps_len[0]) {
00170
00171 ps_len[0]= 0;
00172 } else
00173 if (r >= 0) {
00174 fprintf(stderr,
00175 "slip: odd write to %s, tried %u, wrote %d\n",
00176 ps_device, (unsigned) ps_len[0], (int) r);
00177 break;
00178 } else
00179 if (errno != ASYN_INPROGRESS) {
00180 fprintf(stderr, "slip: error writing %s: %s\n",
00181 ps_device, strerror(errno));
00182 break;
00183 }
00184 }
00185 }
00186
00187 if (doing[1]) {
00188
00189 if (ps_len[1] > 0 && sl_len[1] == 0) {
00190 unsigned char *pp= ps_buf[1];
00191 unsigned char *sp= sl_buf[1];
00192
00193 *sp++ = END;
00194 while (ps_len[1] > 0) {
00195 int c= *pp++;
00196 ps_len[1]--;
00197 switch (c) {
00198 case ESC:
00199 *sp++ = ESC;
00200 c= ESC_ESC;
00201 break;
00202 case END:
00203 *sp++ = ESC;
00204 c= ESC_END;
00205 break;
00206 }
00207 *sp++ = c;
00208 }
00209 *sp++ = END;
00210 sl_len[1]= (sp - sl_buf[1]);
00211 }
00212
00213
00214 if (ps_len[1] == 0 && (HAS_ASYN || sl_len[1] == 0)) {
00215 r= asyn_read(&asyn, ps_fd, ps_buf[1], PACKLEN);
00216 if (r > 0) {
00217
00218 ps_len[1]= r;
00219 } else
00220 if (r == 0) {
00221 fprintf(stderr, "slip: EOF on %s\n", ps_device);
00222 break;
00223 } else
00224 if (errno != ASYN_INPROGRESS) {
00225 fprintf(stderr, "slip: error reading %s: %s\n",
00226 ps_device, strerror(errno));
00227 break;
00228 }
00229 }
00230
00231
00232 if (sl_len[1] > 0) {
00233 r= asyn_write(&asyn, 1, sl_buf[1], sl_len[1]);
00234 if (r > 0) {
00235 if ((sl_len[1]-= r) > 0) {
00236 memmove(sl_buf[1], sl_buf[1] + r, sl_len[1]);
00237 }
00238 } else
00239 if (r == 0) {
00240 fprintf(stderr, "slip: EOF on serial output\n");
00241 break;
00242 } else
00243 if (errno != ASYN_INPROGRESS) {
00244 fprintf(stderr, "slip: serial output error: %s\n",
00245 strerror(errno));
00246 break;
00247 }
00248 }
00249 }
00250
00251
00252 if (asyn_wait(&asyn, 0, nil) < 0) {
00253 fprintf(stderr,
00254 "slip: error while waiting for I/O to happen: %s\n",
00255 strerror(errno));
00256 break;
00257 }
00258 }
00259 #if !HAS_ASYN
00260
00261 kill(other_pid, SIGKILL);
00262 #endif
00263 return 1;
00264 }
00265
00266 static int fprintf(int fd, const char *format, ...)
00267
00268 {
00269 int len;
00270 ssize_t r;
00271 const char *fp0, *fp;
00272 va_list ap;
00273
00274 len= 0;
00275 fp= fp0= format;
00276 va_start(ap, format);
00277
00278 while (*fp != 0) {
00279 if (*fp == '%' && memchr("sdu", fp[1], 3) != nil) {
00280 if (fp > fp0) {
00281 if ((r= write(fd, fp0, (fp - fp0))) < 0) return -1;
00282 len+= r;
00283 }
00284 fp++;
00285 fp0= fp+1;
00286
00287 if (*fp == 's') {
00288 char *s= va_arg(ap, char *);
00289
00290 if ((r= write(fd, s, strlen(s))) < 0) return -1;
00291 len+= r;
00292 } else {
00293 int d;
00294 unsigned u;
00295 char a[3 * sizeof(u) + 2];
00296 char *p;
00297
00298 if (*fp == 'd') {
00299 u= d= va_arg(ap, int);
00300 if (d < 0) u= -u;
00301 } else {
00302 u= va_arg(ap, unsigned);
00303 d= 0;
00304 }
00305
00306 p= a + sizeof(a);
00307 *--p= 0;
00308 do *--p= '0' + (u % 10); while ((u /= 10) > 0);
00309
00310 if (d < 0) *--p= '-';
00311 if ((r= write(fd, p, (a + sizeof(a)) - p)) < 0) return -1;
00312 len+= r;
00313 }
00314 }
00315 fp++;
00316 }
00317 if (fp > fp0) {
00318 if ((r= write(fd, fp0, (fp - fp0))) < 0) return -1;
00319 len+= r;
00320 }
00321 va_end(ap);
00322 return len;
00323 }