/usr.bin/from/from.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 169 lines · 128 code · 11 blank · 30 comment · 38 complexity · a36ee106175ddc4c38854852371f515d MD5 · raw file

  1. /*
  2. * Copyright (c) 1980, 1988, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 4. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. #ifndef lint
  30. static const char copyright[] =
  31. "@(#) Copyright (c) 1980, 1988, 1993\n\
  32. The Regents of the University of California. All rights reserved.\n";
  33. #endif /* not lint */
  34. #ifndef lint
  35. #if 0
  36. static char sccsid[] = "@(#)from.c 8.1 (Berkeley) 6/6/93";
  37. #endif
  38. #endif /* not lint */
  39. #include <sys/cdefs.h>
  40. __FBSDID("$FreeBSD$");
  41. #include <sys/types.h>
  42. #include <ctype.h>
  43. #include <err.h>
  44. #include <pwd.h>
  45. #include <stdio.h>
  46. #include <stdlib.h>
  47. #include <paths.h>
  48. #include <string.h>
  49. #include <unistd.h>
  50. int match(const char *, const char *);
  51. static void usage(void);
  52. int
  53. main(int argc, char **argv)
  54. {
  55. FILE *mbox;
  56. struct passwd *pwd;
  57. int ch, count, newline;
  58. const char *file;
  59. char *sender, *p;
  60. #if MAXPATHLEN > BUFSIZ
  61. char buf[MAXPATHLEN];
  62. #else
  63. char buf[BUFSIZ];
  64. #endif
  65. file = sender = NULL;
  66. count = -1;
  67. while ((ch = getopt(argc, argv, "cf:s:")) != -1)
  68. switch (ch) {
  69. case 'c':
  70. count = 0;
  71. break;
  72. case 'f':
  73. file = optarg;
  74. break;
  75. case 's':
  76. sender = optarg;
  77. for (p = sender; *p; ++p)
  78. if (isupper(*p))
  79. *p = tolower(*p);
  80. break;
  81. case '?':
  82. default:
  83. usage();
  84. }
  85. argc -= optind;
  86. argv += optind;
  87. if (file == NULL) {
  88. if (argc) {
  89. (void)snprintf(buf, sizeof(buf), "%s/%s", _PATH_MAILDIR, *argv);
  90. file = buf;
  91. } else {
  92. if (!(file = getenv("MAIL"))) {
  93. if (!(pwd = getpwuid(getuid())))
  94. errx(1, "no password file entry for you");
  95. file = pwd->pw_name;
  96. (void)snprintf(buf, sizeof(buf),
  97. "%s/%s", _PATH_MAILDIR, file);
  98. file = buf;
  99. }
  100. }
  101. }
  102. /* read from stdin */
  103. if (strcmp(file, "-") == 0) {
  104. mbox = stdin;
  105. }
  106. else if ((mbox = fopen(file, "r")) == NULL) {
  107. errx(1, "can't read %s", file);
  108. }
  109. for (newline = 1; fgets(buf, sizeof(buf), mbox);) {
  110. if (*buf == '\n') {
  111. newline = 1;
  112. continue;
  113. }
  114. if (newline && !strncmp(buf, "From ", 5) &&
  115. (!sender || match(buf + 5, sender))) {
  116. if (count != -1)
  117. count++;
  118. else
  119. printf("%s", buf);
  120. }
  121. newline = 0;
  122. }
  123. if (count != -1)
  124. printf("There %s %d message%s in your incoming mailbox.\n",
  125. count == 1 ? "is" : "are", count, count == 1 ? "" : "s");
  126. fclose(mbox);
  127. exit(0);
  128. }
  129. static void
  130. usage(void)
  131. {
  132. fprintf(stderr, "usage: from [-c] [-f file] [-s sender] [user]\n");
  133. exit(1);
  134. }
  135. int
  136. match(const char *line, const char *sender)
  137. {
  138. char ch, pch, first;
  139. const char *p, *t;
  140. for (first = *sender++;;) {
  141. if (isspace(ch = *line))
  142. return(0);
  143. ++line;
  144. if (isupper(ch))
  145. ch = tolower(ch);
  146. if (ch != first)
  147. continue;
  148. for (p = sender, t = line;;) {
  149. if (!(pch = *p++))
  150. return(1);
  151. if (isupper(ch = *t++))
  152. ch = tolower(ch);
  153. if (ch != pch)
  154. break;
  155. }
  156. }
  157. /* NOTREACHED */
  158. }