Thread: the MAIL command in UNIX and Pipes

  1. #1
    char main() RoshanX's Avatar
    Join Date
    Mar 2003
    Posts
    68

    the MAIL command in UNIX and Pipes

    hi all,
    I am wirting a program which will sent a certain recipent a email ( the email address is taken from the command line). The email contains the current processes that are running in the machine. The subject line will have something like "there are X no of users running X number of processes". It should do this with pipes. (popen()). The program is working. But I am having trouble with the SUBJECT line. The reciving mail won't have a subject. ( the subject will be NONE.) The source code is as follows. The section where the mail is sent is in red.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #define BUFFLEN 40                                 /* length of the array that will hold all the processes */
    #define SIZE 100                                   /* the initial size of the array to hold all the processes */
    #define COMMAND "ps -e -o uid -o pid -o fname"     /* get all the process names */
    char** list;                                       /*the column vector of the 2D array to hold filenames */
    void die(char*);                                   /* die with msg */
    
    int main()
    {
      FILE* pipe_id;
      int i=0,j;                        /* conter variables */
      char buff[BUFFLEN];
      int user_count;
      int proc_count;
      char subject[80];                 /* the subject line */
      char recpt[50];                   /* the recipient of the email*/
      char mail_command[80];
      printf("The mail recipient      : ");
      fscanf(stdin,"%s",recpt);
    
      /* allocate the column vector of the 2D character array */
      if((list=(char**)malloc(sizeof(char*)*SIZE))==NULL)
        die("Memory allocation error.\n");
    
      /* open pipe connection  */
      if ((pipe_id=popen(COMMAND,"r"))==NULL)
        die("Pipe open failiure. Abort");
    
      /*read each line from the pipe and write it to the array */
      while(fgets(buff, BUFFLEN, pipe_id)!= NULL)
        {
          if ((i+1)>SIZE)         /* reallocation required */
            list=(char**)realloc((char**)list,sizeof(char*)*(i+100));         /* reallocate the column vector with 100 more elements */
    
          if ((list[i]=(char*)malloc(sizeof(char)*BUFFLEN))==NULL)              /* allocate rows of the 2D char array */
            die("Memory allocation erro. \n");
    
          strcpy(list[i],buff);                                            /* copy the line read from the pipe to the array element */
          i++;
        }
      //  get_counts(list,&user_count,&proc_count);
      pclose(pipe_id);
    
    sprintf(subject,"\"There are %d no of users using %d processers\"",10,100);
      sprintf(mail_command,"mail -s %s  %s ",subject,recpt);
      printf("%s\n",mail_command);
      pipe_id=popen(mail_command,"w");
      for(j=0;j<i;j++)
        {
          fprintf(pipe_id,"%s",list[j]);
        }
      fprintf(pipe_id,"%c",EOF);
    
      pclose(pipe_id);
    }
    how to solve this ?

  2. #2
    root
    Join Date
    Sep 2003
    Posts
    232
    mail doesn't allow you to include a subject, you should avoid it wherever possible in favor of mailx (or Mail).
    The information given in this message is known to work on FreeBSD 4.8 STABLE.
    *The above statement is false if I was too lazy to test it.*
    Please take note that I am not a technical writer, nor do I care to become one.
    If someone finds a mistake, gleaming error or typo, do me a favor...bite me.
    Don't assume that I'm ever entirely serious or entirely joking.

  3. #3
    char main() RoshanX's Avatar
    Join Date
    Mar 2003
    Posts
    68
    Thanks for the relply. Yer..I solved the problem by replacing "mail" with "Mail". It works now.

    But , "mail" would allow you to specify the subject if you are doing this diectly in the command line.

  4. #4
    root
    Join Date
    Sep 2003
    Posts
    232
    >But , "mail" would allow you to specify the subject if you are doing this diectly in the command line.
    Allow me to speculate wildly then. On the command line 'mail' is a link to Mail or mailx, but for some reason, in your program 'mail' calls the real mail. Of course, I'm not familiar enough with C to speculate on the 'for some reason' part.
    The information given in this message is known to work on FreeBSD 4.8 STABLE.
    *The above statement is false if I was too lazy to test it.*
    Please take note that I am not a technical writer, nor do I care to become one.
    If someone finds a mistake, gleaming error or typo, do me a favor...bite me.
    Don't assume that I'm ever entirely serious or entirely joking.

  5. #5
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>sprintf(mail_command,"mail -s %s %s ",subject,recpt);
    A classic example of a security hazzard. As twm implied, who knows what "mail" actually is. You should be using the full path to the executable: /usr/bin/mail (or whatever)
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  6. #6
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    It would be just as easy to write a small mail client that talks SMTP to a mail server using sockets.

    Check out sockets and the SMTP RFC.

  7. #7
    root
    Join Date
    Sep 2003
    Posts
    232
    >It would be just as easy to write a small mail client that talks SMTP to a mail server using sockets.
    So you're suggesting he write a mail client instead of simply piping to an existing mail client, thus tripling(probably way more) his work load and potential bug count? That sounds like something Windows would do, but we Unix users are above that kind of thing.
    The information given in this message is known to work on FreeBSD 4.8 STABLE.
    *The above statement is false if I was too lazy to test it.*
    Please take note that I am not a technical writer, nor do I care to become one.
    If someone finds a mistake, gleaming error or typo, do me a favor...bite me.
    Don't assume that I'm ever entirely serious or entirely joking.

  8. #8
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    Its just as many lines of code just to connect to an SMTP server and send:

    helo
    mail from: [email protected]
    rcpt to: [email protected]
    data
    subject: my subject
    blah blah blah
    .
    quit

    close connection.

    The alternative is to open a pipe, probably invoke a shell, call another program, and spark another process.

    please don't talk to me about windows.

  9. #9
    root
    Join Date
    Sep 2003
    Posts
    232
    >Its just as many lines of code just to connect to an SMTP server and send:
    Really?
    It would be just as easy to write a small mail client that talks SMTP to a mail server using sockets.
    The way I read this statement is that you would actually write the socket code to connect to a mail server. Setting up a socket, opening and closing the connection and any error checking code alone is longer than opening a pipe and using it. Then of course you need to actually use the socket, this adds even more code. But then you have to consider writing the code to speak SMTP and glue all of this to your program. But let's not talk so much about length of code as complexity and maintenance. By writing something that already exists, you increase the complexity of your program, which is that much more for someone maintaining it to understand. On top of understanding the code, what if it needs to be changed in any signifigant way? Using pipes you could likely just change the program used in a single instance. Using your method, a large portion of the code would have to be cut out, replaced, debugged and tested.

    >The alternative is to open a pipe, probably invoke a shell, call another program, and spark another process.
    All of which are inexpensive enough to make that solution a pretty big win. If it turns out to be too slow after stress testing in a working environment, you can say you tried and then do something else more along your lines. But I would wager the chances of that being needed are slim.

    Once again I ask: Why bother writing a mail client when there are already several that come with Unix/Linux by default and are highly scriptable?
    The information given in this message is known to work on FreeBSD 4.8 STABLE.
    *The above statement is false if I was too lazy to test it.*
    Please take note that I am not a technical writer, nor do I care to become one.
    If someone finds a mistake, gleaming error or typo, do me a favor...bite me.
    Don't assume that I'm ever entirely serious or entirely joking.

  10. #10
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    Write it in bash.

  11. #11
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    ps -e -o uid -o pid -o fname | mail [email protected] -s "ps command output"

  12. #12
    root
    Join Date
    Sep 2003
    Posts
    232
    So we're not using C anymore? Well, then your way is probably as long as the equivalent C program using pipes, just as you said.
    The information given in this message is known to work on FreeBSD 4.8 STABLE.
    *The above statement is false if I was too lazy to test it.*
    Please take note that I am not a technical writer, nor do I care to become one.
    If someone finds a mistake, gleaming error or typo, do me a favor...bite me.
    Don't assume that I'm ever entirely serious or entirely joking.

  13. #13
    char main() RoshanX's Avatar
    Join Date
    Mar 2003
    Posts
    68
    What I really want to know is this, Forget about all the security risks and other stuff.........

    $ mail -s " some kind of subject " [email protected]

    This will send a mail to the recipient with the SUBJECT line.

    But if I do the samething with C ( using pipes or just execl() or system()) , it will send the mail, but without the SUBJECT line. WHY IS THAT ?

  14. #14
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    Does it work the same on the command line?

    Try putting username before the subject if you're using linux.

  15. #15
    root
    Join Date
    Sep 2003
    Posts
    232
    Just a quick note rotis in case you didn't know this:
    Code:
    ps -e -o uid -o pid -o fname | mail [email protected] -s "ps command output"
    The -o option allows a comma separated list. So you should be able to speed yourself up a hair by doing this:
    Code:
    ps -eo uid,pid,fname | mail [email protected] -s "ps command output"
    Scary, huh?

    >WHY IS THAT ?
    I have no clue. Like I said, I'm not familiar enough with C to speculate. Try adding the -v switch to get some extra info on delivery, that may be enlightening.
    The information given in this message is known to work on FreeBSD 4.8 STABLE.
    *The above statement is false if I was too lazy to test it.*
    Please take note that I am not a technical writer, nor do I care to become one.
    If someone finds a mistake, gleaming error or typo, do me a favor...bite me.
    Don't assume that I'm ever entirely serious or entirely joking.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Classical Unix IPC mechanisms
    By cola23 in forum C Programming
    Replies: 1
    Last Post: 02-06-2009, 04:54 AM
  2. Unix pipe simulation
    By TaviO! in forum C Programming
    Replies: 4
    Last Post: 03-19-2008, 12:47 AM