/* This file is based on the IOCCC 1998 winner "schweikh3", alias "samefile". * This is Bisqwit's patch to add mmap() support to it. */ #define _POSIX_SOURCE #include #include #include #include #include #include #include #include static char *A[32767 / sizeof (char *)]; static struct stat S, T; static size_t y; typedef struct f { char *n; struct f *x; dev_t d; ino_t i; } f; typedef struct t { long s, c; f * l; struct t *L, *R; } t; static t * a (void) { t *z = malloc (sizeof *z); if (z) return z; exit (1); } static f * E (void) { f *z = malloc (sizeof *z); if (z) return z; exit (1); } static t * J (t * p, char *n) { if (!p) { p = a (); p->s = S.st_size; p->c = 1; p->L = p->R = 0; p->l = E (); p->l->n = n; p->l->x = 0; p->l->d = S.st_dev; p->l->i = S.st_ino; } else if (S.st_size == p->s) { f *e; for (e = p->l; e; e = e->x) { if (S.st_dev == e->d && S.st_ino == e->i) { return p; } } e = E (); e->x = p->l; e->n = n; e->d = S.st_dev; e->i = S.st_ino; p->l = e; ++p->c; } else if (S.st_size < p->s) { p->L = J (p->L, n); } else { p->R = J (p->R, n); } return p; } static int Q (char *G, char *F) { int d = open (G, O_RDONLY), D = open (F, O_RDONLY); char *m, *M; int k, K, ret; if (d < 0 || fstat (d, &S) || D < 0 || fstat (D, &T) || (y = S.st_size) - T.st_size) { close(d); close(D); return 0; } m = mmap(NULL, y, PROT_READ, MAP_PRIVATE, d, 0); k=0; M = mmap(NULL, y, PROT_READ, MAP_PRIVATE, D, 0); K=0; if(m == NULL || m == (char *)(-1)) { m = malloc(y); read(d, m, y); k=1; } else close(d); if(M == NULL || M == (char *)(-1)) { M = malloc(y); read(D, M, y); K=1; } else close(D); ret = !memcmp (m, M, y); if(k) { free (m); close(d); } else munmap(m, y); if(K) { free (M); close(D); } else munmap(M, y); return ret; } static void C (long z, long N) { long i = N * (N - 1) / 2, j = 1, s; char *q, *e, *p, *w, *l; e = q = calloc ((size_t) i, 1); if (!e) exit (1); p = q + i; for (i = 0; e - p; ++e) { if (!*e && Q (A[i], A[j])) { (void) printf ("%ld\t%s\t%s\t%c\11%d\t%d\n", z, A[i], A[j], S.st_dev - T.st_dev ? 'X' : '=', (int) S.st_nlink, (int) T.st_nlink); if (j - i - 1) { s = N - i - 3; w = e + s + 1; l = q + N * (j - 1) - j * (j - 1) / 2; do { *w = 1; if (w == l) break; w += s; } while (s-- > 0); } } if (++j == N) { j = i++ + 2; } } free (q); } static void P (t * p) { if (p) { P (p->R); if (p->c > 1) { long i = 0; f *l = p->l; for (; i < p->c; ++i) { A[i] = l->n; l = l->x; } C (p->s, p->c); } P (p->L); } } int main (void) { t *r = 0; char *F; for (;;) { if (!(F = malloc (1024))) exit (1); if (!fgets (F, 1024, stdin)) break; *(F + (y = strlen (F)) - 1) = 0; if (!(F = realloc (F, y))) exit (1); if (stat (F, &S) == 0 && S_ISREG (S.st_mode) && S.st_size) r = J (r, F); } if (r) P (r); return 0; }