Re: psql \i handling ~ in specified file name - Mailing list pgsql-patches
From | Zach Irmen |
---|---|
Subject | Re: psql \i handling ~ in specified file name |
Date | |
Msg-id | Pine.WNT.4.58.0401090019350.-501301@zi.ed.shawcable.net Whole thread Raw |
In response to | psql \i handling ~ in specified file name (Zach Irmen <zirmen@shaw.ca>) |
Responses |
Re: psql \i handling ~ in specified file name
Re: psql \i handling ~ in specified file name |
List | pgsql-patches |
Bruce Momjian wrote: > Yes, seems like that will be required. Please use my attached version > to make the adjustments. Ok. Adjustments made. All psql commands should be handled. > Zach Irmen wrote: > > And finally, I was wondering if arguments with leading pipes > > (e.g. "|~/file") should also get substituted. > > Yep, that too. Actually, I found out that popen calls seem to handle the tilde fine as this was already working on my FreeBSD box without substitution. I'm not sure if this is true for all Unix systems in general, but I won't bother putting that in unless it turns out to be needed. Index: command.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/command.c,v retrieving revision 1.108 diff -c -r1.108 command.c *** command.c 1 Dec 2003 22:21:54 -0000 1.108 --- command.c 9 Jan 2004 06:51:55 -0000 *************** *** 413,418 **** --- 413,419 ---- 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 **** --- 495,504 ---- if (!fname) pset.gfname = NULL; else + { + expand_tilde(&fname); pset.gfname = xstrdup(fname); + } free(fname); status = CMD_SEND; } *************** *** 531,536 **** --- 535,541 ---- } else { + expand_tilde(&fname); success = (process_file(fname) == EXIT_SUCCESS); free(fname); } *************** *** 561,567 **** --- 566,575 ---- success = false; } else + { + expand_tilde(&opt2); success = do_lo_export(opt1, opt2); + } } else if (strcmp(cmd + 3, "import") == 0) *************** *** 572,578 **** --- 580,589 ---- success = false; } else + { + expand_tilde(&opt1); success = do_lo_import(opt1, opt2); + } } else if (strcmp(cmd + 3, "list") == 0) *************** *** 602,607 **** --- 613,619 ---- { char *fname = scan_option(&string, OT_FILEPIPE, NULL, true); + expand_tilde(&fname); success = setQFout(fname); free(fname); } *************** *** 653,658 **** --- 665,671 ---- { char *fname = scan_option(&string, OT_NORMAL, NULL, true); + expand_tilde(&fname); success = saveHistory(fname ? fname : "/dev/tty"); if (success && !quiet && fname) *************** *** 771,776 **** --- 784,790 ---- else { fname = scan_option(&string, OT_FILEPIPE, NULL, true); + expand_tilde(&fname); if (!fname) { Index: common.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/common.c,v retrieving revision 1.78 diff -c -r1.78 common.c *** common.c 29 Nov 2003 19:52:06 -0000 1.78 --- common.c 9 Jan 2004 06:51:56 -0000 *************** *** 814,816 **** --- 814,878 ---- else return PQuser(pset.db); } + + + /* expand_tilde + * + * substitute '~' with HOME or '~username' with username's home dir + * + */ + 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; + } Index: common.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/common.h,v retrieving revision 1.31 diff -c -r1.31 common.h *** common.h 1 Dec 2003 22:14:40 -0000 1.31 --- common.h 9 Jan 2004 06:51:56 -0000 *************** *** 58,61 **** --- 58,63 ---- #define pclose(x) _pclose(x) #endif + extern char *expand_tilde(char **filename); + #endif /* COMMON_H */ Index: copy.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/copy.c,v retrieving revision 1.35 diff -c -r1.35 copy.c *** copy.c 1 Dec 2003 22:14:40 -0000 1.35 --- copy.c 9 Jan 2004 06:51:56 -0000 *************** *** 221,226 **** --- 221,227 ---- result->file = NULL; else result->file = xstrdup(token); + expand_tilde(&result->file); token = strtokx(NULL, whitespace, NULL, NULL, 0, false, pset.encoding);
pgsql-patches by date: