Index: trunk/Ohana/src/opihi/cmd.basic/file.c
===================================================================
--- trunk/Ohana/src/opihi/cmd.basic/file.c	(revision 41488)
+++ trunk/Ohana/src/opihi/cmd.basic/file.c	(revision 41489)
@@ -8,4 +8,7 @@
   struct stat fstats;
 
+  if ((N = get_argument (argc, argv, "-h"))) goto usage;
+  if ((N = get_argument (argc, argv, "-help"))) goto usage;
+
   int CAN_READ = FALSE;
   if ((N = get_argument (argc, argv, "-can-read"))) {
@@ -15,13 +18,16 @@
   int CAN_WRITE = FALSE;
   if ((N = get_argument (argc, argv, "-can-write"))) {
+    if (CAN_READ) goto badopts;
     remove_argument (N, &argc, argv);
     CAN_WRITE = TRUE;
   }
+  int GET_STATS = FALSE;
+  if ((N = get_argument (argc, argv, "-stats"))) {
+    if (CAN_READ || CAN_WRITE) goto badopts;
+    remove_argument (N, &argc, argv);
+    GET_STATS = TRUE;
+  }
 
-  if ((argc < 2) || (CAN_READ && CAN_WRITE)) {
-    gprint (GP_ERR, "USAGE: file (filename) [var] [-can-read] [-can-write]\n");
-    gprint (GP_ERR, "  NOTE: only one of -can-read or -can-write is allowed\n");
-    return (FALSE);
-  }
+  if ((argc != 2) && (argc != 3)) goto usage;
 
   if (CAN_READ) {
@@ -30,7 +36,7 @@
       set_int_variable (argv[2], status);
     } else {
-      gprint (GP_ERR, "file %s can", argv[1]);
-      if (!status) gprint (GP_ERR, "not");
-      gprint (GP_ERR, " be read\n");
+      gprint (GP_LOG, "file %s can", argv[1]);
+      if (!status) gprint (GP_LOG, "not");
+      gprint (GP_LOG, " be read\n");
     }
     return TRUE;
@@ -41,7 +47,7 @@
       set_int_variable (argv[2], status);
     } else {
-      gprint (GP_ERR, "file %s can", argv[1]);
-      if (!status) gprint (GP_ERR, "not");
-      gprint (GP_ERR, " be written\n");
+      gprint (GP_LOG, "file %s can", argv[1]);
+      if (!status) gprint (GP_LOG, "not");
+      gprint (GP_LOG, " be written\n");
     }
     return TRUE;
@@ -50,14 +56,76 @@
   status = stat (argv[1], &fstats);
 
