ttyio.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /* $Source: /u/mark/src/pax/RCS/ttyio.c,v $
  2. *
  3. * $Revision: 1.2 $
  4. *
  5. * ttyio.c - Terminal/Console I/O functions for all archive interfaces
  6. *
  7. * DESCRIPTION
  8. *
  9. * These routines provide a consistent, general purpose interface to
  10. * the user via the users terminal, if it is available to the
  11. * process.
  12. *
  13. * AUTHOR
  14. *
  15. * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  16. *
  17. * Sponsored by The USENIX Association for public distribution.
  18. *
  19. * Copyright (c) 1989 Mark H. Colburn.
  20. * All rights reserved.
  21. *
  22. * Redistribution and use in source and binary forms are permitted
  23. * provided that the above copyright notice is duplicated in all such
  24. * forms and that any documentation, advertising materials, and other
  25. * materials related to such distribution and use acknowledge that the
  26. * software was developed * by Mark H. Colburn and sponsored by The
  27. * USENIX Association.
  28. *
  29. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  30. * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  31. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  32. *
  33. * $Log: ttyio.c,v $
  34. * Revision 1.2 89/02/12 10:06:11 mark
  35. * 1.2 release fixes
  36. *
  37. * Revision 1.1 88/12/23 18:02:39 mark
  38. * Initial revision
  39. *
  40. */
  41. #ifndef lint
  42. static char *ident = "$Id: ttyio.c,v 1.2 89/02/12 10:06:11 mark Exp $";
  43. static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  44. #endif /* ! lint */
  45. /* Headers */
  46. #include "pax.h"
  47. /* open_tty - open the terminal for interactive queries
  48. *
  49. * DESCRIPTION
  50. *
  51. * Assumes that background processes ignore interrupts and that the
  52. * open() or the isatty() will fail for processes which are not
  53. * attached to terminals. Returns a file descriptor or -1 if
  54. * unsuccessful.
  55. *
  56. * RETURNS
  57. *
  58. * Returns a file descriptor which can be used to read and write
  59. * directly to the user's terminal, or -1 on failure.
  60. *
  61. * ERRORS
  62. *
  63. * If SIGINT cannot be ignored, or the open fails, or the newly opened
  64. * terminal device is not a tty, then open_tty will return a -1 to the
  65. * caller.
  66. */
  67. #ifdef __STDC__
  68. int open_tty(void)
  69. #else
  70. int open_tty()
  71. #endif
  72. {
  73. int fd; /* file descriptor for terminal */
  74. SIG_T (*intr)(); /* used to restore interupts if signal fails */
  75. if ((intr = signal(SIGINT, SIG_IGN)) == SIG_IGN) {
  76. return (-1);
  77. }
  78. signal(SIGINT, intr);
  79. if ((fd = open(TTY, O_RDWR)) < 0) {
  80. return (-1);
  81. }
  82. if (isatty(fd)) {
  83. return (fd);
  84. }
  85. close(fd);
  86. return (-1);
  87. }
  88. /* nextask - ask a question and get a response
  89. *
  90. * DESCRIPTION
  91. *
  92. * Give the user a prompt and wait for their response. The prompt,
  93. * located in "msg" is printed, then the user is allowed to type
  94. * a response to the message. The first "limit" characters of the
  95. * user response is stored in "answer".
  96. *
  97. * Nextask ignores spaces and tabs.
  98. *
  99. * PARAMETERS
  100. *
  101. * char *msg - Message to display for user
  102. * char *answer - Pointer to user's response to question
  103. * int limit - Limit of length for user's response
  104. *
  105. * RETURNS
  106. *
  107. * Returns the number of characters in the user response to the
  108. * calling function. If an EOF was encountered, a -1 is returned to
  109. * the calling function. If an error occured which causes the read
  110. * to return with a value of -1, then the function will return a
  111. * non-zero return status to the calling process, and abort
  112. * execution.
  113. */
  114. #ifdef __STDC__
  115. int nextask(char *msg, char *answer, int limit)
  116. #else
  117. int nextask(msg, answer, limit)
  118. char *msg; /* message to display for user */
  119. char *answer; /* pointer to user's response to question */
  120. int limit; /* limit of length for user's response */
  121. #endif
  122. {
  123. int idx; /* index into answer for character input */
  124. int got; /* number of characters read */
  125. char c; /* character read */
  126. if (ttyf < 0) {
  127. fatal("/dev/tty Unavailable");
  128. }
  129. write(ttyf, msg, (uint) strlen(msg));
  130. idx = 0;
  131. while ((got = read(ttyf, &c, 1)) == 1) {
  132. if (c == '\n') {
  133. break;
  134. } else if (c == ' ' || c == '\t') {
  135. continue;
  136. } else if (idx < limit - 1) {
  137. answer[idx++] = c;
  138. }
  139. }
  140. if (got == 0) { /* got an EOF */
  141. return(-1);
  142. }
  143. if (got < 0) {
  144. fatal(strerror());
  145. }
  146. answer[idx] = '\0';
  147. return(0);
  148. }
  149. /* lineget - get a line from a given stream
  150. *
  151. * DESCRIPTION
  152. *
  153. * Get a line of input for the stream named by "stream". The data on
  154. * the stream is put into the buffer "buf".
  155. *
  156. * PARAMETERS
  157. *
  158. * FILE *stream - Stream to get input from
  159. * char *buf - Buffer to put input into
  160. *
  161. * RETURNS
  162. *
  163. * Returns 0 if successful, -1 at EOF.
  164. */
  165. #ifdef __STDC__
  166. int lineget(FILE *stream, char *buf)
  167. #else
  168. int lineget(stream, buf)
  169. FILE *stream; /* stream to get input from */
  170. char *buf; /* buffer to put input into */
  171. #endif
  172. {
  173. int c;
  174. for (;;) {
  175. if ((c = getc(stream)) == EOF) {
  176. return (-1);
  177. }
  178. if (c == '\n') {
  179. break;
  180. }
  181. *buf++ = c;
  182. }
  183. *buf = '\0';
  184. return (0);
  185. }
  186. /* next - Advance to the next archive volume.
  187. *
  188. * DESCRIPTION
  189. *
  190. * Prompts the user to replace the backup medium with a new volume
  191. * when the old one is full. There are some cases, such as when
  192. * archiving to a file on a hard disk, that the message can be a
  193. * little surprising. Assumes that background processes ignore
  194. * interrupts and that the open() or the isatty() will fail for
  195. * processes which are not attached to terminals. Returns a file
  196. * descriptor or -1 if unsuccessful.
  197. *
  198. * PARAMETERS
  199. *
  200. * int mode - mode of archive (READ, WRITE, PASS)
  201. */
  202. #ifdef __STDC__
  203. void next(int mode)
  204. #else
  205. void next(mode)
  206. int mode; /* mode of archive (READ, WRITE, PASS) */
  207. #endif
  208. {
  209. char msg[200]; /* buffer for message display */
  210. char answer[20]; /* buffer for user's answer */
  211. int ret;
  212. close_archive();
  213. sprintf(msg, "%s: Ready for volume %u\n%s: Type \"go\" when ready to proceed (or \"quit\" to abort): \07",
  214. myname, arvolume + 1, myname);
  215. for (;;) {
  216. ret = nextask(msg, answer, sizeof(answer));
  217. if (ret == -1 || strcmp(answer, "quit") == 0) {
  218. fatal("Aborted");
  219. }
  220. if (strcmp(answer, "go") == 0 && open_archive(mode) == 0) {
  221. break;
  222. }
  223. }
  224. warnarch("Continuing", (OFFSET) 0);
  225. }