10f66f451Sopenharmony_ci/* cmp.c - Compare two files.
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2012 Timothy Elliott <tle@holymonkey.com>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/cmp.html
60f66f451Sopenharmony_ci
70f66f451Sopenharmony_ciUSE_CMP(NEWTOY(cmp, "<1>2ls(silent)(quiet)[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
80f66f451Sopenharmony_ci
90f66f451Sopenharmony_ciconfig CMP
100f66f451Sopenharmony_ci  bool "cmp"
110f66f451Sopenharmony_ci  default y
120f66f451Sopenharmony_ci  help
130f66f451Sopenharmony_ci    usage: cmp [-l] [-s] FILE1 [FILE2 [SKIP1 [SKIP2]]]
140f66f451Sopenharmony_ci
150f66f451Sopenharmony_ci    Compare the contents of two files. (Or stdin and file if only one given.)
160f66f451Sopenharmony_ci
170f66f451Sopenharmony_ci    -l	Show all differing bytes
180f66f451Sopenharmony_ci    -s	Silent
190f66f451Sopenharmony_ci*/
200f66f451Sopenharmony_ci
210f66f451Sopenharmony_ci#define FOR_cmp
220f66f451Sopenharmony_ci#include "toys.h"
230f66f451Sopenharmony_ci
240f66f451Sopenharmony_ciGLOBALS(
250f66f451Sopenharmony_ci  int fd;
260f66f451Sopenharmony_ci  char *name;
270f66f451Sopenharmony_ci)
280f66f451Sopenharmony_ci
290f66f451Sopenharmony_cistatic void do_cmp(int fd, char *name)
300f66f451Sopenharmony_ci{
310f66f451Sopenharmony_ci  int i, len1, len2, min_len, size = sizeof(toybuf)/2;
320f66f451Sopenharmony_ci  long byte_no = 1, line_no = 1;
330f66f451Sopenharmony_ci  char *buf2 = toybuf+size;
340f66f451Sopenharmony_ci
350f66f451Sopenharmony_ci  // First time through, cache the data and return.
360f66f451Sopenharmony_ci  if (!TT.fd) {
370f66f451Sopenharmony_ci    TT.name = name;
380f66f451Sopenharmony_ci    // On return the old filehandle is closed, and this assures that even
390f66f451Sopenharmony_ci    // if we were called with stdin closed, the new filehandle != 0.
400f66f451Sopenharmony_ci    TT.fd = dup(fd);
410f66f451Sopenharmony_ci    return;
420f66f451Sopenharmony_ci  }
430f66f451Sopenharmony_ci
440f66f451Sopenharmony_ci  toys.exitval = 0;
450f66f451Sopenharmony_ci
460f66f451Sopenharmony_ci  for (;;) {
470f66f451Sopenharmony_ci    len1 = readall(TT.fd, toybuf, size);
480f66f451Sopenharmony_ci    len2 = readall(fd, buf2, size);
490f66f451Sopenharmony_ci
500f66f451Sopenharmony_ci    min_len = len1 < len2 ? len1 : len2;
510f66f451Sopenharmony_ci    for (i=0; i<min_len; i++) {
520f66f451Sopenharmony_ci      if (toybuf[i] != buf2[i]) {
530f66f451Sopenharmony_ci        toys.exitval = 1;
540f66f451Sopenharmony_ci        if (toys.optflags & FLAG_l)
550f66f451Sopenharmony_ci          printf("%ld %o %o\n", byte_no, toybuf[i], buf2[i]);
560f66f451Sopenharmony_ci        else {
570f66f451Sopenharmony_ci          if (!(toys.optflags & FLAG_s))
580f66f451Sopenharmony_ci            printf("%s %s differ: char %ld, line %ld\n",
590f66f451Sopenharmony_ci              TT.name, name, byte_no, line_no);
600f66f451Sopenharmony_ci          goto out;
610f66f451Sopenharmony_ci        }
620f66f451Sopenharmony_ci      }
630f66f451Sopenharmony_ci      byte_no++;
640f66f451Sopenharmony_ci      if (toybuf[i] == '\n') line_no++;
650f66f451Sopenharmony_ci    }
660f66f451Sopenharmony_ci    if (len1 != len2) {
670f66f451Sopenharmony_ci      if (!(toys.optflags & FLAG_s))
680f66f451Sopenharmony_ci        fprintf(stderr, "cmp: EOF on %s\n", len1 < len2 ? TT.name : name);
690f66f451Sopenharmony_ci      toys.exitval = 1;
700f66f451Sopenharmony_ci      break;
710f66f451Sopenharmony_ci    }
720f66f451Sopenharmony_ci    if (len1 < 1) break;
730f66f451Sopenharmony_ci  }
740f66f451Sopenharmony_ciout:
750f66f451Sopenharmony_ci  if (CFG_TOYBOX_FREE) close(TT.fd);
760f66f451Sopenharmony_ci}
770f66f451Sopenharmony_ci
780f66f451Sopenharmony_civoid cmp_main(void)
790f66f451Sopenharmony_ci{
800f66f451Sopenharmony_ci  toys.exitval = 2;
810f66f451Sopenharmony_ci  loopfiles_rw(toys.optargs, O_CLOEXEC|(WARN_ONLY*!(toys.optflags&FLAG_s)), 0,
820f66f451Sopenharmony_ci    do_cmp);
830f66f451Sopenharmony_ci  if (toys.optc == 1) do_cmp(0, "-");
840f66f451Sopenharmony_ci}
85