/* Copyright (c) 2001 by SoftIntegration, Inc. All Rights Reserved */
/***********************************************************
* command name: pushd [n|dir]
* Note: (1) push the current working directory onto the stack
*          and change to dir.
*          The dir is to be poped out by command popd
*       (2) pushd is C shell compatible.
*       (2) global variable g_dirstack is defined in 
*           $CHHOME/config/chrc
*
* History: created by Harry H. Cheng, 11/5/1996
**********************************************************/
#include<stdio.h>
int main(int argc, char *argv[]) {
  struct dirstack_t{ 
    string_t dir;  
    struct dirstack_t *next;
  } *cwdir, *tmp;
  int n;

  if(g_dirstack == NULL) { /* first time */
    cwdir = (struct dirstack_t * )malloc(sizeof(dirstack_t));
    //cwdir = (dirstack_t * )malloc(sizeof(dirstack_t));
    if(cwdir == NULL) {
      fprintf(stderr, "Error: no memory for pushd \n");
      return(1);
    }
    else
      cwdir->next = NULL;
    cwdir->dir = _cwd;
    g_dirstack = (char *)cwdir;
  }
 
  if(argc == 1) {
    cwdir = (struct dirstack_t *)g_dirstack;
    if(cwdir == NULL || cwdir->next == NULL) {
      fprintf(stderr, "pushd: No other directory\n");
      return(1);
    }
    else {
      tmp = (struct dirstack_t *)g_dirstack;
      cwdir = tmp->next;
      tmp = tmp->next->next;
      cwdir->next = (struct dirstack_t *)g_dirstack;
      cwdir->next->next = tmp;
      g_dirstack = (char *)cwdir;
      chdir(cwdir->dir);
      _cwd = cwdir->dir;
      if(!_status) {
         n = 0;
         while(cwdir!=NULL) {
           printf("%d\t%s\n", n++, cwdir->dir);
           cwdir = cwdir->next;
         }
      }
    }
  }
  else if(argc == 2) {
    argv++;
    if(isnum(*argv)) {
      n = atoi(*argv);
      tmp = (struct dirstack_t *)g_dirstack;
      while(tmp->next!=NULL && n>1) {
        tmp = tmp->next;
        n--;
      }
      if(tmp->next==NULL) {
         fprintf(stderr, "pushd: Invalid number for entry in directory stack \n");
         fprintf(stderr, "Usage: pushd [n|dir] \n");
         return(1);
      }
      else {
         cwdir = tmp->next;
         tmp->next = tmp->next->next;
      }
      cwdir->next = (struct dirstack_t *)g_dirstack;
      g_dirstack = (char *)cwdir;
      chdir(cwdir->dir);
      _cwd = cwdir->dir;
      if(!_status) {
         n = 0;
         while(cwdir!=NULL) {
           printf("%d\t%s\n", n++, cwdir->dir);
           cwdir = cwdir->next;
         }
      }
    }
    else {
      if(!chdir(*argv)) { /* chdir successfull */
        _cwd = getcwd(NULL, 256);
        cwdir = (struct dirstack_t * )malloc(sizeof(dirstack_t));
        if(cwdir == NULL) {
          fprintf(stderr, "Error: no memory for pushd \n");
          return(1);
        }
        else
         cwdir->next = NULL;
        cwdir->dir = _cwd;
        cwdir->next = (struct dirstack_t *)g_dirstack;
        g_dirstack = (char *)cwdir;
        n = 0;
        while(cwdir!=NULL) {
          printf("%d\t%s\n", n++, cwdir->dir);
          cwdir = cwdir->next;
        }
      }
      else 
      {
         fprintf(stderr, "pushd: %s: No such directory\n", *argv);
      }
    }
  }
  else {
    fprintf(stderr, "pushd: Too many arguments\n");
    fprintf(stderr, "Usage: pushd [n|dir] \n");
  }

}
