file_io.c
上传用户:knt0001
上传日期:2022-01-28
资源大小:264k
文件大小:5k
源码类别:

Email客户端

开发平台:

C/C++

  1. /**
  2.     eMail is a command line SMTP client.
  3.     Copyright (C) 2001 - 2008 email by Dean Jones
  4.     Software supplied and written by http://www.cleancode.org
  5.     This file is part of eMail.
  6.     eMail is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.     eMail is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.     You should have received a copy of the GNU General Public License
  15.     along with eMail; if not, write to the Free Software
  16.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. **/
  18. #if HAVE_CONFIG_H
  19. # include "config.h"
  20. #endif
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <unistd.h>
  25. #include <errno.h>
  26. #include <sys/wait.h>
  27. #include <sys/stat.h>
  28. #include "email.h"
  29. #include "utils.h"
  30. #include "file_io.h"
  31. #include "sig_file.h"
  32. #include "error.h"
  33. /**
  34.  * ReadInput: This function just reads in a file from STDIN which 
  35.  * allows someone to redirect a file into email from the command line.
  36. **/
  37. dstrbuf *
  38. readInput(void)
  39. {
  40. dstrbuf *fpath=NULL;
  41. dstrbuf *tmp=DSB_NEW, *buf=DSB_NEW;
  42. char *sig_file = NULL;
  43. while (!feof(stdin)) {
  44. dsbReadline(tmp, stdin);
  45. chomp(tmp->str);
  46. dsbCat(buf, tmp->str);
  47. dsbCat(buf, "rn");
  48. }
  49. dsbDestroy(tmp);
  50. /* If they specified a signature file, let's append it */
  51. sig_file = getConfValue("SIGNATURE_FILE");
  52. if (sig_file) {
  53. fpath = expandPath(sig_file);
  54. appendSig(buf, fpath->str);
  55. dsbDestroy(fpath);
  56. }
  57. return buf;
  58. }
  59. /**
  60.  * Question: will simply ask the question provided.  This 
  61.  * function will only accept a yes or no (y or n even) answer
  62.  * and loop until it gets that answer.  It will return
  63.  * TRUE for 'yes', FALSE for 'no'
  64. **/
  65. static bool
  66. question(const char *question)
  67. {
  68. bool resp;
  69. char yorn[5] = { 0 };
  70. for (;;) {
  71. printf("%s[y/n]: ", question);
  72. fgets(yorn, sizeof(yorn), stdin);
  73. chomp(yorn);
  74. if ((strcasecmp(yorn, "no") == 0) || (strcasecmp(yorn, "n") == 0)) {
  75. resp = false;
  76. break;
  77. } else if ((strcasecmp(yorn, "yes") == 0) || 
  78. (strcasecmp(yorn, "y") == 0)) {
  79. resp = true;
  80. break;
  81. } else {
  82. printf("Invalid Response!n");
  83. continue;
  84. }
  85. }
  86. return resp;
  87. }
  88. /**
  89.  * Will for and execute the program that is passed to it.
  90.  * will return -1 if an error occurred.
  91. **/
  92. static int
  93. openEditor(const char *editor, const char *filename)
  94. {
  95. int retval, status;
  96. assert(filename != NULL);
  97. retval = fork();
  98. if (retval == 0) {          /* Child process */
  99. if (execlp(editor, editor, filename, NULL) < 0)
  100. exit(-1);
  101. } else if (retval > 0) {      /* Parent process */
  102. while (waitpid(retval, &status, 0) < 0)
  103. ;
  104. } else  { /* Error */
  105. return -1;
  106. }
  107. if (WIFEXITED(status) != 0) {
  108. if (WEXITSTATUS(status) != 0) {
  109. return -1;
  110. }
  111. }
  112. return 0;
  113. }
  114. static dstrbuf *
  115. getFileContents(const char *filename)
  116. {
  117. dstrbuf *tmp=NULL, *buf=NULL;
  118. FILE *in = fopen(filename, "r");
  119. if (!in) {
  120. return NULL;
  121. }
  122. buf = DSB_NEW;
  123. tmp = DSB_NEW;
  124. while (!feof(in)) {
  125. dsbReadline(tmp, in);
  126. dsbCat(buf, tmp->str);
  127. }
  128. dsbDestroy(tmp);
  129. fclose(in);
  130. return buf;
  131. }
  132. /**
  133.  * EditFile: this function basicly opens the editor of choice 
  134.  * with a temp file and lets you create your message and send it.  
  135. **/
  136. dstrbuf *
  137. editEmail(void)
  138. {
  139. int fd=0;
  140. char *editor;
  141. char *sig_file = NULL;
  142. dstrbuf *fpath=NULL;
  143. dstrbuf *buf=NULL;
  144. size_t fsize=0;
  145. char filename[TMPFILE_TEMPLATE_SIZE] = TMPFILE_TEMPLATE;
  146. if (!(editor = getenv("EDITOR"))) {
  147. warning("Environment varaible EDITOR not set: Defaulting to "vi"n");
  148. editor = "vi";
  149. }
  150. /* Use of mkstemp causes an issue on Cygwin/Windows machines because the 
  151.    only way to avoid a race condition there is to hold the file open
  152.    while the editor oepns it as well. It seems Cygwin/Windows won't
  153.    allow the file to be written to while someone else has it open. 
  154.    So, we need to make sure we close it and just reference the file
  155.    that was created by it's name. */
  156. fd = mkstemp(filename);
  157. if (fd < 0) {
  158. fatal("Could not create temp file for editor");
  159. properExit(ERROR);
  160. }
  161. close(fd);
  162. if (openEditor(editor, filename) < 0) {
  163. warning("Error when trying to open editor '%s'", editor);
  164. }
  165. /* if they quit their editor without makeing an email... */
  166. fsize = filesize(filename);
  167. if (fsize <= 0) {
  168. if (question("You have an empty email, send anyway?") == false) {
  169. unlink(filename);
  170. properExit(EASY);
  171. }
  172. }
  173. buf = getFileContents(filename);
  174. unlink(filename);
  175. /* If they specified a signature file, let's append it */
  176. sig_file = getConfValue("SIGNATURE_FILE");
  177. if (sig_file) {
  178. fpath = expandPath(sig_file);
  179. appendSig(buf, fpath->str);
  180. dsbDestroy(fpath);
  181. }
  182. return buf;
  183. }