cnmagic.c revision 1.1 1 /* $NetBSD: cnmagic.c,v 1.1 2000/11/08 22:41:59 eeh Exp $ */
2
3 /*
4 * Copyright (c) 2000 Eduardo Horvath
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Eduardo Horvath.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35
36 #define ENCODE_STATE(c, n) (short)(((c)&0x1ff)|(((n)&0x7f)<<9))
37
38 static unsigned short cn_magic[CNS_LEN];
39
40 /*
41 * Initialize a cnm_state_t.
42 */
43 void
44 cn_init_magic(cnm_state_t *cnm) {
45 cnm->cnm_state = 0;
46 cnm->cnm_magic = cn_magic;
47 }
48
49 /*
50 * Destroy a cnm_state_t.
51 */
52 void
53 cn_destroy_magic(cnm_state_t *cnm) {
54 cnm->cnm_state = 0;
55 cnm->cnm_magic = NULL;
56 }
57
58 /*
59 * Translate a magic string to a state
60 * machine table.
61 */
62 int
63 cn_set_magic(char *magic)
64 {
65 unsigned int i, c, n;
66 unsigned short m[CNS_LEN];
67
68 for (i=0; i<CNS_LEN; i++) {
69 c = (*magic++)&0xff;
70 n = *magic ? i+1 : CNS_TERM;
71 switch (c) {
72 case 0:
73 /* End of string */
74 if (i == 0) {
75 /* empty string? */
76 cn_magic[0] = 0;
77 #ifdef DEBUG
78 printf("cn_set_magic(): empty!\n");
79 #endif
80 return (0);
81 }
82 do {
83 cn_magic[i] = m[i];
84 } while (i--);
85 return(0);
86 case 0x27:
87 /* Escape sequence */
88 c = (*magic++)&0xff;
89 n = *magic ? i+1 : CNS_TERM;
90 switch (c) {
91 case 0x27:
92 break;
93 case 0x01:
94 /* BREAK */
95 c = CNC_BREAK;
96 break;
97 case 0x02:
98 /* NUL */
99 c = 0;
100 break;
101 }
102 /* FALLTHROUGH */
103 default:
104 /* Transition to the next state. */
105 #ifdef DEBUG
106 printf("mag %d %x:%x\n", i, c, n);
107 #endif
108 m[i] = ENCODE_STATE(c, n);
109 break;
110 }
111 }
112 return (EINVAL);
113 }
114
115 /*
116 * Translatea state machine table back to
117 * a magic string.
118 */
119 int
120 cn_get_magic(char *magic, int maglen) {
121 unsigned int i, c;
122
123 for (i=0; i<CNS_LEN; i++) {
124 c = cn_magic[i];
125 /* Translate a character */
126 switch (CNS_MAGIC_VAL(c)) {
127 case CNC_BREAK:
128 *magic++ = 0x27;
129 *magic++ = 0x01;
130 break;
131 case 0:
132 *magic++ = 0x27;
133 *magic++ = 0x02;
134 break;
135 case 0x27:
136 *magic++ = 0x27;
137 *magic++ = 0x27;
138 break;
139 default:
140 *magic++ = (c&0x0ff);
141 break;
142 }
143 /* Now go to the next state */
144 i = CNS_MAGIC_NEXT(c);
145 if (i == CNS_TERM || i == 0) {
146 /* Either termination state or empty machine */
147 *magic++ = 0;
148 return (0);
149 }
150 }
151 return (EINVAL);
152 }
153
154