]> arthur.barton.de Git - bup.git/blob - lib/bup/_helpers.c
Avoid using incomplete utimensat implementations.
[bup.git] / lib / bup / _helpers.c
1 #define _LARGEFILE64_SOURCE 1
2 #define PY_SSIZE_T_CLEAN 1
3 #undef NDEBUG
4 #include "../../config/config.h"
5
6 // According to Python, its header has to go first:
7 //   http://docs.python.org/2/c-api/intro.html#include-files
8 #include <Python.h>
9
10 #include <assert.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <arpa/inet.h>
14 #include <stdint.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <sys/mman.h>
18
19 #ifdef HAVE_SYS_TYPES_H
20 #include <sys/types.h>
21 #endif
22 #ifdef HAVE_SYS_STAT_H
23 #include <sys/stat.h>
24 #endif
25 #ifdef HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28
29 #ifdef HAVE_LINUX_FS_H
30 #include <linux/fs.h>
31 #endif
32 #ifdef HAVE_SYS_IOCTL_H
33 #include <sys/ioctl.h>
34 #endif
35
36 #include "bupsplit.h"
37
38 #if defined(FS_IOC_GETFLAGS) && defined(FS_IOC_SETFLAGS)
39 #define BUP_HAVE_FILE_ATTRS 1
40 #endif
41
42 /*
43  * Check for incomplete UTIMENSAT support (NetBSD 6), and if so,
44  * pretend we don't have it.
45  */
46 #if !defined(AT_FDCWD) || !defined(AT_SYMLINK_NOFOLLOW)
47 #undef HAVE_UTIMENSAT
48 #endif
49
50 #ifndef FS_NOCOW_FL
51 // Of course, this assumes it's a bitfield value.
52 #define FS_NOCOW_FL 0
53 #endif
54
55 static int istty2 = 0;
56
57 // At the moment any code that calls INTGER_TO_PY() will have to
58 // disable -Wtautological-compare for clang.  See below.
59
60 #define INTEGER_TO_PY(x) \
61     (((x) >= 0) ? PyLong_FromUnsignedLongLong(x) : PyLong_FromLongLong(x))
62
63
64 static int bup_ulong_from_pyint(unsigned long *x, PyObject *py,
65                                 const char *name)
66 {
67     const long tmp = PyInt_AsLong(py);
68     if (tmp == -1 && PyErr_Occurred())
69     {
70         if (PyErr_ExceptionMatches(PyExc_OverflowError))
71             PyErr_Format(PyExc_OverflowError, "%s too big for unsigned long",
72                          name);
73         return 0;
74     }
75     if (tmp < 0)
76     {
77         PyErr_Format(PyExc_OverflowError,
78                      "negative %s cannot be converted to unsigned long", name);
79         return 0;
80     }
81     *x = tmp;
82     return 1;
83 }
84
85
86 static int bup_ulong_from_py(unsigned long *x, PyObject *py, const char *name)
87 {
88     if (PyInt_Check(py))
89         return bup_ulong_from_pyint(x, py, name);
90
91     if (!PyLong_Check(py))
92     {
93         PyErr_Format(PyExc_TypeError, "expected integer %s", name);
94         return 0;
95     }
96
97     const unsigned long tmp = PyLong_AsUnsignedLong(py);
98     if (PyErr_Occurred())
99     {
100         if (PyErr_ExceptionMatches(PyExc_OverflowError))
101             PyErr_Format(PyExc_OverflowError, "%s too big for unsigned long",
102                          name);
103         return 0;
104     }
105     *x = tmp;
106     return 1;
107 }
108
109
110 static int bup_uint_from_py(unsigned int *x, PyObject *py, const char *name)
111 {
112     unsigned long tmp;
113     if (!bup_ulong_from_py(&tmp, py, name))
114         return 0;
115
116     if (tmp > UINT_MAX)
117     {
118         PyErr_Format(PyExc_OverflowError, "%s too big for unsigned int", name);
119         return 0;
120     }
121     *x = tmp;
122     return 1;
123 }
124
125 static int bup_ullong_from_py(unsigned PY_LONG_LONG *x, PyObject *py,
126                               const char *name)
127 {
128     if (PyInt_Check(py))
129     {
130         unsigned long tmp;
131         if (bup_ulong_from_pyint(&tmp, py, name))
132         {
133             *x = tmp;
134             return 1;
135         }
136         return 0;
137     }
138
139     if (!PyLong_Check(py))
140     {
141         PyErr_Format(PyExc_TypeError, "integer argument expected for %s", name);
142         return 0;
143     }
144
145     const unsigned PY_LONG_LONG tmp = PyLong_AsUnsignedLongLong(py);
146     if (tmp == (unsigned long long) -1 && PyErr_Occurred())
147     {
148         if (PyErr_ExceptionMatches(PyExc_OverflowError))
149             PyErr_Format(PyExc_OverflowError,
150                          "%s too big for unsigned long long", name);
151         return 0;
152     }
153     *x = tmp;
154     return 1;
155 }
156
157
158 // Probably we should use autoconf or something and set HAVE_PY_GETARGCARGV...
159 #if __WIN32__ || __CYGWIN__
160
161 // There's no 'ps' on win32 anyway, and Py_GetArgcArgv() isn't available.
162 static void unpythonize_argv(void) { }
163
164 #else // not __WIN32__
165
166 // For some reason this isn't declared in Python.h
167 extern void Py_GetArgcArgv(int *argc, char ***argv);
168
169 static void unpythonize_argv(void)
170 {
171     int argc, i;
172     char **argv, *arge;
173     
174     Py_GetArgcArgv(&argc, &argv);
175     
176     for (i = 0; i < argc-1; i++)
177     {
178         if (argv[i] + strlen(argv[i]) + 1 != argv[i+1])
179         {
180             // The argv block doesn't work the way we expected; it's unsafe
181             // to mess with it.
182             return;
183         }
184     }
185     
186     arge = argv[argc-1] + strlen(argv[argc-1]) + 1;
187     
188     if (strstr(argv[0], "python") && argv[1] == argv[0] + strlen(argv[0]) + 1)
189     {
190         char *p;
191         size_t len, diff;
192         p = strrchr(argv[1], '/');
193         if (p)
194         {
195             p++;
196             diff = p - argv[0];
197             len = arge - p;
198             memmove(argv[0], p, len);
199             memset(arge - diff, 0, diff);
200             for (i = 0; i < argc; i++)
201                 argv[i] = argv[i+1] ? argv[i+1]-diff : NULL;
202         }
203     }
204 }
205
206 #endif // not __WIN32__ or __CYGWIN__
207
208
209 static PyObject *selftest(PyObject *self, PyObject *args)
210 {
211     if (!PyArg_ParseTuple(args, ""))
212         return NULL;
213     
214     return Py_BuildValue("i", !bupsplit_selftest());
215 }
216
217
218 static PyObject *blobbits(PyObject *self, PyObject *args)
219 {
220     if (!PyArg_ParseTuple(args, ""))
221         return NULL;
222     return Py_BuildValue("i", BUP_BLOBBITS);
223 }
224
225
226 static PyObject *splitbuf(PyObject *self, PyObject *args)
227 {
228     unsigned char *buf = NULL;
229     Py_ssize_t len = 0;
230     int out = 0, bits = -1;
231
232     if (!PyArg_ParseTuple(args, "t#", &buf, &len))
233         return NULL;
234     assert(len <= INT_MAX);
235     out = bupsplit_find_ofs(buf, len, &bits);
236     if (out) assert(bits >= BUP_BLOBBITS);
237     return Py_BuildValue("ii", out, bits);
238 }
239
240
241 static PyObject *bitmatch(PyObject *self, PyObject *args)
242 {
243     unsigned char *buf1 = NULL, *buf2 = NULL;
244     Py_ssize_t len1 = 0, len2 = 0;
245     Py_ssize_t byte;
246     int bit;
247
248     if (!PyArg_ParseTuple(args, "t#t#", &buf1, &len1, &buf2, &len2))
249         return NULL;
250     
251     bit = 0;
252     for (byte = 0; byte < len1 && byte < len2; byte++)
253     {
254         int b1 = buf1[byte], b2 = buf2[byte];
255         if (b1 != b2)
256         {
257             for (bit = 0; bit < 8; bit++)
258                 if ( (b1 & (0x80 >> bit)) != (b2 & (0x80 >> bit)) )
259                     break;
260             break;
261         }
262     }
263     
264     assert(byte <= (INT_MAX >> 3));
265     return Py_BuildValue("i", byte*8 + bit);
266 }
267
268
269 static PyObject *firstword(PyObject *self, PyObject *args)
270 {
271     unsigned char *buf = NULL;
272     Py_ssize_t len = 0;
273     uint32_t v;
274
275     if (!PyArg_ParseTuple(args, "t#", &buf, &len))
276         return NULL;
277     
278     if (len < 4)
279         return NULL;
280     
281     v = ntohl(*(uint32_t *)buf);
282     return PyLong_FromUnsignedLong(v);
283 }
284
285
286 #define BLOOM2_HEADERLEN 16
287
288 static void to_bloom_address_bitmask4(const unsigned char *buf,
289         const int nbits, uint64_t *v, unsigned char *bitmask)
290 {
291     int bit;
292     uint32_t high;
293     uint64_t raw, mask;
294
295     memcpy(&high, buf, 4);
296     mask = (1<<nbits) - 1;
297     raw = (((uint64_t)ntohl(high) << 8) | buf[4]);
298     bit = (raw >> (37-nbits)) & 0x7;
299     *v = (raw >> (40-nbits)) & mask;
300     *bitmask = 1 << bit;
301 }
302
303 static void to_bloom_address_bitmask5(const unsigned char *buf,
304         const int nbits, uint32_t *v, unsigned char *bitmask)
305 {
306     int bit;
307     uint32_t high;
308     uint32_t raw, mask;
309
310     memcpy(&high, buf, 4);
311     mask = (1<<nbits) - 1;
312     raw = ntohl(high);
313     bit = (raw >> (29-nbits)) & 0x7;
314     *v = (raw >> (32-nbits)) & mask;
315     *bitmask = 1 << bit;
316 }
317
318 #define BLOOM_SET_BIT(name, address, otype) \
319 static void name(unsigned char *bloom, const unsigned char *buf, const int nbits)\
320 {\
321     unsigned char bitmask;\
322     otype v;\
323     address(buf, nbits, &v, &bitmask);\
324     bloom[BLOOM2_HEADERLEN+v] |= bitmask;\
325 }
326 BLOOM_SET_BIT(bloom_set_bit4, to_bloom_address_bitmask4, uint64_t)
327 BLOOM_SET_BIT(bloom_set_bit5, to_bloom_address_bitmask5, uint32_t)
328
329
330 #define BLOOM_GET_BIT(name, address, otype) \
331 static int name(const unsigned char *bloom, const unsigned char *buf, const int nbits)\
332 {\
333     unsigned char bitmask;\
334     otype v;\
335     address(buf, nbits, &v, &bitmask);\
336     return bloom[BLOOM2_HEADERLEN+v] & bitmask;\
337 }
338 BLOOM_GET_BIT(bloom_get_bit4, to_bloom_address_bitmask4, uint64_t)
339 BLOOM_GET_BIT(bloom_get_bit5, to_bloom_address_bitmask5, uint32_t)
340
341
342 static PyObject *bloom_add(PyObject *self, PyObject *args)
343 {
344     unsigned char *sha = NULL, *bloom = NULL;
345     unsigned char *end;
346     Py_ssize_t len = 0, blen = 0;
347     int nbits = 0, k = 0;
348
349     if (!PyArg_ParseTuple(args, "w#s#ii", &bloom, &blen, &sha, &len, &nbits, &k))
350         return NULL;
351
352     if (blen < 16+(1<<nbits) || len % 20 != 0)
353         return NULL;
354
355     if (k == 5)
356     {
357         if (nbits > 29)
358             return NULL;
359         for (end = sha + len; sha < end; sha += 20/k)
360             bloom_set_bit5(bloom, sha, nbits);
361     }
362     else if (k == 4)
363     {
364         if (nbits > 37)
365             return NULL;
366         for (end = sha + len; sha < end; sha += 20/k)
367             bloom_set_bit4(bloom, sha, nbits);
368     }
369     else
370         return NULL;
371
372
373     return Py_BuildValue("n", len/20);
374 }
375
376 static PyObject *bloom_contains(PyObject *self, PyObject *args)
377 {
378     unsigned char *sha = NULL, *bloom = NULL;
379     Py_ssize_t len = 0, blen = 0;
380     int nbits = 0, k = 0;
381     unsigned char *end;
382     int steps;
383
384     if (!PyArg_ParseTuple(args, "t#s#ii", &bloom, &blen, &sha, &len, &nbits, &k))
385         return NULL;
386
387     if (len != 20)
388         return NULL;
389
390     if (k == 5)
391     {
392         if (nbits > 29)
393             return NULL;
394         for (steps = 1, end = sha + 20; sha < end; sha += 20/k, steps++)
395             if (!bloom_get_bit5(bloom, sha, nbits))
396                 return Py_BuildValue("Oi", Py_None, steps);
397     }
398     else if (k == 4)
399     {
400         if (nbits > 37)
401             return NULL;
402         for (steps = 1, end = sha + 20; sha < end; sha += 20/k, steps++)
403             if (!bloom_get_bit4(bloom, sha, nbits))
404                 return Py_BuildValue("Oi", Py_None, steps);
405     }
406     else
407         return NULL;
408
409     return Py_BuildValue("ii", 1, k);
410 }
411
412
413 static uint32_t _extract_bits(unsigned char *buf, int nbits)
414 {
415     uint32_t v, mask;
416
417     mask = (1<<nbits) - 1;
418     v = ntohl(*(uint32_t *)buf);
419     v = (v >> (32-nbits)) & mask;
420     return v;
421 }
422
423
424 static PyObject *extract_bits(PyObject *self, PyObject *args)
425 {
426     unsigned char *buf = NULL;
427     Py_ssize_t len = 0;
428     int nbits = 0;
429
430     if (!PyArg_ParseTuple(args, "t#i", &buf, &len, &nbits))
431         return NULL;
432     
433     if (len < 4)
434         return NULL;
435     
436     return PyLong_FromUnsignedLong(_extract_bits(buf, nbits));
437 }
438
439
440 struct sha {
441     unsigned char bytes[20];
442 };
443
444
445 struct idx {
446     unsigned char *map;
447     struct sha *cur;
448     struct sha *end;
449     uint32_t *cur_name;
450     Py_ssize_t bytes;
451     int name_base;
452 };
453
454
455 static int _cmp_sha(const struct sha *sha1, const struct sha *sha2)
456 {
457     int i;
458     for (i = 0; i < sizeof(struct sha); i++)
459         if (sha1->bytes[i] != sha2->bytes[i])
460             return sha1->bytes[i] - sha2->bytes[i];
461     return 0;
462 }
463
464
465 static void _fix_idx_order(struct idx **idxs, int *last_i)
466 {
467     struct idx *idx;
468     int low, mid, high, c = 0;
469
470     idx = idxs[*last_i];
471     if (idxs[*last_i]->cur >= idxs[*last_i]->end)
472     {
473         idxs[*last_i] = NULL;
474         PyMem_Free(idx);
475         --*last_i;
476         return;
477     }
478     if (*last_i == 0)
479         return;
480
481     low = *last_i-1;
482     mid = *last_i;
483     high = 0;
484     while (low >= high)
485     {
486         mid = (low + high) / 2;
487         c = _cmp_sha(idx->cur, idxs[mid]->cur);
488         if (c < 0)
489             high = mid + 1;
490         else if (c > 0)
491             low = mid - 1;
492         else
493             break;
494     }
495     if (c < 0)
496         ++mid;
497     if (mid == *last_i)
498         return;
499     memmove(&idxs[mid+1], &idxs[mid], (*last_i-mid)*sizeof(struct idx *));
500     idxs[mid] = idx;
501 }
502
503
504 static uint32_t _get_idx_i(struct idx *idx)
505 {
506     if (idx->cur_name == NULL)
507         return idx->name_base;
508     return ntohl(*idx->cur_name) + idx->name_base;
509 }
510
511 #define MIDX4_HEADERLEN 12
512
513 static PyObject *merge_into(PyObject *self, PyObject *args)
514 {
515     PyObject *py_total, *ilist = NULL;
516     unsigned char *fmap = NULL;
517     struct sha *sha_ptr, *sha_start = NULL;
518     uint32_t *table_ptr, *name_ptr, *name_start;
519     struct idx **idxs = NULL;
520     Py_ssize_t flen = 0;
521     int bits = 0, i;
522     unsigned int total;
523     uint32_t count, prefix;
524     int num_i;
525     int last_i;
526
527     if (!PyArg_ParseTuple(args, "w#iOO",
528                           &fmap, &flen, &bits, &py_total, &ilist))
529         return NULL;
530
531     if (!bup_uint_from_py(&total, py_total, "total"))
532         return NULL;
533
534     num_i = PyList_Size(ilist);
535     idxs = (struct idx **)PyMem_Malloc(num_i * sizeof(struct idx *));
536
537     for (i = 0; i < num_i; i++)
538     {
539         long len, sha_ofs, name_map_ofs;
540         idxs[i] = (struct idx *)PyMem_Malloc(sizeof(struct idx));
541         PyObject *itup = PyList_GetItem(ilist, i);
542         if (!PyArg_ParseTuple(itup, "t#llli", &idxs[i]->map, &idxs[i]->bytes,
543                     &len, &sha_ofs, &name_map_ofs, &idxs[i]->name_base))
544             return NULL;
545         idxs[i]->cur = (struct sha *)&idxs[i]->map[sha_ofs];
546         idxs[i]->end = &idxs[i]->cur[len];
547         if (name_map_ofs)
548             idxs[i]->cur_name = (uint32_t *)&idxs[i]->map[name_map_ofs];
549         else
550             idxs[i]->cur_name = NULL;
551     }
552     table_ptr = (uint32_t *)&fmap[MIDX4_HEADERLEN];
553     sha_start = sha_ptr = (struct sha *)&table_ptr[1<<bits];
554     name_start = name_ptr = (uint32_t *)&sha_ptr[total];
555
556     last_i = num_i-1;
557     count = 0;
558     prefix = 0;
559     while (last_i >= 0)
560     {
561         struct idx *idx;
562         uint32_t new_prefix;
563         if (count % 102424 == 0 && istty2)
564             fprintf(stderr, "midx: writing %.2f%% (%d/%d)\r",
565                     count*100.0/total, count, total);
566         idx = idxs[last_i];
567         new_prefix = _extract_bits((unsigned char *)idx->cur, bits);
568         while (prefix < new_prefix)
569             table_ptr[prefix++] = htonl(count);
570         memcpy(sha_ptr++, idx->cur, sizeof(struct sha));
571         *name_ptr++ = htonl(_get_idx_i(idx));
572         ++idx->cur;
573         if (idx->cur_name != NULL)
574             ++idx->cur_name;
575         _fix_idx_order(idxs, &last_i);
576         ++count;
577     }
578     while (prefix < (1<<bits))
579         table_ptr[prefix++] = htonl(count);
580     assert(count == total);
581     assert(prefix == (1<<bits));
582     assert(sha_ptr == sha_start+count);
583     assert(name_ptr == name_start+count);
584
585     PyMem_Free(idxs);
586     return PyLong_FromUnsignedLong(count);
587 }
588
589 // This function should technically be macro'd out if it's going to be used
590 // more than ocasionally.  As of this writing, it'll actually never be called
591 // in real world bup scenarios (because our packs are < MAX_INT bytes).
592 static uint64_t htonll(uint64_t value)
593 {
594     static const int endian_test = 42;
595
596     if (*(char *)&endian_test == endian_test) // LSB-MSB
597         return ((uint64_t)htonl(value & 0xFFFFFFFF) << 32) | htonl(value >> 32);
598     return value; // already in network byte order MSB-LSB
599 }
600
601 #define FAN_ENTRIES 256
602
603 static PyObject *write_idx(PyObject *self, PyObject *args)
604 {
605     char *filename = NULL;
606     PyObject *py_total, *idx = NULL;
607     PyObject *part;
608     unsigned char *fmap = NULL;
609     Py_ssize_t flen = 0;
610     unsigned int total = 0;
611     uint32_t count;
612     int i, j, ofs64_count;
613     uint32_t *fan_ptr, *crc_ptr, *ofs_ptr;
614     uint64_t *ofs64_ptr;
615     struct sha *sha_ptr;
616
617     if (!PyArg_ParseTuple(args, "sw#OO",
618                           &filename, &fmap, &flen, &idx, &py_total))
619         return NULL;
620
621     if (!bup_uint_from_py(&total, py_total, "total"))
622         return NULL;
623
624     if (PyList_Size (idx) != FAN_ENTRIES) // Check for list of the right length.
625         return PyErr_Format (PyExc_TypeError, "idx must contain %d entries",
626                              FAN_ENTRIES);
627
628     const char idx_header[] = "\377tOc\0\0\0\002";
629     memcpy (fmap, idx_header, sizeof(idx_header) - 1);
630
631     fan_ptr = (uint32_t *)&fmap[sizeof(idx_header) - 1];
632     sha_ptr = (struct sha *)&fan_ptr[FAN_ENTRIES];
633     crc_ptr = (uint32_t *)&sha_ptr[total];
634     ofs_ptr = (uint32_t *)&crc_ptr[total];
635     ofs64_ptr = (uint64_t *)&ofs_ptr[total];
636
637     count = 0;
638     ofs64_count = 0;
639     for (i = 0; i < FAN_ENTRIES; ++i)
640     {
641         int plen;
642         part = PyList_GET_ITEM(idx, i);
643         PyList_Sort(part);
644         plen = PyList_GET_SIZE(part);
645         count += plen;
646         *fan_ptr++ = htonl(count);
647         for (j = 0; j < plen; ++j)
648         {
649             unsigned char *sha = NULL;
650             Py_ssize_t sha_len = 0;
651             PyObject *crc_py, *ofs_py;
652             unsigned int crc;
653             unsigned PY_LONG_LONG ofs_ull;
654             uint64_t ofs;
655             if (!PyArg_ParseTuple(PyList_GET_ITEM(part, j), "t#OO",
656                                   &sha, &sha_len, &crc_py, &ofs_py))
657                 return NULL;
658             if(!bup_uint_from_py(&crc, crc_py, "crc"))
659                 return NULL;
660             if(!bup_ullong_from_py(&ofs_ull, ofs_py, "ofs"))
661                 return NULL;
662             assert(crc <= UINT32_MAX);
663             assert(ofs_ull <= UINT64_MAX);
664             ofs = ofs_ull;
665             if (sha_len != sizeof(struct sha))
666                 return NULL;
667             memcpy(sha_ptr++, sha, sizeof(struct sha));
668             *crc_ptr++ = htonl(crc);
669             if (ofs > 0x7fffffff)
670             {
671                 *ofs64_ptr++ = htonll(ofs);
672                 ofs = 0x80000000 | ofs64_count++;
673             }
674             *ofs_ptr++ = htonl((uint32_t)ofs);
675         }
676     }
677
678     int rc = msync(fmap, flen, MS_ASYNC);
679     if (rc != 0)
680         return PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
681
682     return PyLong_FromUnsignedLong(count);
683 }
684
685
686 // I would have made this a lower-level function that just fills in a buffer
687 // with random values, and then written those values from python.  But that's
688 // about 20% slower in my tests, and since we typically generate random
689 // numbers for benchmarking other parts of bup, any slowness in generating
690 // random bytes will make our benchmarks inaccurate.  Plus nobody wants
691 // pseudorandom bytes much except for this anyway.
692 static PyObject *write_random(PyObject *self, PyObject *args)
693 {
694     uint32_t buf[1024/4];
695     int fd = -1, seed = 0, verbose = 0;
696     ssize_t ret;
697     long long len = 0, kbytes = 0, written = 0;
698
699     if (!PyArg_ParseTuple(args, "iLii", &fd, &len, &seed, &verbose))
700         return NULL;
701     
702     srandom(seed);
703     
704     for (kbytes = 0; kbytes < len/1024; kbytes++)
705     {
706         unsigned i;
707         for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i++)
708             buf[i] = random();
709         ret = write(fd, buf, sizeof(buf));
710         if (ret < 0)
711             ret = 0;
712         written += ret;
713         if (ret < (int)sizeof(buf))
714             break;
715         if (verbose && kbytes/1024 > 0 && !(kbytes%1024))
716             fprintf(stderr, "Random: %lld Mbytes\r", kbytes/1024);
717     }
718     
719     // handle non-multiples of 1024
720     if (len % 1024)
721     {
722         unsigned i;
723         for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i++)
724             buf[i] = random();
725         ret = write(fd, buf, len % 1024);
726         if (ret < 0)
727             ret = 0;
728         written += ret;
729     }
730     
731     if (kbytes/1024 > 0)
732         fprintf(stderr, "Random: %lld Mbytes, done.\n", kbytes/1024);
733     return Py_BuildValue("L", written);
734 }
735
736
737 static PyObject *random_sha(PyObject *self, PyObject *args)
738 {
739     static int seeded = 0;
740     uint32_t shabuf[20/4];
741     int i;
742     
743     if (!seeded)
744     {
745         assert(sizeof(shabuf) == 20);
746         srandom(time(NULL));
747         seeded = 1;
748     }
749     
750     if (!PyArg_ParseTuple(args, ""))
751         return NULL;
752     
753     memset(shabuf, 0, sizeof(shabuf));
754     for (i=0; i < 20/4; i++)
755         shabuf[i] = random();
756     return Py_BuildValue("s#", shabuf, 20);
757 }
758
759
760 static int _open_noatime(const char *filename, int attrs)
761 {
762     int attrs_noatime, fd;
763     attrs |= O_RDONLY;
764 #ifdef O_NOFOLLOW
765     attrs |= O_NOFOLLOW;
766 #endif
767 #ifdef O_LARGEFILE
768     attrs |= O_LARGEFILE;
769 #endif
770     attrs_noatime = attrs;
771 #ifdef O_NOATIME
772     attrs_noatime |= O_NOATIME;
773 #endif
774     fd = open(filename, attrs_noatime);
775     if (fd < 0 && errno == EPERM)
776     {
777         // older Linux kernels would return EPERM if you used O_NOATIME
778         // and weren't the file's owner.  This pointless restriction was
779         // relaxed eventually, but we have to handle it anyway.
780         // (VERY old kernels didn't recognized O_NOATIME, but they would
781         // just harmlessly ignore it, so this branch won't trigger)
782         fd = open(filename, attrs);
783     }
784     return fd;
785 }
786
787
788 static PyObject *open_noatime(PyObject *self, PyObject *args)
789 {
790     char *filename = NULL;
791     int fd;
792     if (!PyArg_ParseTuple(args, "s", &filename))
793         return NULL;
794     fd = _open_noatime(filename, 0);
795     if (fd < 0)
796         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
797     return Py_BuildValue("i", fd);
798 }
799
800
801 static PyObject *fadvise_done(PyObject *self, PyObject *args)
802 {
803     int fd = -1;
804     long long ofs = 0;
805     if (!PyArg_ParseTuple(args, "iL", &fd, &ofs))
806         return NULL;
807 #ifdef POSIX_FADV_DONTNEED
808     posix_fadvise(fd, 0, ofs, POSIX_FADV_DONTNEED);
809 #endif    
810     return Py_BuildValue("");
811 }
812
813
814 #ifdef BUP_HAVE_FILE_ATTRS
815 static PyObject *bup_get_linux_file_attr(PyObject *self, PyObject *args)
816 {
817     int rc;
818     unsigned int attr;
819     char *path;
820     int fd;
821
822     if (!PyArg_ParseTuple(args, "s", &path))
823         return NULL;
824
825     fd = _open_noatime(path, O_NONBLOCK);
826     if (fd == -1)
827         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
828
829     attr = 0;
830     rc = ioctl(fd, FS_IOC_GETFLAGS, &attr);
831     if (rc == -1)
832     {
833         close(fd);
834         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
835     }
836
837     close(fd);
838     return Py_BuildValue("I", attr);
839 }
840 #endif /* def BUP_HAVE_FILE_ATTRS */
841
842
843
844 #ifdef BUP_HAVE_FILE_ATTRS
845 static PyObject *bup_set_linux_file_attr(PyObject *self, PyObject *args)
846 {
847     int rc;
848     unsigned int orig_attr, attr;
849     char *path;
850     PyObject *py_attr;
851     int fd;
852
853     if (!PyArg_ParseTuple(args, "sO", &path, &py_attr))
854         return NULL;
855
856     if (!bup_uint_from_py(&attr, py_attr, "attr"))
857         return NULL;
858
859     fd = open(path, O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_NOFOLLOW);
860     if (fd == -1)
861         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
862
863     // Restrict attr to modifiable flags acdeijstuADST -- see
864     // chattr(1) and the e2fsprogs source.  Letter to flag mapping is
865     // in pf.c flags_array[].
866     attr &= FS_APPEND_FL | FS_COMPR_FL | FS_NODUMP_FL | FS_EXTENT_FL
867     | FS_IMMUTABLE_FL | FS_JOURNAL_DATA_FL | FS_SECRM_FL | FS_NOTAIL_FL
868     | FS_UNRM_FL | FS_NOATIME_FL | FS_DIRSYNC_FL | FS_SYNC_FL
869     | FS_TOPDIR_FL | FS_NOCOW_FL;
870
871     // The extents flag can't be removed, so don't (see chattr(1) and chattr.c).
872     rc = ioctl(fd, FS_IOC_GETFLAGS, &orig_attr);
873     if (rc == -1)
874     {
875         close(fd);
876         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
877     }
878     attr |= (orig_attr & FS_EXTENT_FL);
879
880     rc = ioctl(fd, FS_IOC_SETFLAGS, &attr);
881     if (rc == -1)
882     {
883         close(fd);
884         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
885     }
886
887     close(fd);
888     return Py_BuildValue("O", Py_None);
889 }
890 #endif /* def BUP_HAVE_FILE_ATTRS */
891
892
893 #ifndef HAVE_UTIMENSAT
894 #ifndef HAVE_UTIMES
895 #error "cannot find utimensat or utimes()"
896 #endif
897 #ifndef HAVE_LUTIMES
898 #error "cannot find utimensat or lutimes()"
899 #endif
900 #endif
901
902
903 #define INTEGRAL_ASSIGNMENT_FITS(dest, src)                             \
904     ({                                                                  \
905         *(dest) = (src);                                                \
906         *(dest) == (src) && (*(dest) < 1) == ((src) < 1);               \
907     })
908
909
910 #define ASSIGN_PYLONG_TO_INTEGRAL(dest, pylong, overflow) \
911     ({                                                     \
912         int result = 0;                                                 \
913         *(overflow) = 0;                                                \
914         const long long lltmp = PyLong_AsLongLong(pylong);              \
915         if (lltmp == -1 && PyErr_Occurred())                            \
916         {                                                               \
917             if (PyErr_ExceptionMatches(PyExc_OverflowError))            \
918             {                                                           \
919                 const unsigned long long ulltmp = PyLong_AsUnsignedLongLong(pylong); \
920                 if (ulltmp == (unsigned long long) -1 && PyErr_Occurred()) \
921                 {                                                       \
922                     if (PyErr_ExceptionMatches(PyExc_OverflowError))    \
923                     {                                                   \
924                         PyErr_Clear();                                  \
925                         *(overflow) = 1;                                \
926                     }                                                   \
927                 }                                                       \
928                 if (INTEGRAL_ASSIGNMENT_FITS((dest), ulltmp))           \
929                     result = 1;                                         \
930                 else                                                    \
931                     *(overflow) = 1;                                    \
932             }                                                           \
933         }                                                               \
934         else                                                            \
935         {                                                               \
936             if (INTEGRAL_ASSIGNMENT_FITS((dest), lltmp))                \
937                 result = 1;                                             \
938             else                                                        \
939                 *(overflow) = 1;                                        \
940         }                                                               \
941         result;                                                         \
942         })
943
944
945 #ifdef HAVE_UTIMENSAT
946
947 static PyObject *bup_utimensat(PyObject *self, PyObject *args)
948 {
949     int rc;
950     int fd, flag;
951     char *path;
952     PyObject *access_py, *modification_py;
953     struct timespec ts[2];
954
955     if (!PyArg_ParseTuple(args, "is((Ol)(Ol))i",
956                           &fd,
957                           &path,
958                           &access_py, &(ts[0].tv_nsec),
959                           &modification_py, &(ts[1].tv_nsec),
960                           &flag))
961         return NULL;
962
963     int overflow;
964     if (!ASSIGN_PYLONG_TO_INTEGRAL(&(ts[0].tv_sec), access_py, &overflow))
965     {
966         if (overflow)
967             PyErr_SetString(PyExc_ValueError,
968                             "unable to convert access time seconds for utimensat");
969         return NULL;
970     }
971     if (!ASSIGN_PYLONG_TO_INTEGRAL(&(ts[1].tv_sec), modification_py, &overflow))
972     {
973         if (overflow)
974             PyErr_SetString(PyExc_ValueError,
975                             "unable to convert modification time seconds for utimensat");
976         return NULL;
977     }
978     rc = utimensat(fd, path, ts, flag);
979     if (rc != 0)
980         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
981
982     return Py_BuildValue("O", Py_None);
983 }
984
985 #endif /* def HAVE_UTIMENSAT */
986
987
988 #if defined(HAVE_UTIMES) || defined(HAVE_LUTIMES)
989
990 static int bup_parse_xutimes_args(char **path,
991                                   struct timeval tv[2],
992                                   PyObject *args)
993 {
994     PyObject *access_py, *modification_py;
995     long long access_us, modification_us; // POSIX guarantees tv_usec is signed.
996
997     if (!PyArg_ParseTuple(args, "s((OL)(OL))",
998                           path,
999                           &access_py, &access_us,
1000                           &modification_py, &modification_us))
1001         return 0;
1002
1003     int overflow;
1004     if (!ASSIGN_PYLONG_TO_INTEGRAL(&(tv[0].tv_sec), access_py, &overflow))
1005     {
1006         if (overflow)
1007             PyErr_SetString(PyExc_ValueError, "unable to convert access time seconds to timeval");
1008         return 0;
1009     }
1010     if (!INTEGRAL_ASSIGNMENT_FITS(&(tv[0].tv_usec), access_us))
1011     {
1012         PyErr_SetString(PyExc_ValueError, "unable to convert access time nanoseconds to timeval");
1013         return 0;
1014     }
1015     if (!ASSIGN_PYLONG_TO_INTEGRAL(&(tv[1].tv_sec), modification_py, &overflow))
1016     {
1017         if (overflow)
1018             PyErr_SetString(PyExc_ValueError, "unable to convert modification time seconds to timeval");
1019         return 0;
1020     }
1021     if (!INTEGRAL_ASSIGNMENT_FITS(&(tv[1].tv_usec), modification_us))
1022     {
1023         PyErr_SetString(PyExc_ValueError, "unable to convert modification time nanoseconds to timeval");
1024         return 0;
1025     }
1026     return 1;
1027 }
1028
1029 #endif /* defined(HAVE_UTIMES) || defined(HAVE_LUTIMES) */
1030
1031
1032 #ifdef HAVE_UTIMES
1033 static PyObject *bup_utimes(PyObject *self, PyObject *args)
1034 {
1035     char *path;
1036     struct timeval tv[2];
1037     if (!bup_parse_xutimes_args(&path, tv, args))
1038         return NULL;
1039     int rc = utimes(path, tv);
1040     if (rc != 0)
1041         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1042     return Py_BuildValue("O", Py_None);
1043 }
1044 #endif /* def HAVE_UTIMES */
1045
1046
1047 #ifdef HAVE_LUTIMES
1048 static PyObject *bup_lutimes(PyObject *self, PyObject *args)
1049 {
1050     char *path;
1051     struct timeval tv[2];
1052     if (!bup_parse_xutimes_args(&path, tv, args))
1053         return NULL;
1054     int rc = lutimes(path, tv);
1055     if (rc != 0)
1056         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1057
1058     return Py_BuildValue("O", Py_None);
1059 }
1060 #endif /* def HAVE_LUTIMES */
1061
1062
1063 #ifdef HAVE_STAT_ST_ATIM
1064 # define BUP_STAT_ATIME_NS(st) (st)->st_atim.tv_nsec
1065 # define BUP_STAT_MTIME_NS(st) (st)->st_mtim.tv_nsec
1066 # define BUP_STAT_CTIME_NS(st) (st)->st_ctim.tv_nsec
1067 #elif defined HAVE_STAT_ST_ATIMENSEC
1068 # define BUP_STAT_ATIME_NS(st) (st)->st_atimespec.tv_nsec
1069 # define BUP_STAT_MTIME_NS(st) (st)->st_mtimespec.tv_nsec
1070 # define BUP_STAT_CTIME_NS(st) (st)->st_ctimespec.tv_nsec
1071 #else
1072 # define BUP_STAT_ATIME_NS(st) 0
1073 # define BUP_STAT_MTIME_NS(st) 0
1074 # define BUP_STAT_CTIME_NS(st) 0
1075 #endif
1076
1077
1078 #pragma clang diagnostic push
1079 #pragma clang diagnostic ignored "-Wtautological-compare" // For INTEGER_TO_PY().
1080
1081 static PyObject *stat_struct_to_py(const struct stat *st,
1082                                    const char *filename,
1083                                    int fd)
1084 {
1085     // We can check the known (via POSIX) signed and unsigned types at
1086     // compile time, but not (easily) the unspecified types, so handle
1087     // those via INTEGER_TO_PY().  Assumes ns values will fit in a
1088     // long.
1089     return Py_BuildValue("OKOOOOOL(Ol)(Ol)(Ol)",
1090                          INTEGER_TO_PY(st->st_mode),
1091                          (unsigned PY_LONG_LONG) st->st_ino,
1092                          INTEGER_TO_PY(st->st_dev),
1093                          INTEGER_TO_PY(st->st_nlink),
1094                          INTEGER_TO_PY(st->st_uid),
1095                          INTEGER_TO_PY(st->st_gid),
1096                          INTEGER_TO_PY(st->st_rdev),
1097                          (PY_LONG_LONG) st->st_size,
1098                          INTEGER_TO_PY(st->st_atime),
1099                          (long) BUP_STAT_ATIME_NS(st),
1100                          INTEGER_TO_PY(st->st_mtime),
1101                          (long) BUP_STAT_MTIME_NS(st),
1102                          INTEGER_TO_PY(st->st_ctime),
1103                          (long) BUP_STAT_CTIME_NS(st));
1104 }
1105
1106 #pragma clang diagnostic pop  // ignored "-Wtautological-compare"
1107
1108 static PyObject *bup_stat(PyObject *self, PyObject *args)
1109 {
1110     int rc;
1111     char *filename;
1112
1113     if (!PyArg_ParseTuple(args, "s", &filename))
1114         return NULL;
1115
1116     struct stat st;
1117     rc = stat(filename, &st);
1118     if (rc != 0)
1119         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
1120     return stat_struct_to_py(&st, filename, 0);
1121 }
1122
1123
1124 static PyObject *bup_lstat(PyObject *self, PyObject *args)
1125 {
1126     int rc;
1127     char *filename;
1128
1129     if (!PyArg_ParseTuple(args, "s", &filename))
1130         return NULL;
1131
1132     struct stat st;
1133     rc = lstat(filename, &st);
1134     if (rc != 0)
1135         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
1136     return stat_struct_to_py(&st, filename, 0);
1137 }
1138
1139
1140 static PyObject *bup_fstat(PyObject *self, PyObject *args)
1141 {
1142     int rc, fd;
1143
1144     if (!PyArg_ParseTuple(args, "i", &fd))
1145         return NULL;
1146
1147     struct stat st;
1148     rc = fstat(fd, &st);
1149     if (rc != 0)
1150         return PyErr_SetFromErrno(PyExc_OSError);
1151     return stat_struct_to_py(&st, NULL, fd);
1152 }
1153
1154
1155 static PyMethodDef helper_methods[] = {
1156     { "selftest", selftest, METH_VARARGS,
1157         "Check that the rolling checksum rolls correctly (for unit tests)." },
1158     { "blobbits", blobbits, METH_VARARGS,
1159         "Return the number of bits in the rolling checksum." },
1160     { "splitbuf", splitbuf, METH_VARARGS,
1161         "Split a list of strings based on a rolling checksum." },
1162     { "bitmatch", bitmatch, METH_VARARGS,
1163         "Count the number of matching prefix bits between two strings." },
1164     { "firstword", firstword, METH_VARARGS,
1165         "Return an int corresponding to the first 32 bits of buf." },
1166     { "bloom_contains", bloom_contains, METH_VARARGS,
1167         "Check if a bloom filter of 2^nbits bytes contains an object" },
1168     { "bloom_add", bloom_add, METH_VARARGS,
1169         "Add an object to a bloom filter of 2^nbits bytes" },
1170     { "extract_bits", extract_bits, METH_VARARGS,
1171         "Take the first 'nbits' bits from 'buf' and return them as an int." },
1172     { "merge_into", merge_into, METH_VARARGS,
1173         "Merges a bunch of idx and midx files into a single midx." },
1174     { "write_idx", write_idx, METH_VARARGS,
1175         "Write a PackIdxV2 file from an idx list of lists of tuples" },
1176     { "write_random", write_random, METH_VARARGS,
1177         "Write random bytes to the given file descriptor" },
1178     { "random_sha", random_sha, METH_VARARGS,
1179         "Return a random 20-byte string" },
1180     { "open_noatime", open_noatime, METH_VARARGS,
1181         "open() the given filename for read with O_NOATIME if possible" },
1182     { "fadvise_done", fadvise_done, METH_VARARGS,
1183         "Inform the kernel that we're finished with earlier parts of a file" },
1184 #ifdef BUP_HAVE_FILE_ATTRS
1185     { "get_linux_file_attr", bup_get_linux_file_attr, METH_VARARGS,
1186       "Return the Linux attributes for the given file." },
1187 #endif
1188 #ifdef BUP_HAVE_FILE_ATTRS
1189     { "set_linux_file_attr", bup_set_linux_file_attr, METH_VARARGS,
1190       "Set the Linux attributes for the given file." },
1191 #endif
1192 #ifdef HAVE_UTIMENSAT
1193     { "bup_utimensat", bup_utimensat, METH_VARARGS,
1194       "Change path timestamps with nanosecond precision (POSIX)." },
1195 #endif
1196 #ifdef HAVE_UTIMES
1197     { "bup_utimes", bup_utimes, METH_VARARGS,
1198       "Change path timestamps with microsecond precision." },
1199 #endif
1200 #ifdef HAVE_LUTIMES
1201     { "bup_lutimes", bup_lutimes, METH_VARARGS,
1202       "Change path timestamps with microsecond precision;"
1203       " don't follow symlinks." },
1204 #endif
1205     { "stat", bup_stat, METH_VARARGS,
1206       "Extended version of stat." },
1207     { "lstat", bup_lstat, METH_VARARGS,
1208       "Extended version of lstat." },
1209     { "fstat", bup_fstat, METH_VARARGS,
1210       "Extended version of fstat." },
1211     { NULL, NULL, 0, NULL },  // sentinel
1212 };
1213
1214
1215 PyMODINIT_FUNC init_helpers(void)
1216 {
1217     // FIXME: migrate these tests to configure.  Check against the
1218     // type we're going to use when passing to python.  Other stat
1219     // types are tested at runtime.
1220     assert(sizeof(ino_t) <= sizeof(unsigned PY_LONG_LONG));
1221     assert(sizeof(off_t) <= sizeof(PY_LONG_LONG));
1222     assert(sizeof(blksize_t) <= sizeof(PY_LONG_LONG));
1223     assert(sizeof(blkcnt_t) <= sizeof(PY_LONG_LONG));
1224     // Just be sure (relevant when passing timestamps back to Python above).
1225     assert(sizeof(PY_LONG_LONG) <= sizeof(long long));
1226     assert(sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long long));
1227
1228     char *e;
1229     PyObject *m = Py_InitModule("_helpers", helper_methods);
1230     if (m == NULL)
1231         return;
1232
1233 #pragma clang diagnostic push
1234 #pragma clang diagnostic ignored "-Wtautological-compare" // For INTEGER_TO_PY().
1235 #ifdef HAVE_UTIMENSAT
1236     {
1237         PyObject *value;
1238         value = INTEGER_TO_PY(AT_FDCWD);
1239         PyObject_SetAttrString(m, "AT_FDCWD", value);
1240         Py_DECREF(value);
1241         value = INTEGER_TO_PY(AT_SYMLINK_NOFOLLOW);
1242         PyObject_SetAttrString(m, "AT_SYMLINK_NOFOLLOW", value);
1243         Py_DECREF(value);
1244         value = INTEGER_TO_PY(UTIME_NOW);
1245         PyObject_SetAttrString(m, "UTIME_NOW", value);
1246         Py_DECREF(value);
1247     }
1248 #endif
1249     {
1250         PyObject *value;
1251         const long arg_max = sysconf(_SC_ARG_MAX);
1252         if (arg_max == -1)
1253         {
1254             fprintf(stderr, "Cannot find SC_ARG_MAX, please report a bug.\n");
1255             exit(1);
1256         }
1257         value = INTEGER_TO_PY(arg_max);
1258         PyObject_SetAttrString(m, "SC_ARG_MAX", value);
1259         Py_DECREF(value);
1260     }
1261 #pragma clang diagnostic pop  // ignored "-Wtautological-compare"
1262
1263     e = getenv("BUP_FORCE_TTY");
1264     istty2 = isatty(2) || (atoi(e ? e : "0") & 2);
1265     unpythonize_argv();
1266 }