-  vstat = !status;
+  if (!GET_STATS) {
+    vstat = !status;
+
+    if (argc == 3) {
+      set_int_variable (argv[2], vstat);
+    } else {
+      gprint (GP_LOG, "file %s is ", argv[1]);
+      if (!vstat) gprint (GP_LOG, "not ");
+      gprint (GP_LOG, "found\n");
+    }
+    return (TRUE);
+  }
+
+  int TimeFormat;
+  time_t TimeReference;
+
+  // use the variable to set the stats fields
+  GetTimeFormat (&TimeReference, &TimeFormat);
 
   if (argc == 3) {
-    set_int_variable (argv[2], vstat);
+    char varname[1024];
+
+    snprintf (varname, 1024, "%s:devID",   argv[2]); set_int_variable (varname, fstats.st_dev);
+    snprintf (varname, 1024, "%s:inode",   argv[2]); set_int_variable (varname, fstats.st_ino);
+    snprintf (varname, 1024, "%s:mode",    argv[2]); set_int_variable (varname, fstats.st_mode);
+    snprintf (varname, 1024, "%s:nlink",   argv[2]); set_int_variable (varname, fstats.st_nlink);
+    snprintf (varname, 1024, "%s:uid",     argv[2]); set_int_variable (varname, fstats.st_uid);
+    snprintf (varname, 1024, "%s:gid",     argv[2]); set_int_variable (varname, fstats.st_gid);
+    snprintf (varname, 1024, "%s:rdev",    argv[2]); set_int_variable (varname, fstats.st_rdev);
+    snprintf (varname, 1024, "%s:size",    argv[2]); set_int_variable (varname, fstats.st_size);
+    snprintf (varname, 1024, "%s:blksize", argv[2]); set_int_variable (varname, fstats.st_blksize);
+    snprintf (varname, 1024, "%s:blocks",  argv[2]); set_int_variable (varname, fstats.st_blocks);
+
+    snprintf (varname, 1024, "%s:atime", argv[2]); set_variable (varname, TimeValue (fstats.st_atim.tv_sec, TimeReference, TimeFormat));
+    snprintf (varname, 1024, "%s:mtime", argv[2]); set_variable (varname, TimeValue (fstats.st_mtim.tv_sec, TimeReference, TimeFormat));
+    snprintf (varname, 1024, "%s:ctime", argv[2]); set_variable (varname, TimeValue (fstats.st_ctim.tv_sec, TimeReference, TimeFormat));
   } else {
-    gprint (GP_ERR, "file %s is ", argv[1]);
-    if (!vstat) gprint (GP_ERR, "not ");
-    gprint (GP_ERR, "found\n");
+    gprint (GP_LOG, "devID   : %d\n", (int) fstats.st_dev);
+    gprint (GP_LOG, "inode   : %d\n", (int) fstats.st_ino);
+    gprint (GP_LOG, "mode    : %o\n", (int) fstats.st_mode);
+    gprint (GP_LOG, "nlink   : %d\n", (int) fstats.st_nlink);
+    gprint (GP_LOG, "uid     : %d\n", (int) fstats.st_uid);
+    gprint (GP_LOG, "gid     : %d\n", (int) fstats.st_gid);
+    gprint (GP_LOG, "rdev    : %d\n", (int) fstats.st_rdev);
+    gprint (GP_LOG, "size    : %d\n", (int) fstats.st_size);
+    gprint (GP_LOG, "blksize : %d\n", (int) fstats.st_blksize);
+    gprint (GP_LOG, "blocks  : %d\n", (int) fstats.st_blocks);
+
+    char *adate = ohana_sec_to_date (fstats.st_atim.tv_sec);
+    gprint (GP_LOG, "atime   : %s\n", adate);
+    free (adate);
+
+    char *mdate = ohana_sec_to_date (fstats.st_mtim.tv_sec);
+    gprint (GP_LOG, "mtime   : %s\n", mdate);
+    free (mdate);
+
+    char *cdate = ohana_sec_to_date (fstats.st_ctim.tv_sec);
+    gprint (GP_LOG, "ctime   : %s\n", cdate);
+    free (cdate);
   }
-  return (TRUE);
+  return TRUE;
+
+badopts:
+gprint (GP_ERR, "  NOTE: only one (or none) of -can-read, -can-write, -stats is allowed\n");
+
+ usage:
+  gprint (GP_ERR, "USAGE: file [var] [-can-read] [-can-write] [-stats]\n");
+  gprint (GP_ERR, "  by default, reports if file exists\n");
+  gprint (GP_ERR, "  -can-read: reports if file exists and can be read\n");
+  gprint (GP_ERR, "  -can-write: reports if file exists and can be written to\n");
+  gprint (GP_ERR, "  -stats: reports if file exists and can be written to\n");
+  return FALSE;
 }
 
