]> git.ipfire.org Git - people/ms/libloc.git/blame - src/python/writer.c
Implement signing/verifying databases
[people/ms/libloc.git] / src / python / writer.c
CommitLineData
d688e569
MT
1/*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2017 IPFire Development Team <info@ipfire.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library 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 GNU
14 Lesser General Public License for more details.
15*/
16
17#include <Python.h>
18
19#include <loc/libloc.h>
20#include <loc/writer.h>
21
22#include "locationmodule.h"
f8710bd6 23#include "as.h"
af208e26 24#include "country.h"
a92adad3 25#include "network.h"
d688e569
MT
26#include "writer.h"
27
28static PyObject* Writer_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
29 WriterObject* self = (WriterObject*)type->tp_alloc(type, 0);
30
31 return (PyObject*)self;
32}
33
34static void Writer_dealloc(WriterObject* self) {
35 if (self->writer)
36 loc_writer_unref(self->writer);
37
38 Py_TYPE(self)->tp_free((PyObject* )self);
39}
40
41static int Writer_init(WriterObject* self, PyObject* args, PyObject* kwargs) {
726f9984
MT
42 PyObject* private_key = NULL;
43 FILE* f = NULL;
44
45 // Parse arguments
46 if (!PyArg_ParseTuple(args, "|O", &private_key))
d688e569
MT
47 return -1;
48
726f9984
MT
49 // Convert into FILE*
50 if (private_key) {
51 int fd = PyObject_AsFileDescriptor(private_key);
52 if (fd < 0)
53 return -1;
54
55 // Re-open file descriptor
56 f = fdopen(fd, "r");
57 if (!f) {
58 PyErr_SetFromErrno(PyExc_IOError);
59 return -1;
60 }
61 }
62
63 // Create the writer object
64 int r = loc_writer_new(loc_ctx, &self->writer, f);
65
66 return r;
d688e569
MT
67}
68
69static PyObject* Writer_get_vendor(WriterObject* self) {
70 const char* vendor = loc_writer_get_vendor(self->writer);
71
72 return PyUnicode_FromString(vendor);
73}
74
360ae5ad
MT
75static int Writer_set_vendor(WriterObject* self, PyObject* value) {
76 const char* vendor = PyUnicode_AsUTF8(value);
d688e569
MT
77
78 int r = loc_writer_set_vendor(self->writer, vendor);
79 if (r) {
80 PyErr_Format(PyExc_ValueError, "Could not set vendor: %s", vendor);
81 return r;
82 }
83
84 return 0;
85}
86
9224f7ba
MT
87static PyObject* Writer_get_description(WriterObject* self) {
88 const char* description = loc_writer_get_description(self->writer);
89
90 return PyUnicode_FromString(description);
91}
92
93static int Writer_set_description(WriterObject* self, PyObject* value) {
94 const char* description = PyUnicode_AsUTF8(value);
95
96 int r = loc_writer_set_description(self->writer, description);
97 if (r) {
98 PyErr_Format(PyExc_ValueError, "Could not set description: %s", description);
99 return r;
100 }
101
102 return 0;
103}
104
4bf49d00
MT
105static PyObject* Writer_get_license(WriterObject* self) {
106 const char* license = loc_writer_get_license(self->writer);
107
108 return PyUnicode_FromString(license);
109}
110
111static int Writer_set_license(WriterObject* self, PyObject* value) {
112 const char* license = PyUnicode_AsUTF8(value);
113
114 int r = loc_writer_set_license(self->writer, license);
115 if (r) {
116 PyErr_Format(PyExc_ValueError, "Could not set license: %s", license);
117 return r;
118 }
119
120 return 0;
121}
122
f8710bd6
MT
123static PyObject* Writer_add_as(WriterObject* self, PyObject* args) {
124 struct loc_as* as;
125 uint32_t number = 0;
126
127 if (!PyArg_ParseTuple(args, "i", &number))
128 return NULL;
129
130 // Create AS object
131 int r = loc_writer_add_as(self->writer, &as, number);
132 if (r)
133 return NULL;
134
135 PyObject* obj = new_as(&ASType, as);
136 loc_as_unref(as);
137
138 return obj;
139}
140
af208e26
MT
141static PyObject* Writer_add_country(WriterObject* self, PyObject* args) {
142 struct loc_country* country;
143 const char* country_code;
144
145 if (!PyArg_ParseTuple(args, "s", &country_code))
146 return NULL;
147
148 // Create country object
149 int r = loc_writer_add_country(self->writer, &country, country_code);
150 if (r) {
151 switch (r) {
152 case -EINVAL:
153 PyErr_SetString(PyExc_ValueError, "Invalid network");
154 break;
155
156 default:
157 return NULL;
158 }
159 }
160
161 PyObject* obj = new_country(&CountryType, country);
162 loc_country_unref(country);
163
164 return obj;
165}
166
a92adad3
MT
167static PyObject* Writer_add_network(WriterObject* self, PyObject* args) {
168 struct loc_network* network;
169 const char* string = NULL;
170
171 if (!PyArg_ParseTuple(args, "s", &string))
172 return NULL;
173
174 // Create network object
175 int r = loc_writer_add_network(self->writer, &network, string);
dafdb6c8 176 if (r) {
c04005bb
MT
177 switch (r) {
178 case -EINVAL:
179 PyErr_SetString(PyExc_ValueError, "Invalid network");
180 break;
181
182 case -EBUSY:
183 PyErr_SetString(PyExc_IndexError, "A network already exists here");
184 break;
185 }
dafdb6c8 186
a92adad3 187 return NULL;
dafdb6c8 188 }
a92adad3
MT
189
190 PyObject* obj = new_network(&NetworkType, network);
191 loc_network_unref(network);
192
193 return obj;
194}
195
7d278671
MT
196static PyObject* Writer_write(WriterObject* self, PyObject* args) {
197 const char* path = NULL;
198
199 if (!PyArg_ParseTuple(args, "s", &path))
200 return NULL;
201
726f9984 202 FILE* f = fopen(path, "w+");
7d278671
MT
203 if (!f) {
204 PyErr_Format(PyExc_IOError, strerror(errno));
205 return NULL;
206 }
207
208 int r = loc_writer_write(self->writer, f);
209 fclose(f);
210
211 // Raise any errors
212 if (r) {
213 PyErr_Format(PyExc_IOError, strerror(errno));
214 return NULL;
215 }
216
217 Py_RETURN_NONE;
218}
219
220static struct PyMethodDef Writer_methods[] = {
f8710bd6
MT
221 {
222 "add_as",
223 (PyCFunction)Writer_add_as,
224 METH_VARARGS,
225 NULL,
226 },
a92adad3 227 {
af208e26
MT
228 "add_country",
229 (PyCFunction)Writer_add_country,
230 METH_VARARGS,
231 NULL,
232 },
233 {
a92adad3
MT
234 "add_network",
235 (PyCFunction)Writer_add_network,
236 METH_VARARGS,
237 NULL,
238 },
7d278671
MT
239 {
240 "write",
241 (PyCFunction)Writer_write,
242 METH_VARARGS,
243 NULL,
244 },
245 { NULL },
246};
247
d688e569 248static struct PyGetSetDef Writer_getsetters[] = {
9224f7ba
MT
249 {
250 "description",
251 (getter)Writer_get_description,
252 (setter)Writer_set_description,
253 NULL,
254 NULL,
255 },
4bf49d00
MT
256 {
257 "license",
258 (getter)Writer_get_license,
259 (setter)Writer_set_license,
260 NULL,
261 NULL,
262 },
d688e569
MT
263 {
264 "vendor",
265 (getter)Writer_get_vendor,
266 (setter)Writer_set_vendor,
267 NULL,
268 NULL,
269 },
270 { NULL },
271};
272
273PyTypeObject WriterType = {
274 PyVarObject_HEAD_INIT(NULL, 0)
d42e1dcd
MT
275 .tp_name = "location.Writer",
276 .tp_basicsize = sizeof(WriterObject),
277 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
278 .tp_new = Writer_new,
279 .tp_dealloc = (destructor)Writer_dealloc,
280 .tp_init = (initproc)Writer_init,
281 .tp_doc = "Writer object",
282 .tp_methods = Writer_methods,
283 .tp_getset = Writer_getsetters,
d688e569 284};