Zach Irmen wrote:
> Bruce Momjian wrote:
> > Here is a patch that handles "~" in all the file cases.
> 
> Beat me to it. :)
> 
> I do have a few issues that I was trying to sort out myself
> regarding this, but I guess now is as good a time as any to ask
> them here.
> 
> First off, there should be a check after the malloc to make sure
> NULL wasn't returned in the expand_tilde function. I missed that
> one.

OK, test added.  I see no way to recover from a malloc failure in this
case because we can't honor their specification of file name, so we have
to exit.

> Secondly, there are a couple of SQL commands (like COPY and
> LOAD) and psql commands handled outside command.c (like \copy)
> which also take filenames. I'm guessing that eventually you'll
> want substitution in those cases as well. So does this mean that
> the expand_tilde function probably should not be in command.c?
> Placing it in common.c seems the logical place to make it at
> least available to all the psql commands (\copy included).

Yes, seems like that will be required.  Please use my attached version
to make the adjustments.

> And finally, I was wondering if arguments with leading pipes
> (e.g. "|~/file") should  also get substituted.

Yep, that too.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  [EMAIL PROTECTED]               |  (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 18:01:55 -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,1753 ----
  }
  
  
+ /* expand_tilde
+  *
+  * substitute '~' with HOME or '~username' with username's home dir
+  *
+  */
+ static char *
+ expand_tilde(char **filename)
+ {
+       if (!filename || !(*filename))
+               return NULL;
+ 
+       /* MSDOS uses tilde for short versions of long file names, so skip it. */
+ #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);
+                       if (!newfn)
+                       {
+                               psql_error("out of memory\n");
+                               exit(EXIT_FAILURE);
+                       }
+                       strcpy(newfn, home);
+                       strcat(newfn, p);
+ 
+                       free(fn);
+                       *filename = newfn;
+               }
+       }
+ #endif
+ 
+       return *filename;
+ }
  
  /*
   * process_file
---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
      subscribe-nomail command to [EMAIL PROTECTED] so that your
      message can get through to the mailing list cleanly

Reply via email to