1 /*
2  *  IBM/3270 Driver -- Copyright (C) 2000 UTS Global LLC
3  *
4  *  tubttyaid.c -- Linemode Attention-ID functionality
5  *
6  *
7  *
8  *
9  *
10  *  Author:  Richard Hitt
11  */
12 #include "tubio.h"
13 
14 #define PA1_STR "^C"
15 #define PF3_STR "^D"
16 #define PF9_STR "\033j"
17 #define PF10_STR "\033k"
18 #define PF11_STR "\033j"
19 /* other AID-key default strings */
20 
21 aid_t aidtab[64] = {
22 /* 00         */	{ 0, 0 },
23 /* C1 = PF13  */	{ TA_DOSTRING, 0 },
24 /* C2 = PF14  */	{ TA_DOSTRING, 0 },
25 /* C3 = PF15  */	{ TA_DOSTRING, 0 },
26 /* C4 = PF16  */	{ TA_DOSTRING, 0 },
27 /* C5 = PF17  */	{ TA_DOSTRING, 0 },
28 /* C6 = PF18  */	{ TA_DOSTRING, 0 },
29 /* C7 = PF19  */	{ TA_DOSTRING, 0 },
30 /* C8 = PF20  */	{ TA_DOSTRING, 0 },
31 /* C9 = PF21  */	{ TA_DOSTRING, 0 },
32 /* 4A = PF22  */	{ TA_DOSTRING, 0 },
33 /* 4B = PF23  */	{ TA_DOSTRING, 0 },
34 /* 4C = PF24  */	{ TA_DOSTRING, 0 },
35 /* 0D         */	{ 0, 0 },
36 /* 0E         */	{ 0, 0 },
37 /* 0F         */	{ 0, 0 },
38 /* 10         */	{ 0, 0 },
39 /* 11         */	{ 0, 0 },
40 /* 12         */	{ 0, 0 },
41 /* 13         */	{ 0, 0 },
42 /* 14         */	{ 0, 0 },
43 /* 15         */	{ 0, 0 },
44 /* 16         */	{ 0, 0 },
45 /* 17         */	{ 0, 0 },
46 /* 18         */	{ 0, 0 },
47 /* 19         */	{ 0, 0 },
48 /* 1A         */	{ 0, 0 },
49 /* 1B         */	{ 0, 0 },
50 /* 1C         */	{ 0, 0 },
51 /* 1D         */	{ 0, 0 },
52 /* 1E         */	{ 0, 0 },
53 /* 1F         */	{ 0, 0 },
54 /* 60 = NoAID */	{ 0, 0 },
55 /* 21         */	{ 0, 0 },
56 /* 22         */	{ 0, 0 },
57 /* 23         */	{ 0, 0 },
58 /* 24         */	{ 0, 0 },
59 /* 25         */	{ 0, 0 },
60 /* E6 = OpRdr */	{ 0, 0 },
61 /* E7 = MSRdr */	{ 0, 0 },
62 /* E8 = NoAID */	{ 0, 0 },
63 /* 29         */	{ 0, 0 },
64 /* 2A         */	{ 0, 0 },
65 /* 6B =  PA3  */        { TA_SHORTREAD, 0 },
66 /* 6C =  PA1  */        { TA_SHORTREAD | TA_DOSTRING, PA1_STR },
67 /* 6D = CLEAR */        { TA_SHORTREAD | TA_CLEARKEY, 0 },
68 /* 6E =  PA2  */        { TA_SHORTREAD | TA_CLEARLOG, 0 },
69 /* 2F         */	{ 0, 0 },
70 /* F0 = TstRq */        { 0, 0 },
71 /* F1 =  PF1  */	{ TA_DOSTRING, 0 },
72 /* F2 =  PF2  */	{ TA_DOSTRING, 0 },
73 /* F3 =  PF3  */        { TA_DOSTRING, PF3_STR },
74 /* F4 =  PF4  */	{ TA_DOSTRING, 0 },
75 /* F5 =  PF5  */	{ TA_DOSTRING, 0 },
76 /* F6 =  PF6  */	{ TA_DOSTRING, 0 },
77 /* F7 =  PF7  */	{ TA_DOSTRING, 0 },
78 /* F8 =  PF8  */	{ TA_DOSTRING, 0 },
79 /* F9 =  PF9  */        { TA_DOSTRING, PF9_STR },
80 /* 7A = PF10  */        { TA_DOSTRING, PF10_STR },
81 /* 7B = PF11  */        { TA_DOSTRING, PF11_STR },
82 /* 7C = PF12  */	{ TA_DOSTRING, 0 },
83 /* 7D = ENTER */        { TA_DOENTER, 0 },
84 /* 7E = Pen   */        { 0, 0 },
85 /* 3F         */	{ 0, 0 },
86 };
87 
88 int
tty3270_aid_init(tub_t * tubp)89 tty3270_aid_init(tub_t *tubp)
90 {
91 	memcpy(tubp->tty_aid, aidtab, sizeof aidtab);
92 	tubp->tty_aidinit = 1;
93 	return 0;
94 }
95 
96 void
tty3270_aid_fini(tub_t * tubp)97 tty3270_aid_fini(tub_t *tubp)
98 {
99 	int i;
100 	char *sp;
101 
102 	if (tubp->tty_aidinit == 0)
103 		return;
104 	for (i = 0; i < 64; i++) {
105 		if ((sp = tubp->tty_aid[i].string) == NULL)
106 			continue;
107 		if (sp == aidtab[i].string)
108 			continue;
109 		kfree(sp);
110 	}
111 	tubp->tty_aidinit = 0;
112 }
113 
114 void
tty3270_aid_reinit(tub_t * tubp)115 tty3270_aid_reinit(tub_t *tubp)
116 {
117 	tty3270_aid_fini(tubp);
118 	tty3270_aid_init(tubp);
119 }
120 
121 int
tty3270_aid_get(tub_t * tubp,int aid,int * aidflags,char ** aidstring)122 tty3270_aid_get(tub_t *tubp, int aid, int *aidflags, char **aidstring)
123 {
124 	aid_t *ap;
125 
126 	ap = AIDENTRY(aid, tubp);
127 	*aidflags = ap->aid;
128 	*aidstring = ap->string;
129 	return 0;
130 }
131 
132 /*
133  * tty3270_aid_set() -- write_proc extension
134  * Parse written string as an AID name.  Return 0 if it's not.
135  * Otherwise absorb the string and return count or -error.
136  */
137 int
tty3270_aid_set(tub_t * tubp,char * buf,int count)138 tty3270_aid_set(tub_t *tubp, char *buf, int count)
139 {
140 	char name[8];
141 	char *sp;
142 	int aidn, aidx;
143 	aid_t *ap;
144 	int len;
145 	char *pfp;
146 
147 	if (tubp->tty_aidinit == 0)
148 		return 0;
149 	if (count < 3)          /* If AID-key name too short */
150 		return 0;
151 	name[0] = buf[0] < 0x60? buf[0]: (buf[0] & 0x5f);
152 	name[1] = buf[1] < 0x60? buf[1]: (buf[1] & 0x5f);
153 	if (name[0] == 'P' && name[1] == 'F') {
154 		aidn = simple_strtoul(buf+2, &sp, 10);
155 		if (aidn < 1 || aidn > 24)
156 			return 0;
157 		aidx = aidn > 12? aidn - 12: aidn + 0x30;
158 		ap = &tubp->tty_aid[aidx];
159 	} else if (name[0] == 'P' && name[1] == 'A') {
160 		aidn = simple_strtoul(buf+2, &sp, 10);
161 		if (aidn < 1 || aidn > 3)
162 			return 0;
163 		switch(aidn) {
164 		case 1:  aidx = 0x2c; break;
165 		case 2:  aidx = 0x2e; break;
166 		case 3:  aidx = 0x2b; break;
167 		default:  aidx = 0; break;
168 		}
169 		ap = &tubp->tty_aid[aidx];
170 	} else {
171 		return 0;
172 	}
173 
174 	if (*sp == '\0') {
175 		tubp->tty_showaidx = ap - tubp->tty_aid;
176 		return count;
177 	} else if (*sp == '=') {
178 		len = strlen(++sp);
179 		if (len == 0) {
180 			if (ap->string != NULL &&
181 			    ap->string != aidtab[aidx].string)
182 				kfree(ap->string);
183 			ap->string = aidtab[aidx].string;
184 			ap->aid = aidtab[aidx].aid;
185 			return count;
186 		}
187 		if ((pfp = kmalloc(len + 1, GFP_KERNEL)) == NULL)
188 			return -ENOMEM;
189 		if (ap->string != NULL &&
190 		    ap->string != aidtab[aidx].string)
191 			kfree(ap->string);
192 		if (sp[len - 1] == '\n') {
193 			ap->aid = TA_DOSTRING;
194 			sp[len - 1] = '\0';
195 			len--;
196 		} else {
197 			ap->aid = TA_DOSTRINGD;
198 		}
199 		memcpy(pfp, sp, len + 1);
200 		ap->string = pfp;
201 		return count;
202 	} else {
203 		return -EINVAL;
204 	}
205 }
206