Thread: Calling System Commands from within your program

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    7

    Calling System Commands from within your program

    quick question. how do i call system commands from within my programs.

    for example. if i want it to run ping. like ping 127.0.0.1 from within my own program how would i go about doing that?

    and also if i wanted my program to call a system command with a parameter that is from my prog. like..

    if i run my compiled prog and ran it like so.

    myprog 67.84.xxx.xxx

    i would want it to call the ping command with the parameter 67.84.xxx.xxx

    so it would essentially run ping 67.84.xxx.xxx

    and return the result on my screen.

    how would i do that?

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Read the FAQ. It covers using system as well as command line arguments.


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

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well there's the FAQ for starters.
    http://faq.cprogramming.com/
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    7
    ok i think i got it working. thanks for the reply.

    it was just a matter of using the system(prog) function.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    7
    ok i dont think i can accomplish what im trying to do by doing this.

    wut i had intended on doing was this. i dont know if any of you are familiar the the program "bcrypt" which simply ecrypts a file with the blowfish algo. its syntax is [ bcrypt <filename> ] then it asks you to enter a keyphrase then enter the keyphrase again.

    wut i was trying to do was automate the process so that i could have a program that would take 1 parameter (the file to be encrypted) and run bcrypt [the file] and automatically enter a LONG passphrase twice. so that i dont have to type it out twice every time i want to encrypt a file. there may be a shell scripted way to do this. but im just looking for some guidance. i can see why using the following method it did not work.

    char buff1[50];

    strcpy(buff1,"bcrypt");
    strcat(buff1," filename.txt")

    system(buff1);

    printf("mylongkey\n");

    i can see why this isnt working. its because the printf isnt being called until the bcrypt program is finished running. am i correct. so mabey i could shell script this or something.

  6. #6
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    All system() does is run a command on the shell and return a return value from the shell (which should be the return value of the program run). It does not keep the program open for you to communicate with it.

    If you're trying to communicate with another program, you can programmatically create the process and then redirect streams so your program is writing to that program's stdin.

    In terms of easier solutions, you can redirect the program's IO streams on the commandline. You can do this on the shell simply by using a '|' char. For example:

    On *nix systems:

    Code:
    ls | more
    On Windows/DOS systems:

    Code:
    dir | more
    What that does is redirect stdout on the first process to the stdin of the second process. This means when functions like printf() are used in the first program, the data will go directly to the second program. When the second program uses functions like scanf(), input will be taken from what the first program as sent.

    Another way of doing this, is to write all of your information you want to send to your program in a file. When you run it, redirect its stdin to read from that file. For example:

    Code:
    someprogram.exe < input.txt
    This means that whenever someprogram.exe uses a function like scanf(), input will be read automatically from input.txt.

    Hope some of this is helpful to you.

  7. #7
    Registered User
    Join Date
    Apr 2007
    Posts
    7
    Code:
    someprogram.exe < inputtext.txt
    \

    lmao i cant believe i didnt think of doing that. ill try that out. i think that just might do it.

    thanks for all the help i appreciate it.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by xiver0m View Post
    Code:
    someprogram.exe < inputtext.txt
    \

    lmao i cant believe i didnt think of doing that. ill try that out. i think that just might do it.
    Sometimes it won't work. Often, programs which accept terminal input actually check their stdin descriptor to see if it is a real terminal, or redirected from a file or pipe. The behavior of the program might change, depending.

    So it could work or not. If it doesn't work, I have a new approach to recommend. bcrypt is an open source program. Download the source code and modify it so that it uses some hard-coded password, instead of requiring you to type it in on the command line.

    That way you solve your problem while simultaneously getting exposure to working inside a real, functioning, released program. It isn't a very hard change to make.

  9. #9
    Registered User
    Join Date
    Apr 2007
    Posts
    7
    i was actually really considering doing that. as it shouldnt be hard to change at all.

    i am doing this merly for fun and for educational reasons because i know from a security standpoint this is not the smartest thing to do by any means because if anyone has access to my box they can see my passphrase in plaintext if they read the input txt file or view the source of the modded bcrypt. also it may not be smart as u might be able to reverse engineer the bcrypt that i modded to see the passphrase as well.

  10. #10
    Registered User
    Join Date
    Apr 2007
    Posts
    7
    ok so here is source of bcrypt. (keys.c) this is where the key is grabbed from stdin ill mark the changes that i made. the program compiles but then gives a segmentation fault when ran.

    what gives?
    Code:
    char * getkey(int type){
      char *key, *key2, overflow[2], *ch;
    
    #ifndef WIN32	/* Win32 doesn't have termios.h */
      struct termios term, termsave;
    
      tcgetattr(fileno(stdin), &termsave);
      term = termsave;
      term.c_lflag &= ~ (ECHO | ECHOE | ECHOK | ECHONL);
      tcsetattr(fileno(stdin), TCSANOW, &term);
    #endif
    
      if ((key = malloc(MAXKEYBYTES + 2)) == NULL)
        memerror();
    
      memset(key, 0, MAXKEYBYTES + 2);
    
      //fprintf(stderr, "Encryption key:");       <--------------------------------commented out
      //fgets(key, MAXKEYBYTES + 1, stdin);  <--------------------------------commented out
    	
    	key = "thisisareallylongkey";   <--------------------Defined my own value for variable - key
    
      /* blowfish requires 32 bits, I want 64. deal w/ it	*/
      while (strlen(key) < 9 && type == ENCRYPT) {	/* \n is still tacked on */
        fprintf(stderr, "Key must be at least 8 characters\n");
        memset(key, 0, MAXKEYBYTES + 2);
        //fprintf(stderr, "Encryption key:");
        //fgets(key, MAXKEYBYTES + 1, stdin);
    	key = "thisisareallylongkey";         <-------------------------------- and again here
    
      }
    
      if (memchr(key, (char) 10, MAXKEYBYTES + 1) == NULL) {
        while (fread(overflow, 1, 1, stdin) > 0) {
          if (memcmp(overflow, "\n", 1) == 0)
            break;
        }
      }
    
      if (type == ENCRYPT) {
        if ((key2 = malloc(MAXKEYBYTES + 2)) == NULL)
          memerror();
    
        memset(key2, 0, MAXKEYBYTES + 2);
    //    fprintf(stderr, "\nAgain:");          <--------------------------------commented out
    //  fgets(key2, MAXKEYBYTES + 1, stdin); <--------------------------commented out
    
    	key2 = "thisisareallylongkey";  <--------------Defined own value for key
      
        if (strcmp(key, key2)) {
          fprintf(stderr, "\nKeys don't match!\n");
    #ifndef WIN32	/* Win32 doesn't have termios.h */
          tcsetattr(fileno(stdin), TCSANOW, &termsave);
    #endif
          exit(1);
        }
        memset(key2, 0, strlen(key2));
        free(key2);
      }
    
      if ((ch = memchr(key, (char) 10, strlen(key))) != NULL)
        memset(ch, 0, 1);
    
    #ifndef WIN32	/* Win32 doesn't have termios.h */
    
      tcsetattr(fileno(stdin), TCSANOW, &termsave);
    #endif
    
      fprintf(stderr, "\n");
    
      return(key);
    }
    
    void mutateKey(char **key, char **key2) {
      uInt32 L, R, l, r;
      BLOWFISH_CTX ctx;
      char *newkey, *newkey2;
      int i, j;
    
      j = sizeof(uInt32);
    
      Blowfish_Init(&ctx, *key, strlen(*key));
    
      memcpy(&L, *key, j);
      memcpy(&R, *key+j, j);
      memset(*key, 0, MAXKEYBYTES + 1);
    
      l = L;
      r = R;
    
      if ((*key2 = malloc(MAXKEYBYTES + 1)) == NULL)
        memerror();
      if ((newkey = malloc(MAXKEYBYTES + 1)) == NULL)
        memerror();
      if ((newkey2 = malloc(MAXKEYBYTES + 1)) == NULL)
        memerror();
    
      memset(*key2, 0, MAXKEYBYTES + 1);
      memset(newkey, 0, MAXKEYBYTES + 1);
      memset(newkey2, 0, MAXKEYBYTES + 1);
    
      for (i=0; i < MAXKEYBYTES; i+=(j*2)) {
        Blowfish_Encrypt(&ctx, &L, &R);
        memcpy(newkey+i, &L, j);
        memcpy(newkey+i+j, &R, j);
      }
    
      for (i=0; i < MAXKEYBYTES; i+=(j*2)) {
        l = swapEndian(l);
        r = swapEndian(r);
    
        Blowfish_Encrypt(&ctx, &l, &r);
    
        l = swapEndian(l);
        r = swapEndian(r);
    
        memcpy(newkey2+i, &l, j);
        memcpy(newkey2+i+j, &r, j);
      }
    
      memcpy(*key, newkey, MAXKEYBYTES);
      memcpy(*key2, newkey2, MAXKEYBYTES);
      free(newkey);
    }

  11. #11
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    First of all, you have a char * named key and another one named key2. The following applies to both cases.

    The program malloc()s enough memory to hold a certain length of a key. You then do something like this:

    Code:
    key = "thisisareallylongkey";
    What does this do? Well, basically, "thisisareallylongkey" is stored inside your program somewhere, probably in the .data segment. String literals like this are supposed to be assumed to be read-only memory. This obviously means you shouldn't alter the string. The above line of code causes key to point to the location where this string is inside your program.

    Few problems with this:

    1) As I stated, you are pointing to a (probably) read-only string.
    2) You have a memory leak because key used to point to dynamically allocated memory received from malloc(), and you changed where it points, so you lost the address of the block of memory that malloc() returned to you.

    From briefly looking at the code, you're probably crashing because it's trying to manipulate your key.

    Solution: You should be using strcpy() or strncpy() to set the value of key. Make sure that you do this after key points to a valid block of memory, or change key to be an array.

  12. #12
    Registered User
    Join Date
    Apr 2007
    Posts
    7
    so i added 2 new variables and used strncpy to copy the values into key and key2. when it runs it causes a segmentation fault did i put the strncpy in the wrong place?
    Code:
    char * getkey(int type){
    char *key, *key2, overflow[2], *ch;
    
    char kkey [] = "thisisareallylongkey\n";   <--------added var kkey
    char kkey2 [] = "thisisareallylongkey\n"; <--------added var kkey2
    
    #ifndef WIN32	/* Win32 doesn't have termios.h */
      struct termios term, termsave;
    
      tcgetattr(fileno(stdin), &termsave);
      term = termsave;
      term.c_lflag &= ~ (ECHO | ECHOE | ECHOK | ECHONL);
      tcsetattr(fileno(stdin), TCSANOW, &term);
    #endif
    
      if ((key = malloc(MAXKEYBYTES + 2)) == NULL)
        memerror();
    
      memset(key, 0, MAXKEYBYTES + 2);
    
      fprintf(stderr, "Encryption key:");
      //fgets(key, MAXKEYBYTES + 1, stdin); <----------commented out fgets
      strncpy(key,kkey,MAXKEYBYTES + 1); <---------copied value from kkey (thisisareallylongkey) into var key
    	
    	
    
      /* blowfish requires 32 bits, I want 64. deal w/ it	*/
      while (strlen(key) < 9 && type == ENCRYPT) {	/* \n is still tacked on */
        fprintf(stderr, "Key must be at least 8 characters\n");
        memset(key, 0, MAXKEYBYTES + 2);
        fprintf(stderr, "Encryption key:");
        //fgets(key, MAXKEYBYTES + 1, stdin); <----------commented out fgets
        strncpy(key,kkey,MAXKEYBYTES + 1); <---------copied value from kkey (thisisareallylongkey) into var key
    
      }
    
      if (memchr(key, (char) 10, MAXKEYBYTES + 1) == NULL) {
        while (fread(overflow, 1, 1, stdin) > 0) {
          if (memcmp(overflow, "\n", 1) == 0)
            break;
        }
      }
    
      if (type == ENCRYPT) {
        if ((key2 = malloc(MAXKEYBYTES + 2)) == NULL)
          memerror();
    
        memset(key2, 0, MAXKEYBYTES + 2);
        fprintf(stderr, "\nAgain:");
        //fgets(key2, MAXKEYBYTES + 1, stdin); <----------commented out fgets
        strncpy(key2,kkey2,MAXKEYBYTES + 1); <---------copied value from kkey2 (thisisareallylongkey) into var key2
      
        if (strcmp(key, key2)) {
          fprintf(stderr, "\nKeys don't match!\n");
    #ifndef WIN32	/* Win32 doesn't have termios.h */
          tcsetattr(fileno(stdin), TCSANOW, &termsave);
    #endif
          exit(1);
        }
        memset(key2, 0, strlen(key2));
        free(key2);
      }
    
      if ((ch = memchr(key, (char) 10, strlen(key))) != NULL)
        memset(ch, 0, 1);
    
    #ifndef WIN32	/* Win32 doesn't have termios.h */
    
      tcsetattr(fileno(stdin), TCSANOW, &termsave);
    #endif
    
      fprintf(stderr, "\n");
    
      return(key);
    }
    
    void mutateKey(char **key, char **key2) {
      uInt32 L, R, l, r;
      BLOWFISH_CTX ctx;
      char *newkey, *newkey2;
      int i, j;
    
      j = sizeof(uInt32);
    
      Blowfish_Init(&ctx, *key, strlen(*key));
    
      memcpy(&L, *key, j);
      memcpy(&R, *key+j, j);
      memset(*key, 0, MAXKEYBYTES + 1);
    
      l = L;
      r = R;
    
      if ((*key2 = malloc(MAXKEYBYTES + 1)) == NULL)
        memerror();
      if ((newkey = malloc(MAXKEYBYTES + 1)) == NULL)
        memerror();
      if ((newkey2 = malloc(MAXKEYBYTES + 1)) == NULL)
        memerror();
    
      memset(*key2, 0, MAXKEYBYTES + 1);
      memset(newkey, 0, MAXKEYBYTES + 1);
      memset(newkey2, 0, MAXKEYBYTES + 1);
    
      for (i=0; i < MAXKEYBYTES; i+=(j*2)) {
        Blowfish_Encrypt(&ctx, &L, &R);
        memcpy(newkey+i, &L, j);
        memcpy(newkey+i+j, &R, j);
      }
    
      for (i=0; i < MAXKEYBYTES; i+=(j*2)) {
        l = swapEndian(l);
        r = swapEndian(r);
    
        Blowfish_Encrypt(&ctx, &l, &r);
    
        l = swapEndian(l);
        r = swapEndian(r);
    
        memcpy(newkey2+i, &l, j);
        memcpy(newkey2+i+j, &r, j);
      }
    
      memcpy(*key, newkey, MAXKEYBYTES);
      memcpy(*key2, newkey2, MAXKEYBYTES);
      free(newkey);
    }

  13. #13
    Fear the Reaper...
    Join Date
    Aug 2005
    Location
    Toronto, Ontario, Canada
    Posts
    625
    Where is MAXKEYBYTES defined ? As it could be longer then the amount of space allocated to kkey and kkey2, producing your segfault.
    Teacher: "You connect with Internet Explorer, but what is your browser? You know, Yahoo, Webcrawler...?" It's great to see the educational system moving in the right direction

  14. #14
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    (char) 10
    '\r' or '\n' are easier to read than that.

    You are aware of the problems with strncpy()? If its buffer has at least N characters, no NULL terminator is added! Your code may handle this, I didn't look too closely . . . but in general, you should call strncpy like this:
    Code:
    strcpy(array, data, number);
    array[number-1] = 0;
    Names beginning with is (for isupper() etc in ctype.h) as reserved, so it's possible that names beginning with mem (for memset() etc) might be as well. So you might want to call memerror() something else. That's your decision, though.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Client-server system with input from separate program
    By robot-ic in forum Networking/Device Communication
    Replies: 3
    Last Post: 01-16-2009, 03:30 PM
  2. Using variables in system()
    By Afro in forum C Programming
    Replies: 8
    Last Post: 07-03-2007, 12:27 PM
  3. Limiting another program from taking to much of system
    By adr in forum Windows Programming
    Replies: 9
    Last Post: 07-02-2007, 01:47 AM
  4. Multiple System Commands
    By Denethor2000 in forum C++ Programming
    Replies: 2
    Last Post: 02-21-2004, 08:35 PM
  5. calling a program from a program
    By Waldo2k2 in forum C Programming
    Replies: 2
    Last Post: 01-20-2003, 01:43 PM