// parse raw string into args bool parse_vmgahp_command(const char* raw, Gahp_Args& args) { if (!raw) { vmprintf(D_ALWAYS,"ERROR parse_vmgahp_command: empty command\n"); return false; } args.reset(); int len=strlen(raw); char * buff = (char*)malloc(len+1); ASSERT( buff != NULL ); int buff_len = 0; for (int i = 0; i<len; i++) { if ( raw[i] == '\\' ) { i++; //skip this char if (i<(len-1)) { buff[buff_len++] = raw[i]; } continue; } /* Check if charcater read was whitespace */ if ( raw[i]==' ' || raw[i]=='\t' || raw[i]=='\r' || raw[i] == '\n') { /* Handle Transparency: we would only see these chars if they WEREN'T escaped, so treat them as arg separators */ buff[buff_len++] = '\0'; args.add_arg( strdup(buff) ); buff_len = 0; // re-set temporary buffer } else { // It's just a regular character, save it buff[buff_len++] = raw[i]; } } /* Copy the last portion */ buff[buff_len++] = '\0'; args.add_arg(strdup(buff) ); free (buff); return true; }
bool VMGahpServer::read_argv(Gahp_Args &g_args) { static char* buf = NULL; int ibuf = 0; int result = 0; bool trash_this_line = false; bool escape_seen = false; static const int buf_size = 1024 * 10; if( m_is_initialized == false ) { return false; } if( m_vmgahp_readfd == -1 ) { dprintf( D_ALWAYS, "VMGAHP[%d] -> (no pipe)\n", m_vmgahp_pid ); return false; } g_args.reset(); if( buf == NULL ) { buf = (char*)malloc(buf_size); ASSERT( buf != NULL ); } ibuf = 0; for (;;) { ASSERT(ibuf < buf_size); result = daemonCore->Read_Pipe(m_vmgahp_readfd, &(buf[ibuf]), 1 ); /* Check return value from read() */ if( result < 0 ) { return false; } if( result == 0 ) { /* End of File */ // clear out all entries g_args.reset(); dprintf( D_ALWAYS, "VMGAHP[%d] -> EOF\n", m_vmgahp_pid ); return false; } /* If we just saw an escaping backslash, let this character * through unmolested and without special meaning. */ if( escape_seen ) { ibuf++; escape_seen = false; continue; } /* Check if the character read is a backslash. If it is, then it's * escaping the next character. */ if( buf[ibuf] == '\\' ) { escape_seen = true; continue; } /* Unescaped carriage return characters are ignored */ if( buf[ibuf] == '\r' ) { continue; } /* An unescaped space delimits a parameter to copy into argv */ if( buf[ibuf] == ' ' ) { buf[ibuf] = '\0'; g_args.add_arg( strdup( buf ) ); ibuf = 0; continue; } /* If character was a newline, copy into argv and return */ if( buf[ibuf]=='\n' ) { buf[ibuf] = 0; g_args.add_arg( strdup( buf ) ); trash_this_line = false; // Note: A line of unexpected text from the vmgahp server // that triggers a RESULTS command (whether it's the // async-mode 'R' or some extraneous un-prefixed text) // will be printed in the log after the RESULTS line // is logged. This implied reversal of causality isn't // easy to fix, so we leave it as-is. static MyString debug; debug = ""; if( g_args.argc > 0 ) { debug += "'"; for ( int i = 0; i < g_args.argc; i++ ) { if( i != 0 ) { debug += "' '"; } if( g_args.argv[i] ) { debug += g_args.argv[i]; } } debug += "'"; } dprintf( D_FULLDEBUG, "VMGAHP[%d] -> %s\n", m_vmgahp_pid, debug.Value() ); // check for a single "R". This means we should check // for results in vmgahp async mode. if( trash_this_line==false && g_args.argc == 1 && g_args.argv[0][0] == 'R' ) { poll_real_soon(); // ignore anything else on this line & read again trash_this_line = true; } if( trash_this_line ) { // reset all our buffers and read the next line g_args.reset(); ibuf = 0; continue; // go back to the top of the for loop } return true; } /* Character read was just a regular one.. increment index * and loop back up to read the next character */ ibuf++; } /* end of infinite for loop */ // We will never reach here return false; }