Re: psql \i handling ~ in specified file name - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: psql \i handling ~ in specified file name
Date
Msg-id 200401080521.i085LUG10014@candle.pha.pa.us
Whole thread Raw
In response to Re: psql \i handling ~ in specified file name  (Peter Eisentraut <peter_e@gmx.net>)
List pgsql-patches
Peter Eisentraut wrote:
> Zach Irmen wrote:
> > refers to following item on TODO
> > Have psql '\i ~/<tab><tab>' actually load files it displays from home
> > dir
>
> This expansion should also apply to all other commands that take file
> names.

Here is a patch that handles "~" in all the file cases.  Thanks for the
initial patch.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: src/bin/psql/command.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/command.c,v
retrieving revision 1.108
diff -c -c -r1.108 command.c
*** src/bin/psql/command.c    1 Dec 2003 22:21:54 -0000    1.108
--- src/bin/psql/command.c    8 Jan 2004 05:17:35 -0000
***************
*** 65,70 ****
--- 65,72 ----
  static bool do_connect(const char *new_dbname, const char *new_user);
  static bool do_shell(const char *command);

+ static char *expand_tilde(char **filename);
+
  /*----------
   * HandleSlashCmds:
   *
***************
*** 413,418 ****
--- 415,421 ----
          else
          {
              fname = scan_option(&string, OT_NORMAL, NULL, true);
+             expand_tilde(&fname);
              status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR;
              free(fname);
          }
***************
*** 494,500 ****
--- 497,506 ----
          if (!fname)
              pset.gfname = NULL;
          else
+         {
+             expand_tilde(&fname);
              pset.gfname = xstrdup(fname);
+         }
          free(fname);
          status = CMD_SEND;
      }
***************
*** 531,536 ****
--- 537,543 ----
          }
          else
          {
+             expand_tilde(&fname);
              success = (process_file(fname) == EXIT_SUCCESS);
              free(fname);
          }
***************
*** 602,607 ****
--- 609,615 ----
      {
          char       *fname = scan_option(&string, OT_FILEPIPE, NULL, true);

+         expand_tilde(&fname);
          success = setQFout(fname);
          free(fname);
      }
***************
*** 653,658 ****
--- 661,667 ----
      {
          char       *fname = scan_option(&string, OT_NORMAL, NULL, true);

+         expand_tilde(&fname);
          success = saveHistory(fname ? fname : "/dev/tty");

          if (success && !quiet && fname)
***************
*** 771,776 ****
--- 780,786 ----
          else
          {
              fname = scan_option(&string, OT_FILEPIPE, NULL, true);
+             expand_tilde(&fname);

              if (!fname)
              {
***************
*** 1678,1683 ****
--- 1688,1747 ----
  }


+ /* expand_tilde
+  *
+  * substitute '~' with HOME or '~username' with username's home dir
+  *
+  */
+ static char *
+ expand_tilde(char **filename)
+ {
+       if (!filename || !(*filename))
+               return NULL;
+
+ #ifndef WIN32
+
+       /* try tilde expansion */
+       if (**filename == '~')
+       {
+               char *fn;
+               char *home;
+               char oldp, *p;
+               struct passwd *pw;
+
+               fn = *filename;
+               home = NULL;
+
+               p = fn+1;
+               while (*p != '/' && *p != '\0')
+                       p++;
+
+               oldp = *p;
+               *p = '\0';
+
+               if (*(fn+1) == '\0')
+                       home = getenv("HOME");
+               else if ((pw = getpwnam(fn+1)) != NULL)
+                       home = pw->pw_dir;
+
+               *p = oldp;
+               if (home)
+               {
+                       char *newfn;
+
+                       newfn = malloc(strlen(home) + strlen(p) + 1);
+                       strcpy(newfn,home);
+                       strcat(newfn,p);
+
+                       free(fn);
+                       *filename = newfn;
+               }
+       }
+
+ #endif
+
+       return *filename;
+ }

  /*
   * process_file

pgsql-patches by date:

Previous
From: Zach Irmen
Date:
Subject: psql error in \? output on \w line
Next
From: Manfred Spraul
Date:
Subject: Re: SIGPIPE handling