Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Simple way to email a text file using C in UNIX? 1

Status
Not open for further replies.

willz99ta

IS-IT--Management
Sep 15, 2004
132
US
Thanks for reading my message and for any help you can give.

I am trying to email a text file using C programming in UNIX. What is the easiest way of doing this?

Thanks for any help,
Willz99ta
 
Easiest way is to use a mail program already installed on the system. This isn't very portable, as it will only work on machines that have the program you require. But, this is a cheap and dirty way you might do it.

Code:
system("echo \"message\" | mail -s \"subject\" example@example.com example2@example.com");


[plug=shameless]
[/plug]
 
Hi:

Easy depends on your point of view. Here's a function I wrote some years ago that writes to any valid unix pipe - including the mailx program. It's easy in that the function is already written:

Code:
/*
  * email to user fred using the Unix pipe
  */
#include <stdio.h>

int main(void)
{
static char *slines[] =
    {
     "This is the first line of the mail example",
     "and this is the second line",
     "and of course this is the third"
     };
 char *com_str="mailx -s \"write a message\" fred";

 run_wpipe(slines,   3, com_str);
 exit(0);
 }

/*
 *   This function:
 *   1) creates a pipe.
 *   2) creates another process with fork().
 *   3) couples standard input to the reading end of the pipe
 *      using the dup() call.
 *   4) closes file descriptors.
 *   5) executes the child process.
 *   6) closes the read side of the pipe.
 *   7) opens the write side of the pipe using fdopen().
 *   8) writes the number of input lines.
 *   9) closes the file pointer.
 *
 *   lineptr is an array-of-pointers where each element is a string
 *   to be written to the pipe.
 */
 int run_wpipe(lineptr, nolines, exe_str)
 char *lineptr[]; /*array-of-pointers to strings */
 int  nolines;    /*number of lines to write */
 char *exe_str;   /*pipe command  */
 {
 int i, p[2], pid;
 FILE *ptr, *fdopen();

 if(pipe(p) < 0)
      fatal("pipe call");

 switch(pid=fork())
      {
      case -1:
         fatal("fork call in run_wpipe");
      case 0:
         close(0);    /*close the standard input */
         dup(p[0]);   /*read side of the pipe */
         close(p[0]); /*save the file descriptors */
         close(p[1]);
         execlp("/bin/sh", "sh", "-c", exe_str, NULL);
         fatal("exec call in run_wpipe");
       }
 close(p[0]);  /*close the read side of the parent */
 if((ptr=fdopen(p[1],"w")), ptr ==   NULL)
      fatal("fdopen call in run_wpipe");

 for(i = 0; i<nolines; i++)
      fprintf(ptr,"%s\n", lineptr[i]);
 fclose(ptr);
 /*wait for child process to finish*/
 while(wait((int *)0) != pid)
      ;
 }

int fatal(str)
{
   printf("%s\n");
   exit(1);
}
 
Hi:

Easy depends on your point of view. Here's a function I wrote some years ago that writes to any valid unix pipe - including the mailx program. It's easy in that the function is already written:

Code:
/*
* email to user fred using the Unix pipe
*/
#include <stdio.h>

int main(void)
{
static char *slines[] =
{
"This is the first line of the mail example",
"and this is the second line",
"and of course this is the third"
};
char *com_str="mailx -s \"write a message\" fred";

run_wpipe(slines, 3, com_str);
exit(0);
}

/*
* This function:
* 1) creates a pipe.
* 2) creates another process with fork().
* 3) couples standard input to the reading end of the pipe
* using the dup() call.
* 4) closes file descriptors.
* 5) executes the child process.
* 6) closes the read side of the pipe.
* 7) opens the write side of the pipe using fdopen().
* 8) writes the number of input lines.
* 9) closes the file pointer.
*
* lineptr is an array-of-pointers where each element is a string
* to be written to the pipe.
*/
int run_wpipe(lineptr, nolines, exe_str)
char *lineptr[]; /*array-of-pointers to strings */
int nolines; /*number of lines to write */
char *exe_str; /*pipe command */
{
int i, p[2], pid;
FILE *ptr, *fdopen();

if(pipe(p) < 0)
fatal("pipe call");

switch(pid=fork())
{
case -1:
fatal("fork call in run_wpipe");
case 0:
close(0); /*close the standard input */
dup(p[0]); /*read side of the pipe */
close(p[0]); /*save the file descriptors */
close(p[1]);
execlp("/bin/sh", "sh", "-c", exe_str, NULL);
fatal("exec call in run_wpipe");
}
close(p[0]); /*close the read side of the parent */
if((ptr=fdopen(p[1],"w")), ptr == NULL)
fatal("fdopen call in run_wpipe");

for(i = 0; i<nolines; i++)
fprintf(ptr,"%s\n", lineptr[i]);
fclose(ptr);
/*wait for child process to finish*/
while(wait((int *)0) != pid)
;
}

int fatal(str)
{
printf("%s\n");
exit(1);
}
 
I'd simply code it in the following way.

1. Create tcp socket and assign an sockaddr_in
addr and port members to the address and port
of the user supplied(via getopt() or config file)
information via inet_addr and htons().

2. Create a const char *array[] with the necessary
components for ehlo type handshaking:
Code:
{"mail from:", "rcpt to:", "data:", "\r\n.\r\n"};
Use snprintf and buffer and user supplied data to
populate this framework.

3. Iterate through the array sending and receiving,
checking for system errors(SIGPIPE, EOF), and invalid
responses. When the time comes to send data, open
filename and read to socket till eof, then send your
termination sequence(last member of array).

More flexible and less of a headache than driving a
another binary IMHO.
YMMV.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top