Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ported from mercurial] JOE prompts the user to create the backup dir if it doesn't exist + minor fix to chddir #11

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
57 changes: 0 additions & 57 deletions joe/b.c
Original file line number Diff line number Diff line change
Expand Up @@ -2587,63 +2587,6 @@ char *parsens(const char *s, off_t *skip, off_t *amnt, int *mode)
return n;
}

/* Canonicalize file name: do ~ expansion */

char *canonical(char *n, int flags)
{
ptrdiff_t y = 0;
#ifndef __MSDOS__
ptrdiff_t x;
char *s;
if (!(flags & CANFLAG_NORESTART)) {
for (y = zlen(n); ; --y)
if (y <= 2) {
y = 0;
break;
} else if (n[y-2] == '/' && (n[y-1] == '/' || n[y-1] == '~')) {
y -= 1;
break;
}
}
if (n[y] == '~') {
for (x = y + 1; n[x] && n[x] != '/'; ++x) ;
if (n[x] == '/') {
if (x == y + 1) {
char *z;

s = getenv("HOME");
z = vsncpy(NULL, 0, sz(s));
z = vsncpy(z, sLEN(z), sz(n + x));
vsrm(n);
n = z;
y = 0;
} else {
struct passwd *passwd;

n[x] = 0;
passwd = getpwnam((n + y + 1));
n[x] = '/';
if (passwd) {
char *z = vsncpy(NULL, 0,
sz((passwd->pw_dir)));

z = vsncpy(z, sLEN(z), sz(n + x));
vsrm(n);
n = z;
y = 0;
}
}
}
}
#endif
if (y) {
char *z = vsncpy(NULL, 0, n + y, zlen(n + y));
vsrm(n);
return z;
} else
return n;
}

static off_t euclid(off_t a, off_t b)
{
if (!a)
Expand Down
3 changes: 0 additions & 3 deletions joe/b.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,6 @@ int bsavefd(P *p, int fd, off_t size);

char *parsens(const char *s, off_t *skip, off_t *amnt, int *mode);

char *canonical(char *s, int flags);
#define CANFLAG_NORESTART 1 /* Support path restart feature */

/* Get byte at pointer or return NO_MORE_DATA if pointer is at end of buffer */
int brc(P *p);

Expand Down
25 changes: 25 additions & 0 deletions joe/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,19 @@ int ushowlog(W *w, int k)
return 1;
}

int createbackpathdir(W *w, int c, void *object, int *notify)
{
if (c == YES_CODE || yncheck(yes_key, c)) {
if (mkpath((char *)object)) {
_exit(-1);
}

return 0;
}

return -1;
}

int main(int argc, char **real_argv, const char * const *envv)
{
CAP *cap;
Expand Down Expand Up @@ -659,6 +672,18 @@ int main(int argc, char **real_argv, const char * const *envv)

}

/* Prompt user to create backup directory if it does not exist. */
char *oldpwd = pwd();
const char *backpath = get_status(NULL, "backpath");

if (zcmp(backpath, "") != 0 && chddir(backpath) != 0) {
if (!mkqw(((BASE*)lastw(maint)->object)->parent, sz(joe_gettext(_("Backup directory does not exist. Create the directory (y,n)? "))), createbackpathdir, NULL, (void*)backpath, NULL)) {
return -1;
}
}

chpwd(oldpwd);

