Implemented logging into separate file for debugging
[mtetherd] / device.c
1 /*
2   mtetherd
3   (c) 2010 Gregor Riepl <onitake@gmail.com>
4   
5   Tethering utility for Maemo
6   
7   This program is free software: you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation, either version 3 of the License, or
10   (at your option) any later version.
11   
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16   
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <arpa/inet.h>
25 #include "device.h"
26
27 Device *device_new(const char *name) {
28         if (!name) {
29                 fprintf(stderr, "No device name given.\n");
30                 return NULL;
31         }
32         Device *ret = malloc(sizeof(Device));
33         if (!ret) {
34                 fprintf(stderr, "Error allocating memory for device structure.\n");
35                 return NULL;
36         }
37         memset(ret, 0, sizeof(Device));
38         device_set_name(ret, name);
39         if (!ret->name) {
40                 free(ret);
41                 return NULL;
42         }
43         return ret;
44 }
45
46 Device *device_delete(Device *device) {
47         if (!device) {
48                 fprintf(stderr, "Error: trying to deallocate NULL device structure.\n");
49                 return NULL;
50         }
51         Device *ret = device->next;
52         free(device->name);
53         free(device->address);
54         free(device->startaddress);
55         free(device->endaddress);
56         if (device->previous) {
57                 device->previous->next = device->next;
58         }
59         if (device->next) {
60                 device->next->previous = device->previous;
61         }
62         free(device);
63         return ret;
64 }
65
66 Device *device_delete_all(Device *device) {
67         Device *ret = device->previous;
68         while (device) {
69                 device = device_delete(device);
70         }
71         return ret;
72 }
73
74 Device *device_append(Device *previous, Device *next) {
75         if (previous) {
76                 if (previous->next) {
77                         previous->next->previous = next;
78                         next->next = previous->next;
79                 }
80                 previous->next = next;
81                 next->previous = previous;
82         }
83         return next;
84 }
85
86 Device *device_set_name(Device *device, const char *name) {
87         if (!device) {
88                 fprintf(stderr, "Error: trying to set name of NULL device structure.\n");
89                 return NULL;
90         }
91         free(device->name);
92         size_t length = strlen(name);
93         device->name = malloc(length + 1);
94         if (!device->name) {
95                 fprintf(stderr, "Error allocating memory for device name.\n");
96         } else {
97                 int filtered = 0;
98                 size_t i, j;
99                 for (i = 0, j = 0; i < length; i++) {
100                         if ((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= '0' && name[i] <= '9')) {
101                                 device->name[j] = name[i];
102                                 j++;
103                         } else {
104                                 filtered = 1;
105                         }
106                 }
107                 device->name[j] = '\0';
108                 if (j == 0) {
109                         fprintf(stderr, "Error: Invalid device name.\n");
110                         free(device->name);
111                         device->name = NULL;
112                 } else {
113                         if (filtered) {
114                                 fprintf(stderr, "Warning, device name contained invalid characters. They have been removed.\n");
115                         }
116                 }
117         }
118         return device;
119 }
120
121 Device *device_set_address(Device *device, const char *address) {
122         if (!device) {
123                 fprintf(stderr, "Error: trying to set address of NULL device structure.\n");
124                 return NULL;
125         }
126         free(device->address);
127         struct in_addr addr_in;
128         int err = inet_pton(AF_INET, address, &addr_in);
129         if (err == 0) {
130                 fprintf(stderr, "Address %s is invalid.\n", address);
131                 device->address = NULL;
132         } else if (err == -1) {
133                 fprintf(stderr, "Can't convert address %s.\n", address);
134                 device->address = NULL;
135         } else {
136                 device->address = malloc(16);
137                 if (!device->address) {
138                         fprintf(stderr, "Error allocating memory for converted address.\n");
139                 } else {
140                         if (inet_ntop(AF_INET, &addr_in, device->address, 16) == NULL) {
141                                 fprintf(stderr, "Can't convert address %s\n", address);
142                                 free(device->address);
143                                 device->address = NULL;
144                         }
145                 }
146         }
147         return device;
148 }
149
150 Device *device_set_startaddress(Device *device, const char *address) {
151         if (!device) {
152                 fprintf(stderr, "Error: trying to set start address of NULL device structure.\n");
153                 return NULL;
154         }
155         free(device->startaddress);
156         struct in_addr addr_in;
157         int err = inet_pton(AF_INET, address, &addr_in);
158         if (err == 0) {
159                 fprintf(stderr, "Address %s is invalid.\n", address);
160                 device->startaddress = NULL;
161         } else if (err == -1) {
162                 fprintf(stderr, "Can't convert address %s.\n", address);
163                 device->startaddress = NULL;
164         } else {
165                 device->startaddress = malloc(16);
166                 if (!device->startaddress) {
167                         fprintf(stderr, "Error allocating memory for converted address.\n");
168                 } else {
169                         if (inet_ntop(AF_INET, &addr_in, device->startaddress, 16) == NULL) {
170                                 fprintf(stderr, "Can't convert address %s\n", address);
171                                 free(device->startaddress);
172                                 device->startaddress = NULL;
173                         }
174                 }
175         }
176         return device;
177 }
178
179 Device *device_set_endaddress(Device *device, const char *address) {
180         if (!device) {
181                 fprintf(stderr, "Error: trying to set end address of NULL device structure.\n");
182                 return NULL;
183         }
184         free(device->endaddress);
185         struct in_addr addr_in;
186         int err = inet_pton(AF_INET, address, &addr_in);
187         if (err == 0) {
188                 fprintf(stderr, "Address %s is invalid.\n", address);
189                 device->endaddress = NULL;
190         } else if (err == -1) {
191                 fprintf(stderr, "Can't convert address %s.\n", address);
192                 device->endaddress = NULL;
193         } else {
194                 device->endaddress = malloc(16);
195                 if (!device->endaddress) {
196                         fprintf(stderr, "Error allocating memory for converted address.\n");
197                 } else {
198                         if (inet_ntop(AF_INET, &addr_in, device->endaddress, 16) == NULL) {
199                                 fprintf(stderr, "Can't convert address %s\n", address);
200                                 free(device->endaddress);
201                                 device->endaddress = NULL;
202                         }
203                 }
204         }
205         return device;
206 }
207
208 int device_validate(Device *device) {
209         return device && device->name && device->address && device->startaddress && device->endaddress;
210 }
211
212 Device *device_search(Device *start, const char *name) {
213         for (; start; start = start->next) {
214                 if (strcmp(start->name, name) == 0) {
215                         return start;
216                 }
217         }
218         return NULL;
219 }