Thread: popen and fseek

  1. #1
    Registered User mach5's Avatar
    Join Date
    Feb 2003
    Posts
    7

    popen and fseek

    Hello Everyone,

    I am writing a program that does a whois and nslookup on domains listed in a text file. I am having a problem with popen and fseek. Here is the code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    
      FILE *fptr1, *fptr2, *domreadout, *nsreadout;
    
      char filename1[] = "virt.txt";
      char filename2[] = "output.txt";
      char buff[BUFSIZ];
      char whoiscommand[150];
      char nscommand[150];
      char whoispopenout[BUFSIZ];
      char nspopenout[BUFSIZ];
    
      int count = 0;
      int c;
    
      printf("This program reads the file \"virt.txt\" and does a whois\n");
      printf("and nslookup -q=mx on each domain listed in the file.\n");
      printf("(we sleep for 5 seconds between whois and nslookup)\n\n");
      printf("Let's get started...\n\n");
    
      /*opening files to read and write*/
      if ((fptr1 = fopen(filename1, "r")) == NULL)
      {
        printf("cannot open file %s", filename1);
        return 0;
      }
      else if ((fptr2 = fopen(filename2, "w")) == NULL)
      {
        printf("cannot open file %s", filename2);
        return 0;
      }
      else
      {
        /*main loop - fscanf reads each line in virt.txt into buff*/
        while (fscanf(fptr1, "%s", buff) != EOF)
        {
          fprintf(fptr2, "\n%s\n\n", buff); // precede whois with domain
          printf("working on domain: %s\n", buff); // print what's happening
    
          /*read whois command*/
          sprintf(whoiscommand, "whois.exe -h whois.networksolutions.com %s", buff);
            /*read output from whois command*/
            if ((domreadout = popen(whoiscommand, "rb")) == NULL)
            {
              printf("problem running whois with popen\n");
              return 0;
            }
    
          fseek(domreadout, 0, SEEK_END); // move to end of domreadout
          fseek(domreadout, -200, SEEK_CUR); // back up n bytes
          while (ftell(domreadout) && count < 200) //if we've reached n bytes, stop looping
          {
            count++;
            c = getc(domreadout);
            fprintf(fptr2, "%c", c);
          }
    
          /*sleep for 5 seconds between whois and nslookup*/
          sleep(5000);
    
          /*now the nslookup*/
          sprintf(nscommand, "nslookup -q=mx %s", buff);
            if ((nsreadout = popen(nscommand, "r")) == NULL)
            {
              printf("problem running nslookup with popen\n");
              return 0;
            }
            /*reading nslookup output and write it to output.txt*/
            while (!feof(nsreadout))
            {
              if (fgets(nspopenout, BUFSIZ, nsreadout) != NULL)
              {
                fprintf(fptr2, nspopenout);
              }
            }
        }
      }
      /*close popen*/
      pclose(domreadout);
      pclose(nsreadout);
    
      /*close files*/
      fclose(fptr1);
      fclose(fptr2);
    
      return 0;
    }
    The information in virt.txt is:
    google.com
    yahoo.com

    I am having a problem moving around with fseek. It appears that when I try to fseek the information in domreadout, it's null. Do you know what I'm doing wrong? Can you use fseek with popen?

    I am trying to use the last sixteen lines (approximately) of domreadout and thought that I could accomplish this with fseek. Is there a better way?

    Sorry I stuffed all of this code into main, I plan to write separate functions once I get it right.

    Thank you.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    From the man page:
    The mode argument is a pointer to a null-terminated string which must be either `r' for reading or `w' for writing.
    "r" or "w", not "rb" or "wb" or "r+" or...

    Which basicly means that fseek is not going to work right anyway, since it doesn't work right on text files.

    More of the man page gives you your answer:
    Writing to such a stream
    writes to the standard input of the command; the command's
    standard output is the same as that of the process that
    called popen(), unless this is altered by the command
    itself. Conversely, reading from a ``popened'' stream
    reads the command's standard output, and the command's
    standard input is the same as that of the process that
    called popen.
    So in otherwords, no. Since all you're really writing / reading is the stdin / stdout of another program's execution, how would it be possible for you to fseek anywhere? You can't "seek" to a particular spot in a running application.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Don't think you can use fseek on a pipe - only fread, frwrite, and fflush.

    gg

  4. #4
    Registered User mach5's Avatar
    Join Date
    Feb 2003
    Posts
    7
    Thank you for the fast replies.

    Quzah, this was my first attempt at using fseek, thanks for the information - I understand how it works now.

    Codeplug, I'll use fread and fwrite, thanks.

  5. #5
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by Codeplug
    Don't think you can use fseek on a pipe - only fread, frwrite, and fflush.

    gg
    Hmmm, maybe they should make pread, pwrite, and pflush for the popen?
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

Popular pages Recent additions subscribe to a feed