if (!idleout) {
if (!isatty(fileno(stdin)) && modify_logic((BW *)maint->curwin->object, ((BW *)maint->curwin->object)->b)) {
/* Read stdin into window asynchronously */
Expand Down
83 changes: 80 additions & 3 deletions joe/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ char *endprt(const char *path)
int mkpath(char *path)
{
char *s;
char *oldpwd = pwd(); /* Store pwd so we can return to it after path is made */
char *start = path;

if (path[0] == '/') {
if (chddir("/"))
Expand All @@ -171,19 +173,25 @@ int mkpath(char *path)
c = *s;
*s = 0;
if (chddir(path)) {
if (mkdir(path, 0777))
return 1;
if (chddir(path))
/* Create and change directory unless this segment is a home directory */
if ((start == path && start[0] == '~') || mkdir(path, 0777) || chddir(path)) {
*s = c;
chddir(oldpwd);
return 1;
}
}

*s = c;
in:
while (*s == '/')
++s;
path = s;
}

chddir(oldpwd);
return 0;
}

/********************************************************************/
/* Create a temporary file */
/********************************************************************/
Expand Down Expand Up @@ -231,6 +239,18 @@ char *mktmp(const char *where)
#endif
return name;
}

/********************************************************************/
/* Change dir */
/********************************************************************/
int chddir(const char *path)
{
char *s = canonical(vsndup(NULL, 0, sz(path)), CANFLAG_NORESTART);
int res = chdir(s);
vsrm(s);
return res;
}

/********************************************************************/
int rmatch(const char *a, const char *b)
{
Expand Down Expand Up @@ -507,3 +527,60 @@ char *dequotevs(char *s)
vsrm(s);
return d;
}

/* Canonicalize file name: do ~ expansion */

char *canonical(char *n, int flags)
{
ptrdiff_t y = 0;
#ifndef __MSDOS__
ptrdiff_t x;
char *s;
if (!(flags & CANFLAG_NORESTART)) {
for (y = zlen(n); ; --y)
if (y <= 2) {
y = 0;
break;
} else if (n[y-2] == '/' && (n[y-1] == '/' || n[y-1] == '~')) {
y -= 1;
break;
}
}
if (n[y] == '~') {
for (x = y + 1; n[x] && n[x] != '/'; ++x) ;
if (n[x] == '/') {
if (x == y + 1) {
char *z;

s = getenv("HOME");
z = vsncpy(NULL, 0, sz(s));
z = vsncpy(z, sLEN(z), sz(n + x));
vsrm(n);
n = z;
y = 0;
} else {
struct passwd *passwd;

n[x] = 0;
passwd = getpwnam((n + y + 1));
n[x] = '/';
if (passwd) {
char *z = vsncpy(NULL, 0,
sz((passwd->pw_dir)));

z = vsncpy(z, sLEN(z), sz(n + x));
vsrm(n);
n = z;
y = 0;
}
}
}
}
#endif
if (y) {
char *z = vsncpy(NULL, 0, n + y, zlen(n + y));
vsrm(n);
return z;
} else
return n;
}
12 changes: 10 additions & 2 deletions joe/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ int mkpath(char *path);
*/
char *mktmp(const char *where);

/* Change drive and directory */
#define chddir chdir
/* Change drive and directory
* chdir doesn't seem to correctly handle changing to ~
* so chddir handles the ~, then calls chdir
*/
int chddir(const char* path);

/* int rmatch(char *pattern,char *string);
* Return true if string matches pattern
Expand Down Expand Up @@ -101,3 +104,8 @@ char *pwd(void);
char *simplify_prefix(const char *path);

char *dequotevs(char *path);

/* Canonicalize file name: do ~ expansion */
char *canonical(char *s, int flags);

#define CANFLAG_NORESTART 1 /* Support path restart feature */
2 changes: 1 addition & 1 deletion joe/vs.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ sELEMENT *vsncpy(sELEMENT *vary, ptrdiff_t pos, const sELEMENT *array, ptrdiff_t
return vary;
}

sELEMENT *vsndup(sELEMENT *vary, ptrdiff_t pos, sELEMENT *array, ptrdiff_t len)
sELEMENT *vsndup(sELEMENT *vary, ptrdiff_t pos, const sELEMENT *array, ptrdiff_t len)
{
ptrdiff_t olen = sLEN(vary), x;

Expand Down
2 changes: 1 addition & 1 deletion joe/vs.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ sELEMENT *vsncpy(sELEMENT *vary, ptrdiff_t pos, const sELEMENT *array, ptrdiff_t
* 'pos'. 'array' can be a char array since its length is passed separately. A
* new array is created if 'vary' is 0.
*/
sELEMENT *vsndup(sELEMENT *vary, ptrdiff_t pos, sELEMENT *array, ptrdiff_t len);
sELEMENT *vsndup(sELEMENT *vary, ptrdiff_t pos, const sELEMENT *array, ptrdiff_t len);

/* sELEMENT *vsdup(sELEMENT *vary));
* Duplicate array. This is just a functionalized version of:
Expand Down