/* api_system.c : part of The Bastard disassembly environment 
 *
 */
#include <bastard.h>
#include <dirent.h>
#include <glob.h>
#include <sys/types.h>

/*    API section:
 *
 *    17. System Interaction	:: Various utility functions
 * /

/* ------------------------------------------------------System Interaction */
   void Message( const char *str) {
   /* Print a message unless QUIET is flag is set 
    */
      if (! (disasm_env.flags & QUIET))  printf("%s", str);
      return;
   }

   void ErrorMsg( int num, const char *str) {
   /* Print a message and error code, regardless of QUIET */
      printf("Error %d: %s\n", num, str);
      return;
   }

   void Quit(void) {
      CloseDB();
      finSeer();
      if ( cmd != NULL) free(cmd);
   //if ( stdin != oldIN)   { fclose(stdin); stdin = oldIN; }
   //if ( stdout != oldOUT) { fclose(stdout); stdout = oldOUT; }
   //if ( stderr != oldERR) { fclose(stderr); stderr = oldERR; }
   }

   int Exec( char *args ){
      char buf[256];
      sprintf( buf, ".bdb/%s %s", target.name, args); 
      return(system(buf));
   }

   int Debug(void) {
      char buf[256];
      sprintf( buf, "gdb .bdb/%s", target.name); 
      return(system(buf));
   }

   int Core(void) {
   /* start target in new process w/ core dumps enabled */
   /* wait for user to hit key */
   /* send a sig_core to target PID */
      Message("Core not yet supported!\n");
      return(-1);
   }

   int Panic(void) {
   /* Similar to 'core' */
   /* Get a kernel dump w/o killing the kernel, if possible */
   /* ... the idea is to get a snapshot of the kernel as a target is
    * running */
      Message("Panic not yet supported!\n");
      return(-1);
   }

/* if supplied with a char buffer, the next 2 functions will print to
 * it rather than to stdout. */
   int GetValidFormats(char *buf){
   /* print newline-delimited string of file formats */
      char tmp[4096], *pos;
      glob_t globbuf;
      int x, len;
   
      sprintf(tmp, "%sformats/*.sc", disasm_env.home);
      glob(tmp, 0, NULL, &globbuf);
      for (x=0; x < globbuf.gl_pathc; x++){
         pos = strrchr(globbuf.gl_pathv[x], '/') + 1; 
         len = strstr(globbuf.gl_pathv[x],".sc") - pos;
         strncpy(tmp, pos, len);
         tmp[len] = '\0';
         printf("%s\n", tmp);
      }
      globfree(&globbuf);
      return(0);
   }

   int GetValidArchs(){
   /* print newline-delimited string of cpu architectures */
      char tmp[4096], *pos;
      glob_t globbuf;
      int x, len;
   
      sprintf(tmp, "%sarch/lib*.so", disasm_env.home);
      glob(tmp, 0, NULL, &globbuf);
      for (x=0; x < globbuf.gl_pathc; x++){
         pos = strrchr(globbuf.gl_pathv[x], '/') + 4; 
         len = strstr(globbuf.gl_pathv[x],".so") - pos;
         strncpy(tmp, pos, len);
         tmp[len] = '\0';
         printf("%s\n", tmp);
      }
      globfree(&globbuf);
      return(0);
   }

   int GetEnvFlag( int flag ){
      if (disasm_env.flags & flag) 
         return(1);			
      return(0);
   }

   int SetEnvFlag( int flag ){
      disasm_env.flags != flag;			
      return(0);
   }


   void SetTtyFmt(char *fmt){
      if (disasm_env.ttyFmt != defaultFmt) free(disasm_env.ttyFmt);
      if (! fmt ) disasm_env.ttyFmt = defaultFmt;
      else {
         disasm_env.ttyFmt = malloc(strlen(fmt) + 1);
         strcpy(disasm_env.ttyFmt, fmt);
      }
      return;
   }

   void SetAsmFmt(char *fmt){
      if (disasm_env.asmFmt != defaultFmt) free(disasm_env.asmFmt);
      if (! fmt ) disasm_env.asmFmt = defaultFmt;
      else {
         disasm_env.asmFmt = malloc(strlen(fmt) + 1);
         strcpy(disasm_env.asmFmt, fmt);
      }
      return;
   }

   void SetLprFmt(char *fmt){
      if (disasm_env.lprFmt != defaultFmt) free(disasm_env.lprFmt);
      if (! fmt ) disasm_env.lprFmt = defaultFmt;
      else {
         disasm_env.lprFmt = malloc(strlen(fmt) + 1);
         strcpy(disasm_env.lprFmt, fmt);
      }
      return;
   }

/* ----------------------------------------------- Error Handling */
#include <api_error.h>
   int _last_bastard_error;

   int SetLastError( int errnum ){
   /* This returns 0 so that you can do a `return(SetLastError(#));` */
      _last_bastard_error = errnum;
      return(0);
   }

   char* GetErrorString( int errnum ){
      int x;
   
      for (x=0; _bastard_error_table[x].errnum != 0; x++)
         if (_bastard_error_table[x].errnum == errnum)
            return( _bastard_error_table[x].errstr);
      return( NULL ) ;	
   }

   int GetLastError(){
      return( _last_bastard_error );
   }

   char* GetLastErrorString( ){
      return( GetErrorString( _last_bastard_error) );
   }

   void PrintErrorMsg(int errnum){
      char *msg;
   
      ErrorMsg( errnum, GetErrorString(errnum));
      return;
   }
   void SprintErrorMsg(char *buf, int errnum){
      if (! buf) 
         return;
      strcpy( buf, GetErrorString(errnum) );
      return;
   }

