]> arthur.barton.de Git - bup.git/blob - lib/bup/_helpers.c
c77692ab7e514e489e6f2665afba2b26336afcf0
[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 <stddef.h>
15 #include <stdint.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18
19 #ifdef HAVE_SYS_MMAN_H
20 #include <sys/mman.h>
21 #endif
22 #ifdef HAVE_SYS_TYPES_H
23 #include <sys/types.h>
24 #endif
25 #ifdef HAVE_SYS_STAT_H
26 #include <sys/stat.h>
27 #endif
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31
32 #ifdef HAVE_LINUX_FS_H
33 #include <linux/fs.h>
34 #endif
35 #ifdef HAVE_SYS_IOCTL_H
36 #include <sys/ioctl.h>
37 #endif
38
39 #ifdef HAVE_TM_TM_GMTOFF
40 #include <time.h>
41 #endif
42
43 #include "bupsplit.h"
44
45 #if defined(FS_IOC_GETFLAGS) && defined(FS_IOC_SETFLAGS)
46 #define BUP_HAVE_FILE_ATTRS 1
47 #endif
48
49 /*
50  * Check for incomplete UTIMENSAT support (NetBSD 6), and if so,
51  * pretend we don't have it.
52  */
53 #if !defined(AT_FDCWD) || !defined(AT_SYMLINK_NOFOLLOW)
54 #undef HAVE_UTIMENSAT
55 #endif
56
57 #ifndef FS_NOCOW_FL
58 // Of course, this assumes it's a bitfield value.
59 #define FS_NOCOW_FL 0
60 #endif
61
62
63 typedef unsigned char byte;
64
65 static int istty2 = 0;
66
67
68 #ifndef htonll
69 // This function should technically be macro'd out if it's going to be used
70 // more than ocasionally.  As of this writing, it'll actually never be called
71 // in real world bup scenarios (because our packs are < MAX_INT bytes).
72 static uint64_t htonll(uint64_t value)
73 {
74     static const int endian_test = 42;
75
76     if (*(char *)&endian_test == endian_test) // LSB-MSB
77         return ((uint64_t)htonl(value & 0xFFFFFFFF) << 32) | htonl(value >> 32);
78     return value; // already in network byte order MSB-LSB
79 }
80 #endif
81
82
83 #define INTEGRAL_ASSIGNMENT_FITS(dest, src)                             \
84     ({                                                                  \
85         *(dest) = (src);                                                \
86         *(dest) == (src) && (*(dest) < 1) == ((src) < 1);               \
87     })
88
89
90 // At the moment any code that calls INTGER_TO_PY() will have to
91 // disable -Wtautological-compare for clang.  See below.
92
93 #define INTEGER_TO_PY(x) \
94     (((x) >= 0) ? PyLong_FromUnsignedLongLong(x) : PyLong_FromLongLong(x))
95
96
97 static int bup_ulong_from_pyint(unsigned long *x, PyObject *py,
98                                 const char *name)
99 {
100     const long tmp = PyInt_AsLong(py);
101     if (tmp == -1 && PyErr_Occurred())
102     {
103         if (PyErr_ExceptionMatches(PyExc_OverflowError))
104             PyErr_Format(PyExc_OverflowError, "%s too big for unsigned long",
105                          name);
106         return 0;
107     }
108     if (tmp < 0)
109     {
110         PyErr_Format(PyExc_OverflowError,
111                      "negative %s cannot be converted to unsigned long", name);
112         return 0;
113     }
114     *x = tmp;
115     return 1;
116 }
117
118
119 static int bup_ulong_from_py(unsigned long *x, PyObject *py, const char *name)
120 {
121     if (PyInt_Check(py))
122         return bup_ulong_from_pyint(x, py, name);
123
124     if (!PyLong_Check(py))
125     {
126         PyErr_Format(PyExc_TypeError, "expected integer %s", name);
127         return 0;
128     }
129
130     const unsigned long tmp = PyLong_AsUnsignedLong(py);
131     if (PyErr_Occurred())
132     {
133         if (PyErr_ExceptionMatches(PyExc_OverflowError))
134             PyErr_Format(PyExc_OverflowError, "%s too big for unsigned long",
135                          name);
136         return 0;
137     }
138     *x = tmp;
139     return 1;
140 }
141
142
143 static int bup_uint_from_py(unsigned int *x, PyObject *py, const char *name)
144 {
145     unsigned long tmp;
146     if (!bup_ulong_from_py(&tmp, py, name))
147         return 0;
148
149     if (tmp > UINT_MAX)
150     {
151         PyErr_Format(PyExc_OverflowError, "%s too big for unsigned int", name);
152         return 0;
153     }
154     *x = tmp;
155     return 1;
156 }
157
158 static int bup_ullong_from_py(unsigned PY_LONG_LONG *x, PyObject *py,
159                               const char *name)
160 {
161     if (PyInt_Check(py))
162     {
163         unsigned long tmp;
164         if (bup_ulong_from_pyint(&tmp, py, name))
165         {
166             *x = tmp;
167             return 1;
168         }
169         return 0;
170     }
171
172     if (!PyLong_Check(py))
173     {
174         PyErr_Format(PyExc_TypeError, "integer argument expected for %s", name);
175         return 0;
176     }
177
178     const unsigned PY_LONG_LONG tmp = PyLong_AsUnsignedLongLong(py);
179     if (tmp == (unsigned long long) -1 && PyErr_Occurred())
180     {
181         if (PyErr_ExceptionMatches(PyExc_OverflowError))
182             PyErr_Format(PyExc_OverflowError,
183                          "%s too big for unsigned long long", name);
184         return 0;
185     }
186     *x = tmp;
187     return 1;
188 }
189
190
191 // Probably we should use autoconf or something and set HAVE_PY_GETARGCARGV...
192 #if __WIN32__ || __CYGWIN__
193
194 // There's no 'ps' on win32 anyway, and Py_GetArgcArgv() isn't available.
195 static void unpythonize_argv(void) { }
196
197 #else // not __WIN32__
198
199 // For some reason this isn't declared in Python.h
200 extern void Py_GetArgcArgv(int *argc, char ***argv);
201
202 static void unpythonize_argv(void)
203 {
204     int argc, i;
205     char **argv, *arge;
206     
207     Py_GetArgcArgv(&argc, &argv);
208     
209     for (i = 0; i < argc-1; i++)
210     {
211         if (argv[i] + strlen(argv[i]) + 1 != argv[i+1])
212         {
213             // The argv block doesn't work the way we expected; it's unsafe
214             // to mess with it.
215             return;
216         }
217     }
218     
219     arge = argv[argc-1] + strlen(argv[argc-1]) + 1;
220     
221     if (strstr(argv[0], "python") && argv[1] == argv[0] + strlen(argv[0]) + 1)
222     {
223         char *p;
224         size_t len, diff;
225         p = strrchr(argv[1], '/');
226         if (p)
227         {
228             p++;
229             diff = p - argv[0];
230             len = arge - p;
231             memmove(argv[0], p, len);
232             memset(arge - diff, 0, diff);
233             for (i = 0; i < argc; i++)
234                 argv[i] = argv[i+1] ? argv[i+1]-diff : NULL;
235         }
236     }
237 }
238
239 #endif // not __WIN32__ or __CYGWIN__
240
241
242 static int write_all(int fd, const void *buf, const size_t count)
243 {
244     size_t written = 0;
245     while (written < count)
246     {
247         const ssize_t rc = write(fd, buf + written, count - written);
248         if (rc == -1)
249             return -1;
250         written += rc;
251     }
252     return 0;
253 }
254
255
256 static int uadd(unsigned long long *dest,
257                 const unsigned long long x,
258                 const unsigned long long y)
259 {
260     const unsigned long long result = x + y;
261     if (result < x || result < y)
262         return 0;
263     *dest = result;
264     return 1;
265 }
266
267
268 static PyObject *append_sparse_region(const int fd, unsigned long long n)
269 {
270     while (n)
271     {
272         off_t new_off;
273         if (!INTEGRAL_ASSIGNMENT_FITS(&new_off, n))
274             new_off = INT_MAX;
275         const off_t off = lseek(fd, new_off, SEEK_CUR);
276         if (off == (off_t) -1)
277             return PyErr_SetFromErrno(PyExc_IOError);
278         n -= new_off;
279     }
280     return NULL;
281 }
282
283
284 static PyObject *record_sparse_zeros(unsigned long long *new_pending,
285                                      const int fd,
286                                      unsigned long long prev_pending,
287                                      const unsigned long long count)
288 {
289     // Add count additional sparse zeros to prev_pending and store the
290     // result in new_pending, or if the total won't fit in
291     // new_pending, write some of the zeros to fd sparsely, and store
292     // the remaining sum in new_pending.
293     if (!uadd(new_pending, prev_pending, count))
294     {
295         PyObject *err = append_sparse_region(fd, prev_pending);
296         if (err != NULL)
297             return err;
298         *new_pending = count;
299     }
300     return NULL;
301 }
302
303
304 static byte* find_not_zero(const byte * const start, const byte * const end)
305 {
306     // Return a pointer to first non-zero byte between start and end,
307     // or end if there isn't one.
308     assert(start <= end);
309     const unsigned char *cur = start;
310     while (cur < end && *cur == 0)
311         cur++;
312     return (byte *) cur;
313 }
314
315
316 static byte* find_trailing_zeros(const byte * const start,
317                                  const byte * const end)
318 {
319     // Return a pointer to the start of any trailing run of zeros, or
320     // end if there isn't one.
321     assert(start <= end);
322     if (start == end)
323         return (byte *) end;
324     const byte * cur = end;
325     while (cur > start && *--cur == 0) {}
326     if (*cur == 0)
327         return (byte *) cur;
328     else
329         return (byte *) (cur + 1);
330 }
331
332
333 static byte *find_non_sparse_end(const byte * const start,
334                                  const byte * const end,
335                                  const unsigned long long min_len)
336 {
337     // Return the first pointer to a min_len sparse block in [start,
338     // end) if there is one, otherwise a pointer to the start of any
339     // trailing run of zeros.  If there are no trailing zeros, return
340     // end.
341     if (start == end)
342         return (byte *) end;
343     assert(start < end);
344     assert(min_len);
345     // Probe in min_len jumps, searching backward from the jump
346     // destination for a non-zero byte.  If such a byte is found, move
347     // just past it and try again.
348     const byte *candidate = start;
349     // End of any run of zeros, starting at candidate, that we've already seen
350     const byte *end_of_known_zeros = candidate;
351     while (end - candidate >= min_len) // Handle all min_len candidate blocks
352     {
353         const byte * const probe_end = candidate + min_len;
354         const byte * const trailing_zeros =
355             find_trailing_zeros(end_of_known_zeros, probe_end);
356         if (trailing_zeros == probe_end)
357             end_of_known_zeros = candidate = probe_end;
358         else if (trailing_zeros == end_of_known_zeros)
359         {
360             assert(candidate >= start);
361             assert(candidate <= end);
362             assert(*candidate == 0);
363             return (byte *) candidate;
364         }
365         else
366         {
367             candidate = trailing_zeros;
368             end_of_known_zeros = probe_end;
369         }
370     }
371
372     if (candidate == end)
373         return (byte *) end;
374
375     // No min_len sparse run found, search backward from end
376     const byte * const trailing_zeros = find_trailing_zeros(end_of_known_zeros,
377                                                             end);
378
379     if (trailing_zeros == end_of_known_zeros)
380     {
381         assert(candidate >= start);
382         assert(candidate < end);
383         assert(*candidate == 0);
384         assert(end - candidate < min_len);
385         return (byte *) candidate;
386     }
387
388     if (trailing_zeros == end)
389     {
390         assert(*(end - 1) != 0);
391         return (byte *) end;
392     }
393
394     assert(end - trailing_zeros < min_len);
395     assert(trailing_zeros >= start);
396     assert(trailing_zeros < end);
397     assert(*trailing_zeros == 0);
398     return (byte *) trailing_zeros;
399 }
400
401
402 static PyObject *bup_write_sparsely(PyObject *self, PyObject *args)
403 {
404     int fd;
405     unsigned char *buf = NULL;
406     Py_ssize_t sbuf_len;
407     PyObject *py_min_sparse_len, *py_prev_sparse_len;
408     if (!PyArg_ParseTuple(args, "it#OO",
409                           &fd, &buf, &sbuf_len,
410                           &py_min_sparse_len, &py_prev_sparse_len))
411         return NULL;
412     unsigned long long min_sparse_len, prev_sparse_len, buf_len;
413     if (!bup_ullong_from_py(&min_sparse_len, py_min_sparse_len, "min_sparse_len"))
414         return NULL;
415     if (!bup_ullong_from_py(&prev_sparse_len, py_prev_sparse_len, "prev_sparse_len"))
416         return NULL;
417     if (sbuf_len < 0)
418         return PyErr_Format(PyExc_ValueError, "negative bufer length");
419     if (!INTEGRAL_ASSIGNMENT_FITS(&buf_len, sbuf_len))
420         return PyErr_Format(PyExc_OverflowError, "buffer length too large");
421
422     const byte * block = buf; // Start of pending block
423     const byte * const end = buf + buf_len;
424     unsigned long long zeros = prev_sparse_len;
425     while (1)
426     {
427         assert(block <= end);
428         if (block == end)
429             return PyLong_FromUnsignedLongLong(zeros);
430
431         if (*block != 0)
432         {
433             // Look for the end of block, i.e. the next sparse run of
434             // at least min_sparse_len zeros, or the end of the
435             // buffer.
436             const byte * const probe = find_non_sparse_end(block + 1, end,
437                                                            min_sparse_len);
438             // Either at end of block, or end of non-sparse; write pending data
439             PyObject *err = append_sparse_region(fd, zeros);
440             if (err != NULL)
441                 return err;
442             int rc = write_all(fd, block, probe - block);
443             if (rc)
444                 return PyErr_SetFromErrno(PyExc_IOError);
445
446             if (end - probe < min_sparse_len)
447                 zeros = end - probe;
448             else
449                 zeros = min_sparse_len;
450             block = probe + zeros;
451         }
452         else // *block == 0
453         {
454             // Should be in the first loop iteration, a sparse run of
455             // zeros, or nearly at the end of the block (within
456             // min_sparse_len).
457             const byte * const zeros_end = find_not_zero(block, end);
458             PyObject *err = record_sparse_zeros(&zeros, fd,
459                                                 zeros, zeros_end - block);
460             if (err != NULL)
461                 return err;
462             assert(block <= zeros_end);
463             block = zeros_end;
464         }
465     }
466 }
467
468
469 static PyObject *selftest(PyObject *self, PyObject *args)
470 {
471     if (!PyArg_ParseTuple(args, ""))
472         return NULL;
473     
474     return Py_BuildValue("i", !bupsplit_selftest());
475 }
476
477
478 static PyObject *blobbits(PyObject *self, PyObject *args)
479 {
480     if (!PyArg_ParseTuple(args, ""))
481         return NULL;
482     return Py_BuildValue("i", BUP_BLOBBITS);
483 }
484
485
486 static PyObject *splitbuf(PyObject *self, PyObject *args)
487 {
488     unsigned char *buf = NULL;
489     Py_ssize_t len = 0;
490     int out = 0, bits = -1;
491
492     if (!PyArg_ParseTuple(args, "t#", &buf, &len))
493         return NULL;
494     assert(len <= INT_MAX);
495     out = bupsplit_find_ofs(buf, len, &bits);
496     if (out) assert(bits >= BUP_BLOBBITS);
497     return Py_BuildValue("ii", out, bits);
498 }
499
500
501 static PyObject *bitmatch(PyObject *self, PyObject *args)
502 {
503     unsigned char *buf1 = NULL, *buf2 = NULL;
504     Py_ssize_t len1 = 0, len2 = 0;
505     Py_ssize_t byte;
506     int bit;
507
508     if (!PyArg_ParseTuple(args, "t#t#", &buf1, &len1, &buf2, &len2))
509         return NULL;
510     
511     bit = 0;
512     for (byte = 0; byte < len1 && byte < len2; byte++)
513     {
514         int b1 = buf1[byte], b2 = buf2[byte];
515         if (b1 != b2)
516         {
517             for (bit = 0; bit < 8; bit++)
518                 if ( (b1 & (0x80 >> bit)) != (b2 & (0x80 >> bit)) )
519                     break;
520             break;
521         }
522     }
523     
524     assert(byte <= (INT_MAX >> 3));
525     return Py_BuildValue("i", byte*8 + bit);
526 }
527
528
529 static PyObject *firstword(PyObject *self, PyObject *args)
530 {
531     unsigned char *buf = NULL;
532     Py_ssize_t len = 0;
533     uint32_t v;
534
535     if (!PyArg_ParseTuple(args, "t#", &buf, &len))
536         return NULL;
537     
538     if (len < 4)
539         return NULL;
540     
541     v = ntohl(*(uint32_t *)buf);
542     return PyLong_FromUnsignedLong(v);
543 }
544
545
546 #define BLOOM2_HEADERLEN 16
547
548 static void to_bloom_address_bitmask4(const unsigned char *buf,
549         const int nbits, uint64_t *v, unsigned char *bitmask)
550 {
551     int bit;
552     uint32_t high;
553     uint64_t raw, mask;
554
555     memcpy(&high, buf, 4);
556     mask = (1<<nbits) - 1;
557     raw = (((uint64_t)ntohl(high) << 8) | buf[4]);
558     bit = (raw >> (37-nbits)) & 0x7;
559     *v = (raw >> (40-nbits)) & mask;
560     *bitmask = 1 << bit;
561 }
562
563 static void to_bloom_address_bitmask5(const unsigned char *buf,
564         const int nbits, uint32_t *v, unsigned char *bitmask)
565 {
566     int bit;
567     uint32_t high;
568     uint32_t raw, mask;
569
570     memcpy(&high, buf, 4);
571     mask = (1<<nbits) - 1;
572     raw = ntohl(high);
573     bit = (raw >> (29-nbits)) & 0x7;
574     *v = (raw >> (32-nbits)) & mask;
575     *bitmask = 1 << bit;
576 }
577
578 #define BLOOM_SET_BIT(name, address, otype) \
579 static void name(unsigned char *bloom, const unsigned char *buf, const int nbits)\
580 {\
581     unsigned char bitmask;\
582     otype v;\
583     address(buf, nbits, &v, &bitmask);\
584     bloom[BLOOM2_HEADERLEN+v] |= bitmask;\
585 }
586 BLOOM_SET_BIT(bloom_set_bit4, to_bloom_address_bitmask4, uint64_t)
587 BLOOM_SET_BIT(bloom_set_bit5, to_bloom_address_bitmask5, uint32_t)
588
589
590 #define BLOOM_GET_BIT(name, address, otype) \
591 static int name(const unsigned char *bloom, const unsigned char *buf, const int nbits)\
592 {\
593     unsigned char bitmask;\
594     otype v;\
595     address(buf, nbits, &v, &bitmask);\
596     return bloom[BLOOM2_HEADERLEN+v] & bitmask;\
597 }
598 BLOOM_GET_BIT(bloom_get_bit4, to_bloom_address_bitmask4, uint64_t)
599 BLOOM_GET_BIT(bloom_get_bit5, to_bloom_address_bitmask5, uint32_t)
600
601
602 static PyObject *bloom_add(PyObject *self, PyObject *args)
603 {
604     unsigned char *sha = NULL, *bloom = NULL;
605     unsigned char *end;
606     Py_ssize_t len = 0, blen = 0;
607     int nbits = 0, k = 0;
608
609     if (!PyArg_ParseTuple(args, "w#s#ii", &bloom, &blen, &sha, &len, &nbits, &k))
610         return NULL;
611
612     if (blen < 16+(1<<nbits) || len % 20 != 0)
613         return NULL;
614
615     if (k == 5)
616     {
617         if (nbits > 29)
618             return NULL;
619         for (end = sha + len; sha < end; sha += 20/k)
620             bloom_set_bit5(bloom, sha, nbits);
621     }
622     else if (k == 4)
623     {
624         if (nbits > 37)
625             return NULL;
626         for (end = sha + len; sha < end; sha += 20/k)
627             bloom_set_bit4(bloom, sha, nbits);
628     }
629     else
630         return NULL;
631
632
633     return Py_BuildValue("n", len/20);
634 }
635
636 static PyObject *bloom_contains(PyObject *self, PyObject *args)
637 {
638     unsigned char *sha = NULL, *bloom = NULL;
639     Py_ssize_t len = 0, blen = 0;
640     int nbits = 0, k = 0;
641     unsigned char *end;
642     int steps;
643
644     if (!PyArg_ParseTuple(args, "t#s#ii", &bloom, &blen, &sha, &len, &nbits, &k))
645         return NULL;
646
647     if (len != 20)
648         return NULL;
649
650     if (k == 5)
651     {
652         if (nbits > 29)
653             return NULL;
654         for (steps = 1, end = sha + 20; sha < end; sha += 20/k, steps++)
655             if (!bloom_get_bit5(bloom, sha, nbits))
656                 return Py_BuildValue("Oi", Py_None, steps);
657     }
658     else if (k == 4)
659     {
660         if (nbits > 37)
661             return NULL;
662         for (steps = 1, end = sha + 20; sha < end; sha += 20/k, steps++)
663             if (!bloom_get_bit4(bloom, sha, nbits))
664                 return Py_BuildValue("Oi", Py_None, steps);
665     }
666     else
667         return NULL;
668
669     return Py_BuildValue("ii", 1, k);
670 }
671
672
673 static uint32_t _extract_bits(unsigned char *buf, int nbits)
674 {
675     uint32_t v, mask;
676
677     mask = (1<<nbits) - 1;
678     v = ntohl(*(uint32_t *)buf);
679     v = (v >> (32-nbits)) & mask;
680     return v;
681 }
682
683
684 static PyObject *extract_bits(PyObject *self, PyObject *args)
685 {
686     unsigned char *buf = NULL;
687     Py_ssize_t len = 0;
688     int nbits = 0;
689
690     if (!PyArg_ParseTuple(args, "t#i", &buf, &len, &nbits))
691         return NULL;
692     
693     if (len < 4)
694         return NULL;
695     
696     return PyLong_FromUnsignedLong(_extract_bits(buf, nbits));
697 }
698
699
700 struct sha {
701     unsigned char bytes[20];
702 };
703
704
705 struct idx {
706     unsigned char *map;
707     struct sha *cur;
708     struct sha *end;
709     uint32_t *cur_name;
710     Py_ssize_t bytes;
711     int name_base;
712 };
713
714
715 static int _cmp_sha(const struct sha *sha1, const struct sha *sha2)
716 {
717     int i;
718     for (i = 0; i < sizeof(struct sha); i++)
719         if (sha1->bytes[i] != sha2->bytes[i])
720             return sha1->bytes[i] - sha2->bytes[i];
721     return 0;
722 }
723
724
725 static void _fix_idx_order(struct idx **idxs, int *last_i)
726 {
727     struct idx *idx;
728     int low, mid, high, c = 0;
729
730     idx = idxs[*last_i];
731     if (idxs[*last_i]->cur >= idxs[*last_i]->end)
732     {
733         idxs[*last_i] = NULL;
734         PyMem_Free(idx);
735         --*last_i;
736         return;
737     }
738     if (*last_i == 0)
739         return;
740
741     low = *last_i-1;
742     mid = *last_i;
743     high = 0;
744     while (low >= high)
745     {
746         mid = (low + high) / 2;
747         c = _cmp_sha(idx->cur, idxs[mid]->cur);
748         if (c < 0)
749             high = mid + 1;
750         else if (c > 0)
751             low = mid - 1;
752         else
753             break;
754     }
755     if (c < 0)
756         ++mid;
757     if (mid == *last_i)
758         return;
759     memmove(&idxs[mid+1], &idxs[mid], (*last_i-mid)*sizeof(struct idx *));
760     idxs[mid] = idx;
761 }
762
763
764 static uint32_t _get_idx_i(struct idx *idx)
765 {
766     if (idx->cur_name == NULL)
767         return idx->name_base;
768     return ntohl(*idx->cur_name) + idx->name_base;
769 }
770
771 #define MIDX4_HEADERLEN 12
772
773 static PyObject *merge_into(PyObject *self, PyObject *args)
774 {
775     PyObject *py_total, *ilist = NULL;
776     unsigned char *fmap = NULL;
777     struct sha *sha_ptr, *sha_start = NULL;
778     uint32_t *table_ptr, *name_ptr, *name_start;
779     struct idx **idxs = NULL;
780     Py_ssize_t flen = 0;
781     int bits = 0, i;
782     unsigned int total;
783     uint32_t count, prefix;
784     int num_i;
785     int last_i;
786
787     if (!PyArg_ParseTuple(args, "w#iOO",
788                           &fmap, &flen, &bits, &py_total, &ilist))
789         return NULL;
790
791     if (!bup_uint_from_py(&total, py_total, "total"))
792         return NULL;
793
794     num_i = PyList_Size(ilist);
795     idxs = (struct idx **)PyMem_Malloc(num_i * sizeof(struct idx *));
796
797     for (i = 0; i < num_i; i++)
798     {
799         long len, sha_ofs, name_map_ofs;
800         idxs[i] = (struct idx *)PyMem_Malloc(sizeof(struct idx));
801         PyObject *itup = PyList_GetItem(ilist, i);
802         if (!PyArg_ParseTuple(itup, "t#llli", &idxs[i]->map, &idxs[i]->bytes,
803                     &len, &sha_ofs, &name_map_ofs, &idxs[i]->name_base))
804             return NULL;
805         idxs[i]->cur = (struct sha *)&idxs[i]->map[sha_ofs];
806         idxs[i]->end = &idxs[i]->cur[len];
807         if (name_map_ofs)
808             idxs[i]->cur_name = (uint32_t *)&idxs[i]->map[name_map_ofs];
809         else
810             idxs[i]->cur_name = NULL;
811     }
812     table_ptr = (uint32_t *)&fmap[MIDX4_HEADERLEN];
813     sha_start = sha_ptr = (struct sha *)&table_ptr[1<<bits];
814     name_start = name_ptr = (uint32_t *)&sha_ptr[total];
815
816     last_i = num_i-1;
817     count = 0;
818     prefix = 0;
819     while (last_i >= 0)
820     {
821         struct idx *idx;
822         uint32_t new_prefix;
823         if (count % 102424 == 0 && istty2)
824             fprintf(stderr, "midx: writing %.2f%% (%d/%d)\r",
825                     count*100.0/total, count, total);
826         idx = idxs[last_i];
827         new_prefix = _extract_bits((unsigned char *)idx->cur, bits);
828         while (prefix < new_prefix)
829             table_ptr[prefix++] = htonl(count);
830         memcpy(sha_ptr++, idx->cur, sizeof(struct sha));
831         *name_ptr++ = htonl(_get_idx_i(idx));
832         ++idx->cur;
833         if (idx->cur_name != NULL)
834             ++idx->cur_name;
835         _fix_idx_order(idxs, &last_i);
836         ++count;
837     }
838     while (prefix < (1<<bits))
839         table_ptr[prefix++] = htonl(count);
840     assert(count == total);
841     assert(prefix == (1<<bits));
842     assert(sha_ptr == sha_start+count);
843     assert(name_ptr == name_start+count);
844
845     PyMem_Free(idxs);
846     return PyLong_FromUnsignedLong(count);
847 }
848
849 #define FAN_ENTRIES 256
850
851 static PyObject *write_idx(PyObject *self, PyObject *args)
852 {
853     char *filename = NULL;
854     PyObject *py_total, *idx = NULL;
855     PyObject *part;
856     unsigned char *fmap = NULL;
857     Py_ssize_t flen = 0;
858     unsigned int total = 0;
859     uint32_t count;
860     int i, j, ofs64_count;
861     uint32_t *fan_ptr, *crc_ptr, *ofs_ptr;
862     uint64_t *ofs64_ptr;
863     struct sha *sha_ptr;
864
865     if (!PyArg_ParseTuple(args, "sw#OO",
866                           &filename, &fmap, &flen, &idx, &py_total))
867         return NULL;
868
869     if (!bup_uint_from_py(&total, py_total, "total"))
870         return NULL;
871
872     if (PyList_Size (idx) != FAN_ENTRIES) // Check for list of the right length.
873         return PyErr_Format (PyExc_TypeError, "idx must contain %d entries",
874                              FAN_ENTRIES);
875
876     const char idx_header[] = "\377tOc\0\0\0\002";
877     memcpy (fmap, idx_header, sizeof(idx_header) - 1);
878
879     fan_ptr = (uint32_t *)&fmap[sizeof(idx_header) - 1];
880     sha_ptr = (struct sha *)&fan_ptr[FAN_ENTRIES];
881     crc_ptr = (uint32_t *)&sha_ptr[total];
882     ofs_ptr = (uint32_t *)&crc_ptr[total];
883     ofs64_ptr = (uint64_t *)&ofs_ptr[total];
884
885     count = 0;
886     ofs64_count = 0;
887     for (i = 0; i < FAN_ENTRIES; ++i)
888     {
889         int plen;
890         part = PyList_GET_ITEM(idx, i);
891         PyList_Sort(part);
892         plen = PyList_GET_SIZE(part);
893         count += plen;
894         *fan_ptr++ = htonl(count);
895         for (j = 0; j < plen; ++j)
896         {
897             unsigned char *sha = NULL;
898             Py_ssize_t sha_len = 0;
899             PyObject *crc_py, *ofs_py;
900             unsigned int crc;
901             unsigned PY_LONG_LONG ofs_ull;
902             uint64_t ofs;
903             if (!PyArg_ParseTuple(PyList_GET_ITEM(part, j), "t#OO",
904                                   &sha, &sha_len, &crc_py, &ofs_py))
905                 return NULL;
906             if(!bup_uint_from_py(&crc, crc_py, "crc"))
907                 return NULL;
908             if(!bup_ullong_from_py(&ofs_ull, ofs_py, "ofs"))
909                 return NULL;
910             assert(crc <= UINT32_MAX);
911             assert(ofs_ull <= UINT64_MAX);
912             ofs = ofs_ull;
913             if (sha_len != sizeof(struct sha))
914                 return NULL;
915             memcpy(sha_ptr++, sha, sizeof(struct sha));
916             *crc_ptr++ = htonl(crc);
917             if (ofs > 0x7fffffff)
918             {
919                 *ofs64_ptr++ = htonll(ofs);
920                 ofs = 0x80000000 | ofs64_count++;
921             }
922             *ofs_ptr++ = htonl((uint32_t)ofs);
923         }
924     }
925
926     int rc = msync(fmap, flen, MS_ASYNC);
927     if (rc != 0)
928         return PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
929
930     return PyLong_FromUnsignedLong(count);
931 }
932
933
934 // I would have made this a lower-level function that just fills in a buffer
935 // with random values, and then written those values from python.  But that's
936 // about 20% slower in my tests, and since we typically generate random
937 // numbers for benchmarking other parts of bup, any slowness in generating
938 // random bytes will make our benchmarks inaccurate.  Plus nobody wants
939 // pseudorandom bytes much except for this anyway.
940 static PyObject *write_random(PyObject *self, PyObject *args)
941 {
942     uint32_t buf[1024/4];
943     int fd = -1, seed = 0, verbose = 0;
944     ssize_t ret;
945     long long len = 0, kbytes = 0, written = 0;
946
947     if (!PyArg_ParseTuple(args, "iLii", &fd, &len, &seed, &verbose))
948         return NULL;
949     
950     srandom(seed);
951     
952     for (kbytes = 0; kbytes < len/1024; kbytes++)
953     {
954         unsigned i;
955         for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i++)
956             buf[i] = random();
957         ret = write(fd, buf, sizeof(buf));
958         if (ret < 0)
959             ret = 0;
960         written += ret;
961         if (ret < (int)sizeof(buf))
962             break;
963         if (verbose && kbytes/1024 > 0 && !(kbytes%1024))
964             fprintf(stderr, "Random: %lld Mbytes\r", kbytes/1024);
965     }
966     
967     // handle non-multiples of 1024
968     if (len % 1024)
969     {
970         unsigned i;
971         for (i = 0; i < sizeof(buf)/sizeof(buf[0]); i++)
972             buf[i] = random();
973         ret = write(fd, buf, len % 1024);
974         if (ret < 0)
975             ret = 0;
976         written += ret;
977     }
978     
979     if (kbytes/1024 > 0)
980         fprintf(stderr, "Random: %lld Mbytes, done.\n", kbytes/1024);
981     return Py_BuildValue("L", written);
982 }
983
984
985 static PyObject *random_sha(PyObject *self, PyObject *args)
986 {
987     static int seeded = 0;
988     uint32_t shabuf[20/4];
989     int i;
990     
991     if (!seeded)
992     {
993         assert(sizeof(shabuf) == 20);
994         srandom(time(NULL));
995         seeded = 1;
996     }
997     
998     if (!PyArg_ParseTuple(args, ""))
999         return NULL;
1000     
1001     memset(shabuf, 0, sizeof(shabuf));
1002     for (i=0; i < 20/4; i++)
1003         shabuf[i] = random();
1004     return Py_BuildValue("s#", shabuf, 20);
1005 }
1006
1007
1008 static int _open_noatime(const char *filename, int attrs)
1009 {
1010     int attrs_noatime, fd;
1011     attrs |= O_RDONLY;
1012 #ifdef O_NOFOLLOW
1013     attrs |= O_NOFOLLOW;
1014 #endif
1015 #ifdef O_LARGEFILE
1016     attrs |= O_LARGEFILE;
1017 #endif
1018     attrs_noatime = attrs;
1019 #ifdef O_NOATIME
1020     attrs_noatime |= O_NOATIME;
1021 #endif
1022     fd = open(filename, attrs_noatime);
1023     if (fd < 0 && errno == EPERM)
1024     {
1025         // older Linux kernels would return EPERM if you used O_NOATIME
1026         // and weren't the file's owner.  This pointless restriction was
1027         // relaxed eventually, but we have to handle it anyway.
1028         // (VERY old kernels didn't recognized O_NOATIME, but they would
1029         // just harmlessly ignore it, so this branch won't trigger)
1030         fd = open(filename, attrs);
1031     }
1032     return fd;
1033 }
1034
1035
1036 static PyObject *open_noatime(PyObject *self, PyObject *args)
1037 {
1038     char *filename = NULL;
1039     int fd;
1040     if (!PyArg_ParseTuple(args, "s", &filename))
1041         return NULL;
1042     fd = _open_noatime(filename, 0);
1043     if (fd < 0)
1044         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
1045     return Py_BuildValue("i", fd);
1046 }
1047
1048
1049 static PyObject *fadvise_done(PyObject *self, PyObject *args)
1050 {
1051     int fd = -1;
1052     long long llofs, lllen = 0;
1053     if (!PyArg_ParseTuple(args, "iLL", &fd, &llofs, &lllen))
1054         return NULL;
1055     off_t ofs, len;
1056     if (!INTEGRAL_ASSIGNMENT_FITS(&ofs, llofs))
1057         return PyErr_Format(PyExc_OverflowError,
1058                             "fadvise offset overflows off_t");
1059     if (!INTEGRAL_ASSIGNMENT_FITS(&len, lllen))
1060         return PyErr_Format(PyExc_OverflowError,
1061                             "fadvise length overflows off_t");
1062 #ifdef POSIX_FADV_DONTNEED
1063     posix_fadvise(fd, ofs, len, POSIX_FADV_DONTNEED);
1064 #endif    
1065     return Py_BuildValue("");
1066 }
1067
1068
1069 // Currently the Linux kernel and FUSE disagree over the type for
1070 // FS_IOC_GETFLAGS and FS_IOC_SETFLAGS.  The kernel actually uses int,
1071 // but FUSE chose long (matching the declaration in linux/fs.h).  So
1072 // if you use int, and then traverse a FUSE filesystem, you may
1073 // corrupt the stack.  But if you use long, then you may get invalid
1074 // results on big-endian systems.
1075 //
1076 // For now, we just use long, and then disable Linux attrs entirely
1077 // (with a warning) in helpers.py on systems that are affected.
1078
1079 #ifdef BUP_HAVE_FILE_ATTRS
1080 static PyObject *bup_get_linux_file_attr(PyObject *self, PyObject *args)
1081 {
1082     int rc;
1083     unsigned long attr;
1084     char *path;
1085     int fd;
1086
1087     if (!PyArg_ParseTuple(args, "s", &path))
1088         return NULL;
1089
1090     fd = _open_noatime(path, O_NONBLOCK);
1091     if (fd == -1)
1092         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1093
1094     attr = 0;  // Handle int/long mismatch (see above)
1095     rc = ioctl(fd, FS_IOC_GETFLAGS, &attr);
1096     if (rc == -1)
1097     {
1098         close(fd);
1099         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1100     }
1101     close(fd);
1102     assert(attr <= UINT_MAX);  // Kernel type is actually int
1103     return PyLong_FromUnsignedLong(attr);
1104 }
1105 #endif /* def BUP_HAVE_FILE_ATTRS */
1106
1107
1108
1109 #ifdef BUP_HAVE_FILE_ATTRS
1110 static PyObject *bup_set_linux_file_attr(PyObject *self, PyObject *args)
1111 {
1112     int rc;
1113     unsigned long orig_attr;
1114     unsigned int attr;
1115     char *path;
1116     PyObject *py_attr;
1117     int fd;
1118
1119     if (!PyArg_ParseTuple(args, "sO", &path, &py_attr))
1120         return NULL;
1121
1122     if (!bup_uint_from_py(&attr, py_attr, "attr"))
1123         return NULL;
1124
1125     fd = open(path, O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_NOFOLLOW);
1126     if (fd == -1)
1127         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1128
1129     // Restrict attr to modifiable flags acdeijstuADST -- see
1130     // chattr(1) and the e2fsprogs source.  Letter to flag mapping is
1131     // in pf.c flags_array[].
1132     attr &= FS_APPEND_FL | FS_COMPR_FL | FS_NODUMP_FL | FS_EXTENT_FL
1133     | FS_IMMUTABLE_FL | FS_JOURNAL_DATA_FL | FS_SECRM_FL | FS_NOTAIL_FL
1134     | FS_UNRM_FL | FS_NOATIME_FL | FS_DIRSYNC_FL | FS_SYNC_FL
1135     | FS_TOPDIR_FL | FS_NOCOW_FL;
1136
1137     // The extents flag can't be removed, so don't (see chattr(1) and chattr.c).
1138     orig_attr = 0; // Handle int/long mismatch (see above)
1139     rc = ioctl(fd, FS_IOC_GETFLAGS, &orig_attr);
1140     assert(orig_attr <= UINT_MAX);  // Kernel type is actually int
1141     if (rc == -1)
1142     {
1143         close(fd);
1144         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1145     }
1146     attr |= ((unsigned int) orig_attr) & FS_EXTENT_FL;
1147
1148     rc = ioctl(fd, FS_IOC_SETFLAGS, &attr);
1149     if (rc == -1)
1150     {
1151         close(fd);
1152         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1153     }
1154
1155     close(fd);
1156     return Py_BuildValue("O", Py_None);
1157 }
1158 #endif /* def BUP_HAVE_FILE_ATTRS */
1159
1160
1161 #ifndef HAVE_UTIMENSAT
1162 #ifndef HAVE_UTIMES
1163 #error "cannot find utimensat or utimes()"
1164 #endif
1165 #ifndef HAVE_LUTIMES
1166 #error "cannot find utimensat or lutimes()"
1167 #endif
1168 #endif
1169
1170 #define ASSIGN_PYLONG_TO_INTEGRAL(dest, pylong, overflow) \
1171     ({                                                     \
1172         int result = 0;                                                 \
1173         *(overflow) = 0;                                                \
1174         const long long lltmp = PyLong_AsLongLong(pylong);              \
1175         if (lltmp == -1 && PyErr_Occurred())                            \
1176         {                                                               \
1177             if (PyErr_ExceptionMatches(PyExc_OverflowError))            \
1178             {                                                           \
1179                 const unsigned long long ulltmp = PyLong_AsUnsignedLongLong(pylong); \
1180                 if (ulltmp == (unsigned long long) -1 && PyErr_Occurred()) \
1181                 {                                                       \
1182                     if (PyErr_ExceptionMatches(PyExc_OverflowError))    \
1183                     {                                                   \
1184                         PyErr_Clear();                                  \
1185                         *(overflow) = 1;                                \
1186                     }                                                   \
1187                 }                                                       \
1188                 if (INTEGRAL_ASSIGNMENT_FITS((dest), ulltmp))           \
1189                     result = 1;                                         \
1190                 else                                                    \
1191                     *(overflow) = 1;                                    \
1192             }                                                           \
1193         }                                                               \
1194         else                                                            \
1195         {                                                               \
1196             if (INTEGRAL_ASSIGNMENT_FITS((dest), lltmp))                \
1197                 result = 1;                                             \
1198             else                                                        \
1199                 *(overflow) = 1;                                        \
1200         }                                                               \
1201         result;                                                         \
1202         })
1203
1204
1205 #ifdef HAVE_UTIMENSAT
1206
1207 static PyObject *bup_utimensat(PyObject *self, PyObject *args)
1208 {
1209     int rc;
1210     int fd, flag;
1211     char *path;
1212     PyObject *access_py, *modification_py;
1213     struct timespec ts[2];
1214
1215     if (!PyArg_ParseTuple(args, "is((Ol)(Ol))i",
1216                           &fd,
1217                           &path,
1218                           &access_py, &(ts[0].tv_nsec),
1219                           &modification_py, &(ts[1].tv_nsec),
1220                           &flag))
1221         return NULL;
1222
1223     int overflow;
1224     if (!ASSIGN_PYLONG_TO_INTEGRAL(&(ts[0].tv_sec), access_py, &overflow))
1225     {
1226         if (overflow)
1227             PyErr_SetString(PyExc_ValueError,
1228                             "unable to convert access time seconds for utimensat");
1229         return NULL;
1230     }
1231     if (!ASSIGN_PYLONG_TO_INTEGRAL(&(ts[1].tv_sec), modification_py, &overflow))
1232     {
1233         if (overflow)
1234             PyErr_SetString(PyExc_ValueError,
1235                             "unable to convert modification time seconds for utimensat");
1236         return NULL;
1237     }
1238     rc = utimensat(fd, path, ts, flag);
1239     if (rc != 0)
1240         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1241
1242     return Py_BuildValue("O", Py_None);
1243 }
1244
1245 #endif /* def HAVE_UTIMENSAT */
1246
1247
1248 #if defined(HAVE_UTIMES) || defined(HAVE_LUTIMES)
1249
1250 static int bup_parse_xutimes_args(char **path,
1251                                   struct timeval tv[2],
1252                                   PyObject *args)
1253 {
1254     PyObject *access_py, *modification_py;
1255     long long access_us, modification_us; // POSIX guarantees tv_usec is signed.
1256
1257     if (!PyArg_ParseTuple(args, "s((OL)(OL))",
1258                           path,
1259                           &access_py, &access_us,
1260                           &modification_py, &modification_us))
1261         return 0;
1262
1263     int overflow;
1264     if (!ASSIGN_PYLONG_TO_INTEGRAL(&(tv[0].tv_sec), access_py, &overflow))
1265     {
1266         if (overflow)
1267             PyErr_SetString(PyExc_ValueError, "unable to convert access time seconds to timeval");
1268         return 0;
1269     }
1270     if (!INTEGRAL_ASSIGNMENT_FITS(&(tv[0].tv_usec), access_us))
1271     {
1272         PyErr_SetString(PyExc_ValueError, "unable to convert access time nanoseconds to timeval");
1273         return 0;
1274     }
1275     if (!ASSIGN_PYLONG_TO_INTEGRAL(&(tv[1].tv_sec), modification_py, &overflow))
1276     {
1277         if (overflow)
1278             PyErr_SetString(PyExc_ValueError, "unable to convert modification time seconds to timeval");
1279         return 0;
1280     }
1281     if (!INTEGRAL_ASSIGNMENT_FITS(&(tv[1].tv_usec), modification_us))
1282     {
1283         PyErr_SetString(PyExc_ValueError, "unable to convert modification time nanoseconds to timeval");
1284         return 0;
1285     }
1286     return 1;
1287 }
1288
1289 #endif /* defined(HAVE_UTIMES) || defined(HAVE_LUTIMES) */
1290
1291
1292 #ifdef HAVE_UTIMES
1293 static PyObject *bup_utimes(PyObject *self, PyObject *args)
1294 {
1295     char *path;
1296     struct timeval tv[2];
1297     if (!bup_parse_xutimes_args(&path, tv, args))
1298         return NULL;
1299     int rc = utimes(path, tv);
1300     if (rc != 0)
1301         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1302     return Py_BuildValue("O", Py_None);
1303 }
1304 #endif /* def HAVE_UTIMES */
1305
1306
1307 #ifdef HAVE_LUTIMES
1308 static PyObject *bup_lutimes(PyObject *self, PyObject *args)
1309 {
1310     char *path;
1311     struct timeval tv[2];
1312     if (!bup_parse_xutimes_args(&path, tv, args))
1313         return NULL;
1314     int rc = lutimes(path, tv);
1315     if (rc != 0)
1316         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
1317
1318     return Py_BuildValue("O", Py_None);
1319 }
1320 #endif /* def HAVE_LUTIMES */
1321
1322
1323 #ifdef HAVE_STAT_ST_ATIM
1324 # define BUP_STAT_ATIME_NS(st) (st)->st_atim.tv_nsec
1325 # define BUP_STAT_MTIME_NS(st) (st)->st_mtim.tv_nsec
1326 # define BUP_STAT_CTIME_NS(st) (st)->st_ctim.tv_nsec
1327 #elif defined HAVE_STAT_ST_ATIMENSEC
1328 # define BUP_STAT_ATIME_NS(st) (st)->st_atimespec.tv_nsec
1329 # define BUP_STAT_MTIME_NS(st) (st)->st_mtimespec.tv_nsec
1330 # define BUP_STAT_CTIME_NS(st) (st)->st_ctimespec.tv_nsec
1331 #else
1332 # define BUP_STAT_ATIME_NS(st) 0
1333 # define BUP_STAT_MTIME_NS(st) 0
1334 # define BUP_STAT_CTIME_NS(st) 0
1335 #endif
1336
1337
1338 #pragma clang diagnostic push
1339 #pragma clang diagnostic ignored "-Wtautological-compare" // For INTEGER_TO_PY().
1340
1341 static PyObject *stat_struct_to_py(const struct stat *st,
1342                                    const char *filename,
1343                                    int fd)
1344 {
1345     // We can check the known (via POSIX) signed and unsigned types at
1346     // compile time, but not (easily) the unspecified types, so handle
1347     // those via INTEGER_TO_PY().  Assumes ns values will fit in a
1348     // long.
1349     return Py_BuildValue("OKOOOOOL(Ol)(Ol)(Ol)",
1350                          INTEGER_TO_PY(st->st_mode),
1351                          (unsigned PY_LONG_LONG) st->st_ino,
1352                          INTEGER_TO_PY(st->st_dev),
1353                          INTEGER_TO_PY(st->st_nlink),
1354                          INTEGER_TO_PY(st->st_uid),
1355                          INTEGER_TO_PY(st->st_gid),
1356                          INTEGER_TO_PY(st->st_rdev),
1357                          (PY_LONG_LONG) st->st_size,
1358                          INTEGER_TO_PY(st->st_atime),
1359                          (long) BUP_STAT_ATIME_NS(st),
1360                          INTEGER_TO_PY(st->st_mtime),
1361                          (long) BUP_STAT_MTIME_NS(st),
1362                          INTEGER_TO_PY(st->st_ctime),
1363                          (long) BUP_STAT_CTIME_NS(st));
1364 }
1365
1366 #pragma clang diagnostic pop  // ignored "-Wtautological-compare"
1367
1368 static PyObject *bup_stat(PyObject *self, PyObject *args)
1369 {
1370     int rc;
1371     char *filename;
1372
1373     if (!PyArg_ParseTuple(args, "s", &filename))
1374         return NULL;
1375
1376     struct stat st;
1377     rc = stat(filename, &st);
1378     if (rc != 0)
1379         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
1380     return stat_struct_to_py(&st, filename, 0);
1381 }
1382
1383
1384 static PyObject *bup_lstat(PyObject *self, PyObject *args)
1385 {
1386     int rc;
1387     char *filename;
1388
1389     if (!PyArg_ParseTuple(args, "s", &filename))
1390         return NULL;
1391
1392     struct stat st;
1393     rc = lstat(filename, &st);
1394     if (rc != 0)
1395         return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
1396     return stat_struct_to_py(&st, filename, 0);
1397 }
1398
1399
1400 static PyObject *bup_fstat(PyObject *self, PyObject *args)
1401 {
1402     int rc, fd;
1403
1404     if (!PyArg_ParseTuple(args, "i", &fd))
1405         return NULL;
1406
1407     struct stat st;
1408     rc = fstat(fd, &st);
1409     if (rc != 0)
1410         return PyErr_SetFromErrno(PyExc_OSError);
1411     return stat_struct_to_py(&st, NULL, fd);
1412 }
1413
1414
1415 #ifdef HAVE_TM_TM_GMTOFF
1416 static PyObject *bup_localtime(PyObject *self, PyObject *args)
1417 {
1418     long long lltime;
1419     time_t ttime;
1420     if (!PyArg_ParseTuple(args, "L", &lltime))
1421         return NULL;
1422     if (!INTEGRAL_ASSIGNMENT_FITS(&ttime, lltime))
1423         return PyErr_Format(PyExc_OverflowError, "time value too large");
1424
1425     struct tm tm;
1426     tzset();
1427     if(localtime_r(&ttime, &tm) == NULL)
1428         return PyErr_SetFromErrno(PyExc_OSError);
1429
1430     // Match the Python struct_time values.
1431     return Py_BuildValue("[i,i,i,i,i,i,i,i,i,i,s]",
1432                          1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
1433                          tm.tm_hour, tm.tm_min, tm.tm_sec,
1434                          tm.tm_wday, tm.tm_yday + 1,
1435                          tm.tm_isdst, tm.tm_gmtoff, tm.tm_zone);
1436 }
1437 #endif /* def HAVE_TM_TM_GMTOFF */
1438
1439
1440 #ifdef BUP_MINCORE_BUF_TYPE
1441 static PyObject *bup_mincore(PyObject *self, PyObject *args)
1442 {
1443     const char *src;
1444     Py_ssize_t src_ssize;
1445     Py_buffer dest;
1446     PyObject *py_src_n, *py_src_off, *py_dest_off;
1447     if (!PyArg_ParseTuple(args, "s#OOw*O",
1448                           &src, &src_ssize, &py_src_n, &py_src_off,
1449                           &dest, &py_dest_off))
1450         return NULL;
1451
1452     unsigned long long src_size, src_n, src_off, dest_size, dest_off;
1453     if (!(bup_ullong_from_py(&src_n, py_src_n, "src_n")
1454           && bup_ullong_from_py(&src_off, py_src_off, "src_off")
1455           && bup_ullong_from_py(&dest_off, py_dest_off, "dest_off")))
1456         return NULL;
1457
1458     if (!INTEGRAL_ASSIGNMENT_FITS(&src_size, src_ssize))
1459         return PyErr_Format(PyExc_OverflowError, "invalid src size");
1460     unsigned long long src_region_end;
1461
1462     if (!uadd(&src_region_end, src_off, src_n))
1463         return PyErr_Format(PyExc_OverflowError, "(src_off + src_n) too large");
1464     if (src_region_end > src_size)
1465         return PyErr_Format(PyExc_OverflowError, "region runs off end of src");
1466
1467     if (!INTEGRAL_ASSIGNMENT_FITS(&dest_size, dest.len))
1468         return PyErr_Format(PyExc_OverflowError, "invalid dest size");
1469     if (dest_off > dest_size)
1470         return PyErr_Format(PyExc_OverflowError, "region runs off end of dest");
1471
1472     size_t length;
1473     if (!INTEGRAL_ASSIGNMENT_FITS(&length, src_n))
1474         return PyErr_Format(PyExc_OverflowError, "src_n overflows size_t");
1475     int rc = mincore((void *)(src + src_off), src_n,
1476                      (BUP_MINCORE_BUF_TYPE *) (dest.buf + dest_off));
1477     if (rc != 0)
1478         return PyErr_SetFromErrno(PyExc_OSError);
1479     return Py_BuildValue("O", Py_None);
1480 }
1481 #endif /* def BUP_MINCORE_BUF_TYPE */
1482
1483
1484 static PyMethodDef helper_methods[] = {
1485     { "write_sparsely", bup_write_sparsely, METH_VARARGS,
1486       "Write buf excepting zeros at the end. Return trailing zero count." },
1487     { "selftest", selftest, METH_VARARGS,
1488         "Check that the rolling checksum rolls correctly (for unit tests)." },
1489     { "blobbits", blobbits, METH_VARARGS,
1490         "Return the number of bits in the rolling checksum." },
1491     { "splitbuf", splitbuf, METH_VARARGS,
1492         "Split a list of strings based on a rolling checksum." },
1493     { "bitmatch", bitmatch, METH_VARARGS,
1494         "Count the number of matching prefix bits between two strings." },
1495     { "firstword", firstword, METH_VARARGS,
1496         "Return an int corresponding to the first 32 bits of buf." },
1497     { "bloom_contains", bloom_contains, METH_VARARGS,
1498         "Check if a bloom filter of 2^nbits bytes contains an object" },
1499     { "bloom_add", bloom_add, METH_VARARGS,
1500         "Add an object to a bloom filter of 2^nbits bytes" },
1501     { "extract_bits", extract_bits, METH_VARARGS,
1502         "Take the first 'nbits' bits from 'buf' and return them as an int." },
1503     { "merge_into", merge_into, METH_VARARGS,
1504         "Merges a bunch of idx and midx files into a single midx." },
1505     { "write_idx", write_idx, METH_VARARGS,
1506         "Write a PackIdxV2 file from an idx list of lists of tuples" },
1507     { "write_random", write_random, METH_VARARGS,
1508         "Write random bytes to the given file descriptor" },
1509     { "random_sha", random_sha, METH_VARARGS,
1510         "Return a random 20-byte string" },
1511     { "open_noatime", open_noatime, METH_VARARGS,
1512         "open() the given filename for read with O_NOATIME if possible" },
1513     { "fadvise_done", fadvise_done, METH_VARARGS,
1514         "Inform the kernel that we're finished with earlier parts of a file" },
1515 #ifdef BUP_HAVE_FILE_ATTRS
1516     { "get_linux_file_attr", bup_get_linux_file_attr, METH_VARARGS,
1517       "Return the Linux attributes for the given file." },
1518 #endif
1519 #ifdef BUP_HAVE_FILE_ATTRS
1520     { "set_linux_file_attr", bup_set_linux_file_attr, METH_VARARGS,
1521       "Set the Linux attributes for the given file." },
1522 #endif
1523 #ifdef HAVE_UTIMENSAT
1524     { "bup_utimensat", bup_utimensat, METH_VARARGS,
1525       "Change path timestamps with nanosecond precision (POSIX)." },
1526 #endif
1527 #ifdef HAVE_UTIMES
1528     { "bup_utimes", bup_utimes, METH_VARARGS,
1529       "Change path timestamps with microsecond precision." },
1530 #endif
1531 #ifdef HAVE_LUTIMES
1532     { "bup_lutimes", bup_lutimes, METH_VARARGS,
1533       "Change path timestamps with microsecond precision;"
1534       " don't follow symlinks." },
1535 #endif
1536     { "stat", bup_stat, METH_VARARGS,
1537       "Extended version of stat." },
1538     { "lstat", bup_lstat, METH_VARARGS,
1539       "Extended version of lstat." },
1540     { "fstat", bup_fstat, METH_VARARGS,
1541       "Extended version of fstat." },
1542 #ifdef HAVE_TM_TM_GMTOFF
1543     { "localtime", bup_localtime, METH_VARARGS,
1544       "Return struct_time elements plus the timezone offset and name." },
1545 #endif
1546 #ifdef BUP_MINCORE_BUF_TYPE
1547     { "mincore", bup_mincore, METH_VARARGS,
1548       "For mincore(src, src_n, src_off, dest, dest_off)"
1549       " call the system mincore(src + src_off, src_n, &dest[dest_off])." },
1550 #endif
1551     { NULL, NULL, 0, NULL },  // sentinel
1552 };
1553
1554
1555 PyMODINIT_FUNC init_helpers(void)
1556 {
1557     // FIXME: migrate these tests to configure.  Check against the
1558     // type we're going to use when passing to python.  Other stat
1559     // types are tested at runtime.
1560     assert(sizeof(ino_t) <= sizeof(unsigned PY_LONG_LONG));
1561     assert(sizeof(off_t) <= sizeof(PY_LONG_LONG));
1562     assert(sizeof(blksize_t) <= sizeof(PY_LONG_LONG));
1563     assert(sizeof(blkcnt_t) <= sizeof(PY_LONG_LONG));
1564     // Just be sure (relevant when passing timestamps back to Python above).
1565     assert(sizeof(PY_LONG_LONG) <= sizeof(long long));
1566     assert(sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long long));
1567
1568     // Originally required by append_sparse_region()
1569     {
1570         off_t probe;
1571         if (!INTEGRAL_ASSIGNMENT_FITS(&probe, INT_MAX))
1572         {
1573             fprintf(stderr, "off_t can't hold INT_MAX; please report.\n");
1574             exit(1);
1575         }
1576     }
1577
1578     char *e;
1579     PyObject *m = Py_InitModule("_helpers", helper_methods);
1580     if (m == NULL)
1581         return;
1582
1583 #pragma clang diagnostic push
1584 #pragma clang diagnostic ignored "-Wtautological-compare" // For INTEGER_TO_PY().
1585     {
1586         PyObject *value;
1587         value = INTEGER_TO_PY(INT_MAX);
1588         PyObject_SetAttrString(m, "INT_MAX", value);
1589         Py_DECREF(value);
1590         value = INTEGER_TO_PY(UINT_MAX);
1591         PyObject_SetAttrString(m, "UINT_MAX", value);
1592         Py_DECREF(value);
1593     }
1594 #ifdef HAVE_UTIMENSAT
1595     {
1596         PyObject *value;
1597         value = INTEGER_TO_PY(AT_FDCWD);
1598         PyObject_SetAttrString(m, "AT_FDCWD", value);
1599         Py_DECREF(value);
1600         value = INTEGER_TO_PY(AT_SYMLINK_NOFOLLOW);
1601         PyObject_SetAttrString(m, "AT_SYMLINK_NOFOLLOW", value);
1602         Py_DECREF(value);
1603         value = INTEGER_TO_PY(UTIME_NOW);
1604         PyObject_SetAttrString(m, "UTIME_NOW", value);
1605         Py_DECREF(value);
1606     }
1607 #endif
1608 #ifdef BUP_HAVE_MINCORE_INCORE
1609     {
1610         PyObject *value;
1611         value = INTEGER_TO_PY(MINCORE_INCORE);
1612         PyObject_SetAttrString(m, "MINCORE_INCORE", value);
1613         Py_DECREF(value);
1614     }
1615 #endif
1616 #pragma clang diagnostic pop  // ignored "-Wtautological-compare"
1617
1618     e = getenv("BUP_FORCE_TTY");
1619     istty2 = isatty(2) || (atoi(e ? e : "0") & 2);
1620     unpythonize_argv();
1621 }