/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* This file is distributed subject to a Software License Agreement found
* in the file LICENSE that is included with this distribution. 
\*************************************************************************/

/*
 * $Log: not supported by cvs2svn $
 * Revision 1.3  2003/08/08 20:43:11  soliday
 * Updated code so that this is a dynamically loadable extension.
 *
 * Revision 1.2  2002/08/14 20:44:39  soliday
 * Added Open License
 *
 * Revision 1.1  1999/06/10 19:37:49  soliday
 * Moved to oag tree.
 *
 * Revision 1.3  1999/06/08 20:47:22  soliday
 * Removed compiler warnings under Linux.
 *
 * Revision 1.2  1999/04/21 19:51:57  soliday
 * Added tclEditString
 *
 * Revision 1.1  1996/12/16 20:49:59  saunders
 * New extension for implementing os specific functions. Initially,
 * lockf is being implemented.
 *
 */

#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

#include <tclOS.h>

#define VERSION "1.0"

#if ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8)
#define OSCONST const
#else
#define OSCONST
#endif

static Tcl_HashTable tclOSCmdTable;

typedef struct {
  char *name;     /* os xxx command name */
  int (*proc)();  /* command handling function */
} CMD_INFO;

static CMD_INFO tclOSCommands[] = {
  {"lockf", tclOSLockf},
  {"editstring", tclEditString},
  {"setfacl", tclOSSetfacl},
  {"getfacl", tclOSGetfacl},
  {(char *)NULL, (int (*)())NULL}
};


/* Function Prototypes */
EXTERN int Tclos_Init(Tcl_Interp *interp);
int tclOSCmd(ClientData dummy, Tcl_Interp *interp, int argc, OSCONST char *argv[]);
int tclOSCmd(ClientData dummy, Tcl_Interp *interp, int argc, OSCONST char *argv[])
{

  Tcl_HashEntry *entryPtr;
  int (*handler)();

  if (argc < 2) {
    Tcl_SetResult(interp, "os: must specify a sub-command", 
		  (Tcl_FreeProc *) NULL); 
    return TCL_ERROR;
  }

  entryPtr = Tcl_FindHashEntry(&tclOSCmdTable, argv[1]);
  if (entryPtr == NULL) {
    Tcl_SetResult(interp, "Unknown os command ", (Tcl_FreeProc *) NULL);
    return TCL_ERROR;
  } else {
    handler = (int(*)())Tcl_GetHashValue(entryPtr);
    return ((*handler)(interp, argc, argv));
  }

}

int Tclos_Init(Tcl_Interp *interp) {
  CMD_INFO *cmd;
  if (Tcl_InitStubs(interp, "8.0", 0) == NULL) {
    return TCL_ERROR;
  }
  if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) {
    if (TCL_VERSION[0] == '7') {
      if (Tcl_PkgRequire(interp, "Tcl", "8.0", 0) == NULL) {
	return TCL_ERROR;
      }
    }
  }
  if (Tcl_PkgProvide(interp, "os", VERSION) != TCL_OK) {
    return TCL_ERROR;
  }

  Tcl_CreateCommand(interp, "os", tclOSCmd, (ClientData *) NULL,
		    (Tcl_CmdDeleteProc *)NULL);

  Tcl_InitHashTable(&tclOSCmdTable, TCL_STRING_KEYS);
  for (cmd=tclOSCommands ; cmd->name != NULL ; cmd++) {
    int newEntry;
    Tcl_HashEntry *entryPtr;
    entryPtr = Tcl_CreateHashEntry(&tclOSCmdTable, cmd->name, &newEntry);
    Tcl_SetHashValue(entryPtr, cmd->proc);
  }
  tclOSInit(interp);
  
  return TCL_OK;
}




