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
21aid_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
88int
89tty3270_aid_init(tub_t *tubp)
90{
91	memcpy(tubp->tty_aid, aidtab, sizeof aidtab);
92	tubp->tty_aidinit = 1;
93	return 0;
94}
95
96void
97tty3270_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
114void
115tty3270_aid_reinit(tub_t *tubp)
116{
117	tty3270_aid_fini(tubp);
118	tty3270_aid_init(tubp);
119}
120
121int
122tty3270_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 */
137int
138tty3270_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