Index: trunk/Ohana/src/opihi/lib.shell/BufferOps.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/BufferOps.c	(revision 41488)
+++ trunk/Ohana/src/opihi/lib.shell/BufferOps.c	(revision 41489)
@@ -278,9 +278,9 @@
   
   if (Long) {
-    gprint (GP_LOG, "    N       name                      file     X     Y    bytes BP  U   bzero     bscale  \n");
+    gprint (GP_LOG, "    N       name                      file ND     X     Y     Z      bytes  BP U      bzero     bscale\n");
     for (i = 0; i < Nbuffers; i++) {
-      gprint (GP_LOG, "%5d %10s %25s %5lld %5lld %10lld %3d %1d %10.4e %10.4e\n",
-	      i, buffers[i][0].name, buffers[i][0].file, 
-	      (long long) buffers[i][0].header.Naxis[0], (long long) buffers[i][0].header.Naxis[1],
+      gprint (GP_LOG, "%5d %10s %25s %2d %5lld %5lld %5lld %10lld %3d %1d %10.4e %10.4e\n",
+	      i, buffers[i][0].name, buffers[i][0].file, buffers[i][0].header.Naxes,
+	      (long long) buffers[i][0].header.Naxis[0], (long long) buffers[i][0].header.Naxis[1], (long long) buffers[i][0].header.Naxis[2],
  	      (long long) buffers[i][0].header.datasize + buffers[i][0].matrix.datasize, buffers[i][0].bitpix, 
 	      buffers[i][0].unsign, buffers[i][0].bzero, buffers[i][0].bscale);
@@ -289,9 +289,9 @@
   }
 
-  gprint (GP_LOG, "    N       name                      file     X     Y    bytes\n");
+  gprint (GP_LOG, "    N       name                      file ND     X     Y     Z      bytes\n");
   for (i = 0; i < Nbuffers; i++) {
-    gprint (GP_LOG, "%5d %10s %25s %5lld %5lld %10lld\n",
-	    i, buffers[i][0].name, buffers[i][0].file, 
-	    (long long) buffers[i][0].header.Naxis[0], (long long) buffers[i][0].header.Naxis[1],
+    gprint (GP_LOG, "%5d %10s %25s %2d %5lld %5lld %5lld %10lld\n",
+	    i, buffers[i][0].name, buffers[i][0].file, buffers[i][0].header.Naxes,
+	    (long long) buffers[i][0].header.Naxis[0], (long long) buffers[i][0].header.Naxis[1], (long long) buffers[i][0].header.Naxis[2],
 	    (long long) buffers[i][0].header.datasize + buffers[i][0].matrix.datasize);
   }
Index: trunk/Ohana/src/opihi/lib.shell/parse.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/parse.c	(revision 41488)
+++ trunk/Ohana/src/opihi/lib.shell/parse.c	(revision 41489)
@@ -200,19 +200,7 @@
     }
 
-    /* find value for assignment */
-    V1 = nextcomm (line);
-    if (V1 == (char *) NULL) goto error;
-    if (V1[0] != '=') goto error;
-    V1 ++;
-
-    /*** assign vector element to value ***/
-    val = dvomath (1, &V1, &size, 0); 
-    if (val == (char *) NULL) {
-      print_error ();
-      goto error;
-    }
-
-    /* find vector */
+    /* find vector or buffer (check for valid element)*/
     if (isBuffer) {
+      // unknown buffer name
       if ((buf = SelectBuffer (V0, OLDBUFFER, TRUE)) == NULL) goto error;
       free (V0); V0 = (char *) NULL;
@@ -229,7 +217,4 @@
       if (Nx < 0) Nx += buf[0].header.Naxis[0];
       if (Ny < 0) Ny += buf[0].header.Naxis[1];
-
-      fptr = (float *) buf[0].matrix.buffer;
-      fptr[Nx + Ny*buf[0].header.Naxis[0]] = atof (val);
     } else {
       if ((vec = SelectVector (V0, OLDVECTOR, TRUE)) == NULL) goto error;
@@ -244,9 +229,39 @@
       }
       if (Nx < 0) Nx += vec[0].Nelements;
+    }
+
+    /* find value for assignment */
+    V1 = nextcomm (line);
+    if (V1 == (char *) NULL) goto error;
+    if (V1[0] != '=') goto error;
+    V1 ++;
+
+    /*** assign vector (or buffer) element to value ***/
+    val = dvomath (1, &V1, &size, 0); 
+    if (val == NULL) { 
+      if (!isBuffer && (vec->type == OPIHI_STR)) {
+	while (OHANA_WHITESPACE (*V1)) V1++;
+	val = strcreate (V1);
+	init_error ();
+      } else {
+	print_error ();
+	goto error;
+      }
+    }
+
+    /* find vector */
+    if (isBuffer) {
+      fptr = (float *) buf[0].matrix.buffer;
+      fptr[Nx + Ny*buf[0].header.Naxis[0]] = atof (val);
+    } else {
       if (vec[0].type == OPIHI_FLT) {
 	vec[0].elements.Flt[Nx] = atof (val);
-      } else {
+      } 
+      if (vec[0].type == OPIHI_INT) {
 	vec[0].elements.Int[Nx] = atoll (val);
       }
+      if (vec[0].type == OPIHI_STR) {
+	vec[0].elements.Str[Nx] = strcreate (val);
+      } 
     }
     goto escape;
@@ -359,5 +374,5 @@
 
 /* case 3: we hunt for '{', and then the first '}' and pass everything
-   inbetween.  no nested {{}}s are allowed! */
+   in between.  no nested {{}}s are allowed! */
   
 /* thisword ALLOCATES
Index: trunk/Ohana/src/opihi/pcontrol/Makefile
===================================================================
--- trunk/Ohana/src/opihi/pcontrol/Makefile	(revision 41488)
+++ trunk/Ohana/src/opihi/pcontrol/Makefile	(revision 41489)
@@ -11,6 +11,6 @@
 
 # programs may add their own internal requirements here
-LIBS1         = -ldvo -lkapa -lFITS -lohana
-LIBS2         = -lbasiccmd -lshell -ldata 
+LIBS1         = -lbasiccmd -lshell -ldata 
+LIBS2         = -ldvo -lkapa -lFITS -lohana
 FULL_CFLAGS   = $(BASE_CFLAGS)
 FULL_CPPFLAGS = $(BASE_CPPFLAGS)
