version 0.2.0
[expresskeys.git] / src-server / config_read.c
1 /*
2  config_read.c -- Support ExpressKeys & Touch Strips on a Wacom Intuos3 tablet.
3  
4  Copyright (C) 2005 - Mats Johannesson
5  
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15  
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
19 */
20
21 #include "globals.h"
22
23 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24  Function reads a configuration file containing program names and
25  definitions of which keys that should be mapped to pad buttons and
26  touch strips. It takes a file pointer and a pointer to a global
27  structure as input. Returns nothing unless an error occured.
28  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
29
30 int read_file_config(int *ip, FILE *fp)
31 {
32
33         struct program *p;
34         p = (void *)*ip;
35
36         int i;
37         int num_record = 0;
38         int num_field = 0;
39         
40         int *field_index = 0;
41
42         char buffer [MAXBUFFER];
43         char line_buffer [MAXBUFFER];
44         const char ignore[] = " \t\n";
45         const char *delimiter_first, *delimiter_last;
46         char *token;
47
48 /* Previously allocated memory for the program names must be released
49    on subsequent reads of the config file. At program start the flag is 0 */
50
51         if (reread_config) {
52                 for (i = 0; i < num_list; i++, p++) {
53                         free(p->class_name);
54                 }
55                 p = (void *)*ip;
56         }
57         reread_config = 1;
58         num_list = 0;
59
60 /* Begin by making sure that the Config File Version number is present before
61    a record begins. We exit if it's lacking or the number doesn't match up */
62
63 /* FIXME Unpredictable behaviour on lines longer than MAXBUFFER! */
64
65         while ((fgets(line_buffer, MAXBUFFER, fp)) != NULL) {
66                 if ((delimiter_first = (strchr(line_buffer, '#'))) != NULL) {
67                         strncpy(buffer, line_buffer, ((delimiter_first) - (line_buffer)));
68                         strncpy(buffer + ((delimiter_first) - (line_buffer)), "\0", 1);
69                         strcpy(line_buffer, buffer);
70                 }
71                 if ((delimiter_first = (strchr(line_buffer, '%'))) != NULL &&
72                 (delimiter_last = (strrchr(line_buffer, '%'))) != NULL &&
73                 (delimiter_last != delimiter_first)) {
74                         return 3;
75                 }
76                 if ((delimiter_first = (strchr(line_buffer, ':'))) != NULL) {
77                         strcpy(buffer, line_buffer);
78                         token = strtok(buffer, ":");
79                         token = strtok(NULL, ignore);
80                         strcpy(buffer, token);
81                         if ((atoi(buffer)) != CONFIG_VERSION) {
82                                 return 3;
83                         }
84                         break;
85                 }
86         }
87
88 /* Read the config file in one go from top to bottom. Parse out the info
89    between record start "%%" and record end "%%". Recognize field beginnings
90    by a colon ":". Each full record is written to a global memory structure,
91    while partial records are discarded and excessive fields are truncated.
92    No sanity check on program names or keycode functionality is performed
93    A global counter variable of full record instances is updated before the
94    function exits to reflect the new state. */
95
96 /* FIXME Unpredictable behaviour on lines longer than MAXBUFFER! */
97
98         while ((fgets(line_buffer, MAXBUFFER, fp)) != NULL) {
99                 if (num_record < MAXRECORDS) {
100                         if ((delimiter_first = (strchr(line_buffer, '#'))) != NULL) {
101                                 strncpy(buffer, line_buffer, ((delimiter_first) - (line_buffer)));
102                                 strncpy(buffer + ((delimiter_first) - (line_buffer)), "\0", 1);
103                                 strcpy(line_buffer, buffer);
104                         }
105                         if ((delimiter_first = (strchr(line_buffer, '%'))) == NULL &&
106                         (delimiter_last = (strrchr(line_buffer, '%'))) == NULL &&
107                         (delimiter_last == delimiter_first)) {
108                                 if ((delimiter_first = (strchr(line_buffer, ':'))) != NULL) {
109                                         if ((delimiter_first = (strchr(line_buffer, '"'))) != NULL) {
110                                                 strcpy(buffer, line_buffer);
111                                                 token = strtok(buffer, "\t\n");
112                                                 while ((delimiter_first = (strchr(token, '"'))) == NULL) {
113                                                         token = strtok(NULL, "\t\n");
114                                                 }
115                                                 if (((delimiter_last = (strrchr(token, '"'))) != NULL) &&
116                                                 (delimiter_last != delimiter_first)) {
117                                                         strncpy(buffer, delimiter_first+1, ((delimiter_last) - (delimiter_first + 1)));
118                                                         strncpy(buffer + ((delimiter_last) - (delimiter_first + 1)), "\0", 1);
119                                                         if ((p->class_name = (char *)malloc(strlen(buffer)+1)) == NULL) {
120                                                                 return 2;
121                                                         }
122                                                         sprintf(p->class_name, "%s", buffer);
123                                                         if (be_verbose) {
124                                                                 fprintf(stderr, "PGR RECNAME = %s\n", buffer);
125                                                         }
126                                                         field_index = &p->handle_touch;
127
128 /* FIXME Unpredictable behaviour on lines longer than MAXBUFFER! */
129
130                                                         while ((fgets(line_buffer, MAXBUFFER, fp)) != NULL) {
131                                                                 if ((delimiter_first = (strchr(line_buffer, '%'))) != NULL &&
132                                                                 (delimiter_last = (strrchr(line_buffer, '%'))) != NULL &&
133                                                                 (delimiter_last != delimiter_first)) {
134                                                                         break;
135                                                                 }
136                                                                 if (num_field < MAXFIELDS) {
137                                                                         if ((delimiter_first = (strchr(line_buffer, '#'))) != NULL) {
138                                                                                 strncpy(buffer, line_buffer, ((delimiter_first) - (line_buffer)));
139                                                                                 strncpy(buffer + ((delimiter_first) - (line_buffer)), "\0", 1);
140                                                                                 strcpy(line_buffer, buffer);
141                                                                         }
142                                                                         if ((delimiter_first = (strchr(line_buffer, ':'))) != NULL) {
143                                                                                 strcpy(buffer, line_buffer);
144                                                                                 token = strtok(buffer, ":");
145                                                                                 token = strtok(NULL, ignore);
146                                                                                 strcpy(buffer, token);
147                                                                                 *field_index = atoi(buffer);
148                                                                                 field_index++;
149                                                                                 num_field++;
150                                                                         }
151                                                                 }
152                                                         }
153                                                         if (num_field == MAXFIELDS) {
154                                                                 num_record++;
155                                                                 p++;
156                                                         } else {
157                                                                 free(p->class_name);
158                                                         }
159                                                         num_field = 0;
160                                                 }
161                                         }
162                                 }
163                         }
164                 }
165         }
166         if (!num_record) {
167                 return 1;
168         }
169         num_list = num_record;
170
171         if (be_verbose) {
172                 fprintf(stderr, "PGR RECORDS = %d\n", num_list);
173         }
174
175         return 0;
176 }
177
178 /* End Code */
179