1339 lines
35 KiB
C
1339 lines
35 KiB
C
#include <cdk.h>
|
|
|
|
/*
|
|
* $Author: garbled $
|
|
* $Date: 2001/01/04 19:58:11 $
|
|
* $Revision: 1.1.1.1 $
|
|
*/
|
|
|
|
/*
|
|
* Declare file local prototypes.
|
|
*/
|
|
static BINDFN_PROTO(fselectAdjustScrollCB);
|
|
static BINDFN_PROTO(completeFilenameCB);
|
|
static BINDFN_PROTO(displayFileInfoCB);
|
|
static char *expandFilename (char *filename);
|
|
static void setPWD (CDKFSELECT *fselect);
|
|
|
|
/*
|
|
* Declare file local variables.
|
|
*/
|
|
extern char *GPasteBuffer;
|
|
|
|
DeclareCDKObjects(my_funcs,Fselect);
|
|
|
|
/*
|
|
* This creates a file selection widget.
|
|
*/
|
|
CDKFSELECT *newCDKFselect (CDKSCREEN *cdkscreen, int xplace, int yplace, int height, int width, char *title, char *label, chtype fieldAttribute, chtype fillerChar, chtype highlight, char *dAttribute, char *fAttribute, char *lAttribute, char *sAttribute, boolean Box, boolean shadow)
|
|
{
|
|
/* Set up some variables. */
|
|
CDKFSELECT *fselect = newCDKObject(CDKFSELECT, &my_funcs);
|
|
int parentWidth = getmaxx(cdkscreen->window);
|
|
int parentHeight = getmaxy(cdkscreen->window);
|
|
int boxWidth = width;
|
|
int boxHeight = height;
|
|
int xpos = xplace;
|
|
int ypos = yplace;
|
|
int entryWidth, x, labelLen, junk;
|
|
chtype *chtypeString;
|
|
|
|
/*
|
|
* If the height is a negative value, the height will
|
|
* be ROWS-height, otherwise, the height will be the
|
|
* given height.
|
|
*/
|
|
boxHeight = setWidgetDimension (parentHeight, height, 0);
|
|
|
|
/*
|
|
* If the width is a negative value, the width will
|
|
* be COLS-width, otherwise, the width will be the
|
|
* given width.
|
|
*/
|
|
boxWidth = setWidgetDimension (parentWidth, width, 0);
|
|
|
|
/* Rejustify the x and y positions if we need to. */
|
|
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
|
|
|
|
/* Make sure the box isn't too small. */
|
|
boxWidth = MAXIMUM (boxWidth, 15);
|
|
boxHeight = MAXIMUM (boxHeight, 6);
|
|
|
|
/* Make the file selector window. */
|
|
fselect->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
|
|
|
|
/* Is the window null? */
|
|
if (fselect->win == 0)
|
|
{
|
|
return (0);
|
|
}
|
|
keypad (fselect->win, TRUE);
|
|
|
|
/* Set some variables. */
|
|
ScreenOf(fselect) = cdkscreen;
|
|
fselect->parent = cdkscreen->window;
|
|
fselect->dirAttribute = copyChar (dAttribute);
|
|
fselect->fileAttribute = copyChar (fAttribute);
|
|
fselect->linkAttribute = copyChar (lAttribute);
|
|
fselect->sockAttribute = copyChar (sAttribute);
|
|
fselect->highlight = highlight;
|
|
fselect->fillerCharacter = fillerChar;
|
|
fselect->fieldAttribute = fieldAttribute;
|
|
fselect->boxHeight = boxHeight;
|
|
fselect->boxWidth = boxWidth;
|
|
fselect->fileCounter = 0;
|
|
fselect->pwd = 0;
|
|
fselect->exitType = vNEVER_ACTIVATED;
|
|
ObjOf(fselect)->box = Box;
|
|
fselect->shadow = shadow;
|
|
|
|
/* Zero out the contents of the directory listing. */
|
|
for (x=0; x < MAX_ITEMS; x++)
|
|
{
|
|
fselect->dirContents[x] = 0;
|
|
}
|
|
|
|
/* Get the present working directory. */
|
|
setPWD(fselect);
|
|
|
|
/* Get the contents of the current directory. */
|
|
setCDKFselectDirContents (fselect);
|
|
|
|
/* Create the entry field in the selector. */
|
|
chtypeString = char2Chtype (label, &labelLen, &junk);
|
|
freeChtype (chtypeString);
|
|
entryWidth = boxWidth - labelLen - 2;
|
|
fselect->entryField = newCDKEntry (cdkscreen,
|
|
getbegx(fselect->win),
|
|
getbegy(fselect->win),
|
|
title, label,
|
|
fieldAttribute, fillerChar,
|
|
vMIXED, entryWidth, 0, 512,
|
|
Box, FALSE);
|
|
|
|
/* Make sure the widget was created. */
|
|
if (fselect->entryField == 0)
|
|
{
|
|
/* Clean up. */
|
|
freeCharList (fselect->dirContents, MAX_ITEMS);
|
|
freeChar (fselect->pwd);
|
|
freeChar (fselect->dirAttribute);
|
|
freeChar (fselect->fileAttribute);
|
|
freeChar (fselect->linkAttribute);
|
|
freeChar (fselect->sockAttribute);
|
|
deleteCursesWindow (fselect->win);
|
|
return (0);
|
|
}
|
|
|
|
/* Set the lower left/right characters of the entry field. */
|
|
setCDKEntryLLChar (fselect->entryField, ACS_LTEE);
|
|
setCDKEntryLRChar (fselect->entryField, ACS_RTEE);
|
|
|
|
/* Define the callbacks for the entry field. */
|
|
bindCDKObject (vENTRY, fselect->entryField, KEY_UP, fselectAdjustScrollCB, fselect);
|
|
bindCDKObject (vENTRY, fselect->entryField, KEY_PPAGE, fselectAdjustScrollCB, fselect);
|
|
bindCDKObject (vENTRY, fselect->entryField, CONTROL('B'), fselectAdjustScrollCB, fselect);
|
|
bindCDKObject (vENTRY, fselect->entryField, KEY_DOWN, fselectAdjustScrollCB, fselect);
|
|
bindCDKObject (vENTRY, fselect->entryField, KEY_NPAGE, fselectAdjustScrollCB, fselect);
|
|
bindCDKObject (vENTRY, fselect->entryField, CONTROL('F'), fselectAdjustScrollCB, fselect);
|
|
bindCDKObject (vENTRY, fselect->entryField, KEY_TAB, completeFilenameCB, fselect);
|
|
bindCDKObject (vENTRY, fselect->entryField, CONTROL('^'), displayFileInfoCB, fselect);
|
|
|
|
/* Put the current working directory in the entry field. */
|
|
setCDKEntryValue (fselect->entryField, fselect->pwd);
|
|
|
|
/* Create the scrolling list in the selector. */
|
|
fselect->scrollField = newCDKScroll (cdkscreen,
|
|
getbegx(fselect->win),
|
|
getbegy(fselect->win) + (fselect->entryField)->titleLines + 2,
|
|
RIGHT,
|
|
boxHeight - (fselect->entryField)->titleLines - 2,
|
|
boxWidth,
|
|
0,
|
|
fselect->dirContents,
|
|
fselect->fileCounter,
|
|
NONUMBERS, fselect->highlight,
|
|
Box, FALSE);
|
|
|
|
/* Set the lower left/right characters of the entry field. */
|
|
setCDKScrollULChar (fselect->scrollField, ACS_LTEE);
|
|
setCDKScrollURChar (fselect->scrollField, ACS_RTEE);
|
|
|
|
/* Register this baby. */
|
|
registerCDKObject (cdkscreen, vFSELECT, fselect);
|
|
|
|
/* Return the file selector pointer. */
|
|
return (fselect);
|
|
}
|
|
|
|
/*
|
|
* This erases the file selector from the screen.
|
|
*/
|
|
static void _eraseCDKFselect (CDKOBJS *object)
|
|
{
|
|
CDKFSELECT * fselect = (CDKFSELECT *)object;
|
|
|
|
eraseCDKScroll (fselect->scrollField);
|
|
eraseCDKEntry (fselect->entryField);
|
|
eraseCursesWindow (fselect->win);
|
|
}
|
|
|
|
/*
|
|
* This moves the fselect field to the given location.
|
|
*/
|
|
static void _moveCDKFselect (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
|
|
{
|
|
CDKFSELECT *fselect = (CDKFSELECT *)object;
|
|
|
|
/*
|
|
* If this is a relative move, then we will adjust where we want
|
|
* to move to.
|
|
*/
|
|
if (relative)
|
|
{
|
|
xplace += getbegx(fselect->win);
|
|
yplace += getbegy(fselect->win);
|
|
}
|
|
|
|
/* Adjust the window if we need to. */
|
|
alignxy (WindowOf(fselect), &xplace, &yplace, fselect->boxWidth, fselect->boxHeight);
|
|
|
|
/* Move the window to the new location. */
|
|
moveCursesWindow(fselect->win, xplace, yplace);
|
|
|
|
/* Move the sub-widgets. */
|
|
/* XXXX */
|
|
moveCDKEntry (fselect->entryField, xplace, yplace, relative, FALSE);
|
|
moveCDKScroll (fselect->scrollField, xplace, yplace, relative, FALSE);
|
|
|
|
/* Redraw the window, if they asked for it. */
|
|
if (refresh_flag)
|
|
{
|
|
drawCDKFselect (fselect, ObjOf(fselect)->box);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This draws the file selector widget.
|
|
*/
|
|
static void _drawCDKFselect (CDKOBJS *object, boolean Box GCC_UNUSED)
|
|
{
|
|
CDKFSELECT *fselect = (CDKFSELECT *)object;
|
|
|
|
/* Draw in the entry field. */
|
|
drawCDKEntry (fselect->entryField, ObjOf(fselect->entryField)->box);
|
|
|
|
/* Draw in the scroll field. */
|
|
drawCDKScroll (fselect->scrollField, ObjOf(fselect->scrollField)->box);
|
|
}
|
|
|
|
/*
|
|
* This means you want to use the given file selector. It takes input
|
|
* from the keyboard, and when it's done, it fills the entry info
|
|
* element of the structure with what was typed.
|
|
*/
|
|
char *activateCDKFselect (CDKFSELECT *fselect, chtype *actions)
|
|
{
|
|
/* Declare local variables. */
|
|
chtype input = 0;
|
|
char *ret = 0;
|
|
|
|
/* Draw the widget. */
|
|
drawCDKFselect (fselect, ObjOf(fselect)->box);
|
|
|
|
/* Check if 'actions' is null. */
|
|
if (actions == 0)
|
|
{
|
|
for (;;)
|
|
{
|
|
/* Get the input. */
|
|
wrefresh (fselect->entryField->fieldWin);
|
|
input = wgetch (fselect->entryField->fieldWin);
|
|
|
|
/* Inject the character into the widget. */
|
|
ret = injectCDKFselect (fselect, input);
|
|
if (fselect->exitType != vEARLY_EXIT)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int length = chlen (actions);
|
|
int x =0;
|
|
|
|
/* Inject each character one at a time. */
|
|
for (x=0; x < length; x++)
|
|
{
|
|
ret = injectCDKFselect (fselect, actions[x]);
|
|
if (fselect->exitType != vEARLY_EXIT)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Set the exit type and exit. */
|
|
fselect->exitType = vEARLY_EXIT;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* This injects a single character into the file selector.
|
|
*/
|
|
char *injectCDKFselect (CDKFSELECT *fselect, chtype input)
|
|
{
|
|
/* Declare local variables. */
|
|
char *filename;
|
|
boolean file;
|
|
|
|
/* Let the user play. */
|
|
filename = injectCDKEntry (fselect->entryField, input);
|
|
|
|
/* Copy the entry field exitType to the fileselector. */
|
|
fselect->exitType = fselect->entryField->exitType;
|
|
|
|
/* If we exited early, make sure we don't interpret it as a file. */
|
|
if (fselect->exitType == vEARLY_EXIT
|
|
|| fselect->exitType == vESCAPE_HIT)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* Can we change into the directory? */
|
|
file = chdir (filename);
|
|
chdir (fselect->pwd);
|
|
|
|
/* If it's not a directory, return the filename. */
|
|
if (file != 0 && errno == ENOTDIR)
|
|
{
|
|
/* It's a regular file, create the full path. */
|
|
fselect->pathname = copyChar (filename);
|
|
|
|
/* Return the complete pathname. */
|
|
return (fselect->pathname);
|
|
}
|
|
else
|
|
{
|
|
/* Set the file selector information. */
|
|
setCDKFselect (fselect, filename,
|
|
fselect->fieldAttribute, fselect->fillerCharacter,
|
|
fselect->highlight,
|
|
fselect->dirAttribute, fselect->fileAttribute,
|
|
fselect->linkAttribute, fselect->sockAttribute,
|
|
ObjOf(fselect)->box);
|
|
|
|
/* Redraw the scrolling list. */
|
|
drawCDKScroll (fselect->scrollField, ObjOf(fselect->scrollField)->box);
|
|
}
|
|
|
|
/* Set the exit type and return a null pointer. */
|
|
fselect->exitType = vEARLY_EXIT;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* This function sets the information inside the file selector.
|
|
*/
|
|
void setCDKFselect (CDKFSELECT *fselect, char *directory, chtype fieldAttrib, chtype filler, chtype highlight, char *dirAttribute, char *fileAttribute, char *linkAttribute, char *sockAttribute, boolean Box GCC_UNUSED)
|
|
{
|
|
/* Declare local variables. */
|
|
CDKSCROLL *fscroll = fselect->scrollField;
|
|
CDKENTRY *fentry = fselect->entryField;
|
|
char *tempDir = 0;
|
|
char *mesg[10], newDirectory[2000], temp[100];
|
|
int ret;
|
|
|
|
/* Keep the info sent to us. */
|
|
fselect->fieldAttribute = fieldAttrib;
|
|
fselect->fillerCharacter = filler;
|
|
fselect->highlight = highlight;
|
|
strcpy (newDirectory, directory);
|
|
|
|
/* Set the attributes of the entry field/scrolling list. */
|
|
setCDKEntryFillerChar (fentry, filler);
|
|
setCDKScrollHighlight (fscroll, highlight);
|
|
|
|
/* Only do the directory stuff if the directory is not null. */
|
|
if (directory != 0)
|
|
{
|
|
/* Try to expand the directory if it starts with a ~ */
|
|
if (directory[0] == '~')
|
|
{
|
|
tempDir = expandFilename (directory);
|
|
if (tempDir != 0)
|
|
{
|
|
strcpy (newDirectory, tempDir);
|
|
freeChar (tempDir);
|
|
}
|
|
}
|
|
|
|
/* Change directories. */
|
|
ret = chdir (newDirectory);
|
|
if (ret != 0)
|
|
{
|
|
/* Beep at them. */
|
|
Beep();
|
|
|
|
/* Couldn't get into the directory, pop up a little message. */
|
|
sprintf (temp, "<C>Could not change into %s", newDirectory);
|
|
mesg[0] = copyChar (temp);
|
|
|
|
#ifdef HAVE_STRERROR
|
|
sprintf (temp, "<C></U>%s", strerror(errno));
|
|
mesg[1] = copyChar (temp);
|
|
#else
|
|
mesg[1] = copyChar ("<C></U>Unknown reason.");
|
|
#endif
|
|
|
|
mesg[2] = copyChar (" ");
|
|
mesg[3] = copyChar ("<C>Press Any Key To Continue.");
|
|
|
|
/* Pop Up a message. */
|
|
popupLabel (ScreenOf(fselect), mesg, 4);
|
|
|
|
/* Clean up some memory. */
|
|
freeCharList (mesg, 4);
|
|
|
|
/* Get out of here. */
|
|
eraseCDKFselect (fselect);
|
|
drawCDKFselect (fselect, ObjOf(fselect)->box);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* If the information coming in is the same as the information
|
|
* that is already there, there is no need to destroy it.
|
|
*/
|
|
if (fselect->pwd != directory)
|
|
{
|
|
setPWD(fselect);
|
|
}
|
|
if (fselect->fileAttribute != fileAttribute)
|
|
{
|
|
/* Remove the old pointer and set the new value. */
|
|
freeChar (fselect->fileAttribute);
|
|
fselect->fileAttribute = copyChar (fileAttribute);
|
|
}
|
|
if (fselect->dirAttribute != dirAttribute)
|
|
{
|
|
/* Remove the old pointer and set the new value. */
|
|
freeChar (fselect->dirAttribute);
|
|
fselect->dirAttribute = copyChar (dirAttribute);
|
|
}
|
|
if (fselect->linkAttribute != linkAttribute)
|
|
{
|
|
/* Remove the old pointer and set the new value. */
|
|
freeChar (fselect->linkAttribute);
|
|
fselect->linkAttribute = copyChar (linkAttribute);
|
|
}
|
|
if (fselect->sockAttribute != sockAttribute)
|
|
{
|
|
/* Remove the old pointer and set the new value. */
|
|
freeChar (fselect->sockAttribute);
|
|
fselect->sockAttribute = copyChar (sockAttribute);
|
|
}
|
|
|
|
/* Set the contents of the entry field. */
|
|
setCDKEntryValue (fentry, fselect->pwd);
|
|
drawCDKEntry (fentry, ObjOf(fentry)->box);
|
|
|
|
/* Get the directory contents. */
|
|
if (setCDKFselectDirContents (fselect) == 0)
|
|
{
|
|
Beep();
|
|
return;
|
|
}
|
|
|
|
/* Set the values in the scrolling list. */
|
|
setCDKScrollItems (fscroll,
|
|
fselect->dirContents,
|
|
fselect->fileCounter,
|
|
FALSE);
|
|
}
|
|
|
|
/*
|
|
* This creates a list of the files in the current directory.
|
|
*/
|
|
int setCDKFselectDirContents (CDKFSELECT *fselect)
|
|
{
|
|
/* Declare local variables. */
|
|
struct stat fileStat;
|
|
char *dirList[MAX_ITEMS];
|
|
char temp[200], mode;
|
|
int fileCount;
|
|
int x = 0;
|
|
|
|
/* Get the directory contents. */
|
|
fileCount = getDirectoryContents (fselect->pwd, dirList, MAX_ITEMS);
|
|
if (fileCount == -1)
|
|
{
|
|
/* We couldn't read the directory. Return. */
|
|
return 0;
|
|
}
|
|
|
|
/* Clean out the old directory list. */
|
|
freeCharList (fselect->dirContents, fselect->fileCounter);
|
|
fselect->fileCounter = fileCount;
|
|
|
|
/* Set the properties of the files. */
|
|
for (x=0; x < fselect->fileCounter; x++)
|
|
{
|
|
/* Stat the file. */
|
|
lstat (dirList[x], &fileStat);
|
|
|
|
/* Check the mode. */
|
|
mode = ' ';
|
|
if (((fileStat.st_mode & S_IXUSR) != 0) ||
|
|
((fileStat.st_mode & S_IXGRP) != 0) ||
|
|
((fileStat.st_mode & S_IXOTH) != 0))
|
|
{
|
|
mode = '*';
|
|
}
|
|
|
|
/* Create the filename. */
|
|
switch (mode2Filetype(fileStat.st_mode)) {
|
|
case 'l':
|
|
sprintf (temp, "%s%s@", fselect->linkAttribute, dirList[x]);
|
|
break;
|
|
case '@':
|
|
sprintf (temp, "%s%s&", fselect->sockAttribute, dirList[x]);
|
|
break;
|
|
case '-':
|
|
sprintf (temp, "%s%s%c", fselect->fileAttribute, dirList[x], mode);
|
|
break;
|
|
case 'd':
|
|
sprintf (temp, "%s%s/", fselect->dirAttribute, dirList[x]);
|
|
break;
|
|
default:
|
|
sprintf (temp, "%s%c", dirList[x], mode);
|
|
break;
|
|
}
|
|
fselect->dirContents[x] = copyChar (temp);
|
|
|
|
/* Free up this piece of memory. */
|
|
freeChar (dirList[x]);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
char **getCDKFselectDirContents (CDKFSELECT *fselect, int *count)
|
|
{
|
|
(*count) = fselect->fileCounter;
|
|
return fselect->dirContents;
|
|
}
|
|
|
|
/*
|
|
* This sets the current directory of the file selector.
|
|
*/
|
|
int setCDKFselectDirectory (CDKFSELECT *fselect, char *directory)
|
|
{
|
|
/* Declare local variables. */
|
|
CDKENTRY *fentry = fselect->entryField;
|
|
CDKSCROLL *fscroll = fselect->scrollField;
|
|
int ret;
|
|
|
|
/*
|
|
* If the directory supplied is the same as what is already
|
|
* there, return.
|
|
*/
|
|
if (fselect->pwd == directory)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
/* Try to chdir into the given directory. */
|
|
ret = chdir (directory);
|
|
if (ret != 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
setPWD(fselect);
|
|
|
|
/* Set the contents of the entry field. */
|
|
setCDKEntryValue (fentry, fselect->pwd);
|
|
drawCDKEntry (fentry, ObjOf(fentry)->box);
|
|
|
|
/* Get the directory contents. */
|
|
if (setCDKFselectDirContents (fselect) == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* Set the values in the scrolling list. */
|
|
setCDKScrollItems (fscroll, fselect->dirContents,
|
|
fselect->fileCounter,
|
|
FALSE);
|
|
return 1;
|
|
}
|
|
char *getCDKFselectDirectory (CDKFSELECT *fselect)
|
|
{
|
|
return fselect->pwd;
|
|
}
|
|
/*
|
|
* This sets the filler character of the entry field.
|
|
*/
|
|
void setCDKFselectFillerChar (CDKFSELECT *fselect, chtype filler)
|
|
{
|
|
CDKENTRY *fentry = fselect->entryField;
|
|
fselect->fillerCharacter = filler;
|
|
setCDKEntryFillerChar (fentry, filler);
|
|
}
|
|
chtype getCDKFselectFillerChar (CDKFSELECT *fselect)
|
|
{
|
|
return fselect->fillerCharacter;
|
|
}
|
|
|
|
/*
|
|
* This sets the highlight bar of the scrolling list.
|
|
*/
|
|
void setCDKFselectHighlight (CDKFSELECT *fselect, chtype highlight)
|
|
{
|
|
CDKSCROLL *fscroll = (CDKSCROLL *)fselect->scrollField;
|
|
fselect->highlight = highlight;
|
|
setCDKScrollHighlight (fscroll, highlight);
|
|
|
|
}
|
|
chtype getCDKFselectHighlight (CDKFSELECT *fselect)
|
|
{
|
|
return fselect->highlight;
|
|
}
|
|
|
|
/*
|
|
* This sets the attribute of the directory attribute in the
|
|
* scrolling list.
|
|
*/
|
|
void setCDKFselectDirAttribute (CDKFSELECT *fselect, char *attribute)
|
|
{
|
|
/* Make sure they are not one in the same. */
|
|
if (fselect->dirAttribute == attribute)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Clean out the old attribute, and set the new. */
|
|
freeChar (fselect->dirAttribute);
|
|
fselect->dirAttribute = copyChar (attribute);
|
|
|
|
/*
|
|
* We need to reset the contents of the scrolling
|
|
* list using the new attribute.
|
|
*/
|
|
setCDKFselectDirContents (fselect);
|
|
}
|
|
char *getCDKFselectDirAttribute (CDKFSELECT *fselect)
|
|
{
|
|
return fselect->dirAttribute;
|
|
}
|
|
|
|
/*
|
|
* This sets the attribute of the link attribute in the
|
|
* scrolling list.
|
|
*/
|
|
void setCDKFselectLinkAttribute (CDKFSELECT *fselect, char *attribute)
|
|
{
|
|
/* Make sure they are not one in the same. */
|
|
if (fselect->linkAttribute == attribute)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Clean out the old attribute, and set the new. */
|
|
freeChar (fselect->linkAttribute);
|
|
fselect->linkAttribute = copyChar (attribute);
|
|
|
|
/*
|
|
* We need to reset the contents of the scrolling
|
|
* list using the new attribute.
|
|
*/
|
|
setCDKFselectDirContents (fselect);
|
|
}
|
|
char *getCDKFselectLinkAttribute (CDKFSELECT *fselect)
|
|
{
|
|
return fselect->linkAttribute;
|
|
}
|
|
|
|
/*
|
|
* This sets the attribute of the link attribute in the
|
|
* scrolling list.
|
|
*/
|
|
void setCDKFselectSocketAttribute (CDKFSELECT *fselect, char *attribute)
|
|
{
|
|
/* Make sure they are not one in the same. */
|
|
if (fselect->sockAttribute == attribute)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Clean out the old attribute, and set the new. */
|
|
freeChar (fselect->sockAttribute);
|
|
fselect->sockAttribute = copyChar (attribute);
|
|
|
|
/*
|
|
* We need to reset the contents of the scrolling
|
|
* list using the new attribute.
|
|
*/
|
|
setCDKFselectDirContents (fselect);
|
|
}
|
|
char *getCDKFselectSocketAttribute (CDKFSELECT *fselect)
|
|
{
|
|
return fselect->sockAttribute;
|
|
}
|
|
|
|
/*
|
|
* This sets the attribute of the link attribute in the
|
|
* scrolling list.
|
|
*/
|
|
void setCDKFselectFileAttribute (CDKFSELECT *fselect, char *attribute)
|
|
{
|
|
/* Make sure they are not one in the same. */
|
|
if (fselect->fileAttribute == attribute)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Clean out the old attribute, and set the new. */
|
|
freeChar (fselect->fileAttribute);
|
|
fselect->fileAttribute = copyChar (attribute);
|
|
|
|
/*
|
|
* We need to reset the contents of the scrolling
|
|
* list using the new attribute.
|
|
*/
|
|
setCDKFselectDirContents (fselect);
|
|
}
|
|
char *getCDKFselectFileAttribute (CDKFSELECT *fselect)
|
|
{
|
|
return fselect->fileAttribute;
|
|
}
|
|
|
|
/*
|
|
* This sets the box attribute of the widget.
|
|
*/
|
|
void setCDKFselectBox (CDKFSELECT *fselect, boolean Box)
|
|
{
|
|
ObjOf(fselect)->box = Box;
|
|
}
|
|
boolean getCDKFselectBox (CDKFSELECT *fselect)
|
|
{
|
|
return ObjOf(fselect)->box;
|
|
}
|
|
|
|
/*
|
|
* These functions set the drawing characters of the widget.
|
|
*/
|
|
void setCDKFselectULChar (CDKFSELECT *fselect, chtype character)
|
|
{
|
|
setCDKEntryULChar (fselect->entryField, character);
|
|
}
|
|
void setCDKFselectURChar (CDKFSELECT *fselect, chtype character)
|
|
{
|
|
setCDKEntryURChar (fselect->entryField, character);
|
|
}
|
|
void setCDKFselectLLChar (CDKFSELECT *fselect, chtype character)
|
|
{
|
|
setCDKScrollLLChar (fselect->scrollField, character);
|
|
}
|
|
void setCDKFselectLRChar (CDKFSELECT *fselect, chtype character)
|
|
{
|
|
setCDKScrollLRChar (fselect->scrollField, character);
|
|
}
|
|
void setCDKFselectVerticalChar (CDKFSELECT *fselect, chtype character)
|
|
{
|
|
setCDKEntryVerticalChar (fselect->entryField, character);
|
|
setCDKScrollVerticalChar (fselect->scrollField, character);
|
|
}
|
|
void setCDKFselectHorizontalChar (CDKFSELECT *fselect, chtype character)
|
|
{
|
|
setCDKEntryHorizontalChar (fselect->entryField, character);
|
|
setCDKScrollHorizontalChar (fselect->scrollField, character);
|
|
}
|
|
void setCDKFselectBoxAttribute (CDKFSELECT *fselect, chtype character)
|
|
{
|
|
setCDKEntryBoxAttribute (fselect->entryField, character);
|
|
setCDKScrollBoxAttribute (fselect->scrollField, character);
|
|
}
|
|
|
|
/*
|
|
* This sets the background color of the widget.
|
|
*/
|
|
void setCDKFselectBackgroundColor (CDKFSELECT *fselect, char *color)
|
|
{
|
|
if (color != 0)
|
|
{
|
|
setCDKEntryBackgroundColor (fselect->entryField, color);
|
|
setCDKScrollBackgroundColor (fselect->scrollField, color);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* This destroys the file selector.
|
|
*/
|
|
void destroyCDKFselect (CDKFSELECT *fselect)
|
|
{
|
|
/* Erase the file selector. */
|
|
eraseCDKFselect (fselect);
|
|
|
|
/* Free up the character pointers. */
|
|
freeChar (fselect->pwd);
|
|
freeChar (fselect->pathname);
|
|
freeChar (fselect->dirAttribute);
|
|
freeChar (fselect->fileAttribute);
|
|
freeChar (fselect->linkAttribute);
|
|
freeChar (fselect->sockAttribute);
|
|
freeCharList (fselect->dirContents, fselect->fileCounter);
|
|
|
|
/* Destroy the other Cdk objects. */
|
|
destroyCDKScroll (fselect->scrollField);
|
|
destroyCDKEntry (fselect->entryField);
|
|
|
|
/* Free up the window pointers. */
|
|
deleteCursesWindow (fselect->win);
|
|
|
|
/* Unregister the object. */
|
|
unregisterCDKObject (vFSELECT, fselect);
|
|
|
|
/* Free up the object pointer. */
|
|
free (fselect);
|
|
}
|
|
|
|
/*
|
|
********************************
|
|
* Callback functions.
|
|
********************************
|
|
*/
|
|
|
|
/*
|
|
* This is a callback to the scrolling list which displays information
|
|
* about the current file. (and the whole directory as well)
|
|
*/
|
|
static void displayFileInfoCB (EObjectType objectType GCC_UNUSED, void *object, void *clientData, chtype key GCC_UNUSED)
|
|
{
|
|
/* Declare local variables. */
|
|
CDKENTRY *entry = (CDKENTRY *)object;
|
|
CDKFSELECT *fselect = (CDKFSELECT *)clientData;
|
|
CDKLABEL *infoLabel;
|
|
struct stat fileStat;
|
|
struct passwd *pwEnt;
|
|
struct group *grEnt;
|
|
char *filename;
|
|
char *filetype;
|
|
char *mesg[10];
|
|
char temp[100];
|
|
char stringMode[15];
|
|
int len;
|
|
int intMode;
|
|
|
|
/* Get the file name. */
|
|
filename = fselect->entryField->info;
|
|
|
|
/* Get specific information about the files. */
|
|
lstat (filename, &fileStat);
|
|
|
|
/* Determine the file type. */
|
|
switch (mode2Filetype(fileStat.st_mode)) {
|
|
case 'l':
|
|
filetype = "Symbolic Link";
|
|
break;
|
|
case '@':
|
|
filetype = "Socket";
|
|
break;
|
|
case '-':
|
|
filetype = "Regular File";
|
|
break;
|
|
case 'd':
|
|
filetype = "Directory";
|
|
break;
|
|
case 'c':
|
|
filetype = "Character Device";
|
|
break;
|
|
case 'b':
|
|
filetype = "Block Device";
|
|
break;
|
|
case '&':
|
|
filetype = "FIFO Device";
|
|
break;
|
|
default:
|
|
filetype = "Unknown";
|
|
break;
|
|
}
|
|
|
|
/* Get the user name and group name. */
|
|
pwEnt = getpwuid (fileStat.st_uid);
|
|
grEnt = getgrgid (fileStat.st_gid);
|
|
|
|
/* Convert the mode_t type to both string and int. */
|
|
intMode = mode2Char (stringMode, fileStat.st_mode);
|
|
|
|
/* Create the message. */
|
|
sprintf (temp, "Directory : </U>%s", fselect->pwd);
|
|
mesg[0] = copyChar (temp);
|
|
|
|
sprintf (temp, "Filename : </U>%s", filename);
|
|
mesg[1] = copyChar (temp);
|
|
|
|
sprintf (temp, "Owner : </U>%s<!U> (%d)", pwEnt->pw_name, (int)fileStat.st_uid);
|
|
mesg[2] = copyChar (temp);
|
|
|
|
sprintf (temp, "Group : </U>%s<!U> (%d)", grEnt->gr_name, (int)fileStat.st_gid);
|
|
mesg[3] = copyChar (temp);
|
|
|
|
sprintf (temp, "Permissions: </U>%s<!U> (%o)", stringMode, intMode);
|
|
mesg[4] = copyChar (temp);
|
|
|
|
sprintf (temp, "Size : </U>%ld<!U> bytes", (long) fileStat.st_size);
|
|
mesg[5] = copyChar (temp);
|
|
|
|
sprintf (temp, "Last Access: </U>%s", ctime (&fileStat.st_atime));
|
|
len = (int)strlen (temp);
|
|
temp[len] = '\0'; temp[len-1] = '\0';
|
|
mesg[6] = copyChar (temp);
|
|
|
|
sprintf (temp, "Last Change: </U>%s", ctime (&fileStat.st_ctime));
|
|
len = (int)strlen (temp);
|
|
temp[len] = '\0'; temp[len-1] = '\0';
|
|
mesg[7] = copyChar (temp);
|
|
|
|
sprintf (temp, "File Type : </U>%s", filetype);
|
|
mesg[8] = copyChar (temp);
|
|
|
|
/* Create the pop up label. */
|
|
infoLabel = newCDKLabel (entry->obj.screen, CENTER, CENTER,
|
|
mesg, 9, TRUE, FALSE);
|
|
drawCDKLabel (infoLabel, TRUE);
|
|
waitCDKLabel (infoLabel, 0);
|
|
|
|
/* Clean up some memory. */
|
|
destroyCDKLabel (infoLabel);
|
|
freeCharList (mesg, 9);
|
|
|
|
/* Redraw the file selector. */
|
|
drawCDKFselect (fselect, ObjOf(fselect)->box);
|
|
}
|
|
|
|
/*
|
|
* This tries to complete the filename.
|
|
*/
|
|
static void completeFilenameCB (EObjectType objectType GCC_UNUSED, void *object GCC_UNUSED, void *clientData, chtype key GCC_UNUSED)
|
|
{
|
|
CDKFSELECT *fselect = (CDKFSELECT *)clientData;
|
|
CDKSCROLL *scrollp = (CDKSCROLL *)fselect->scrollField;
|
|
CDKENTRY *entry = (CDKENTRY *)fselect->entryField;
|
|
char *filename = copyChar (entry->info);
|
|
char *basename = baseName (filename);
|
|
char *dirname = dirName (filename);
|
|
char *dirPWD = dirName (fselect->pwd);
|
|
char *basePWD = baseName (fselect->pwd);
|
|
char *newFilename = 0;
|
|
chtype *tempChtype = 0;
|
|
char *tempChar = 0;
|
|
int filenameLen = 0;
|
|
int currentIndex = 0;
|
|
int matches = 0;
|
|
int baseChars = 0;
|
|
int secondaryMatches = 0;
|
|
int isDirectory = 0;
|
|
char *list[MAX_ITEMS], temp[1000];
|
|
int Index, pos, ret, j, j2, x;
|
|
int difference, absoluteDifference;
|
|
|
|
/* Make sure the filename is not null. */
|
|
if (filename == 0)
|
|
{
|
|
Beep();
|
|
return;
|
|
}
|
|
filenameLen = (int)strlen (filename);
|
|
|
|
/* If the filename length is equal to zero, just leave. */
|
|
if (filenameLen == 0)
|
|
{
|
|
Beep();
|
|
return;
|
|
}
|
|
|
|
/* Try to expand the filename if it starts with a ~ */
|
|
if (filename[0] == '~')
|
|
{
|
|
newFilename = expandFilename (filename);
|
|
if (newFilename != 0)
|
|
{
|
|
freeChar (filename);
|
|
filename = newFilename;
|
|
setCDKEntryValue (entry, filename);
|
|
drawCDKEntry (entry, ObjOf(entry)->box);
|
|
}
|
|
}
|
|
|
|
/* Make sure we can change into the directory. */
|
|
isDirectory = chdir (filename);
|
|
chdir (fselect->pwd);
|
|
|
|
/* If we can, change into the directory. */
|
|
if (isDirectory == 0)
|
|
{
|
|
/*
|
|
* The basenames of both the present working directory and
|
|
* the basename of the filename are different. The filename
|
|
* provided is a directory; therefore we should chdir into
|
|
* it and reload the file selector.
|
|
*/
|
|
setCDKFselect (fselect, filename,
|
|
fselect->fieldAttribute, fselect->fillerCharacter,
|
|
fselect->highlight,
|
|
fselect->dirAttribute, fselect->fileAttribute,
|
|
fselect->linkAttribute, fselect->sockAttribute,
|
|
ObjOf(fselect)->box);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* The basenames of both the present working directory and
|
|
* the basename of the filename are different. The filename
|
|
* provided is a file; therefore we should chdir into the
|
|
* basename of the file and reload the file selector.
|
|
* Then we should continue to try to complete the filename.
|
|
* (which is done below)
|
|
*/
|
|
setCDKFselect (fselect, dirname,
|
|
fselect->fieldAttribute, fselect->fillerCharacter,
|
|
fselect->highlight,
|
|
fselect->dirAttribute, fselect->fileAttribute,
|
|
fselect->linkAttribute, fselect->sockAttribute,
|
|
ObjOf(fselect)->box);
|
|
|
|
/*
|
|
* Set the entry field with the filename so the current
|
|
* filename selection shows up.
|
|
*/
|
|
setCDKEntryValue (entry, filename);
|
|
drawCDKEntry (entry, ObjOf(entry)->box);
|
|
}
|
|
|
|
/* Clean up our pointers. */
|
|
freeChar (basename);
|
|
freeChar (dirname);
|
|
freeChar (dirPWD);
|
|
freeChar (basePWD);
|
|
|
|
/* Create the file list. */
|
|
for (x=0; x < fselect->fileCounter; x++)
|
|
{
|
|
/* We need to remove the special characters from the filenames. */
|
|
tempChtype = char2Chtype (fselect->dirContents[x], &j, &j2);
|
|
tempChar = chtype2Char (tempChtype);
|
|
|
|
/* Create the pathname. */
|
|
if (strcmp (fselect->pwd, "/") == 0)
|
|
{
|
|
sprintf (temp, "/%s", tempChar);
|
|
}
|
|
else
|
|
{
|
|
sprintf (temp, "%s/%s", fselect->pwd, tempChar);
|
|
}
|
|
list[x] = copyChar (temp);
|
|
|
|
/* Clean up. */
|
|
freeChtype (tempChtype);
|
|
freeChar (tempChar);
|
|
}
|
|
|
|
/* Look for a unique filename match. */
|
|
Index = searchList (list, fselect->fileCounter, filename);
|
|
|
|
/* If the index is less than zero, return we didn't find a match. */
|
|
if (Index < 0)
|
|
{
|
|
/* Clean up. */
|
|
freeCharList (list, fselect->fileCounter);
|
|
freeChar (filename);
|
|
Beep();
|
|
return;
|
|
}
|
|
|
|
/* Create the filename of the found file. */
|
|
sprintf (temp, "%s", list[Index]);
|
|
temp[(int)strlen(temp)-1] = '\0';
|
|
|
|
/* Did we find the last file in the list? */
|
|
if (Index == fselect->fileCounter)
|
|
{
|
|
/* Set the filename in the entry field. */
|
|
setCDKEntryValue (entry, list[Index]);
|
|
drawCDKEntry (entry, ObjOf(entry)->box);
|
|
|
|
/* Clean up. */
|
|
freeCharList (list, fselect->fileCounter);
|
|
freeChar (filename);
|
|
return;
|
|
}
|
|
|
|
/* Move to the current item in the scrolling list. */
|
|
difference = Index - scrollp->currentItem;
|
|
absoluteDifference = abs (difference);
|
|
if (difference < 0)
|
|
{
|
|
for (x=0; x < absoluteDifference; x++)
|
|
{
|
|
injectCDKScroll (scrollp, KEY_UP);
|
|
}
|
|
}
|
|
else if (difference > 0)
|
|
{
|
|
for (x=0; x < absoluteDifference; x++)
|
|
{
|
|
injectCDKScroll (scrollp, KEY_DOWN);
|
|
}
|
|
}
|
|
drawCDKScroll (scrollp, ObjOf(scrollp)->box);
|
|
|
|
/* Ok, we found a match, is the next item similar? */
|
|
ret = strncmp (list[Index + 1], filename, filenameLen);
|
|
if (ret == 0)
|
|
{
|
|
currentIndex = Index;
|
|
baseChars = filenameLen;
|
|
matches = 0;
|
|
pos = 0;
|
|
|
|
/* Determine the number of files which match. */
|
|
while (currentIndex < fselect->fileCounter)
|
|
{
|
|
if (list[currentIndex] != 0)
|
|
{
|
|
if (strncmp (list[currentIndex], filename, filenameLen) == 0)
|
|
{
|
|
matches++;
|
|
}
|
|
}
|
|
currentIndex++;
|
|
}
|
|
|
|
/* Start looking for the common base characters. */
|
|
for (;;)
|
|
{
|
|
secondaryMatches = 0;
|
|
for (x=Index; x < Index + matches; x++)
|
|
{
|
|
if (list[Index][baseChars] == list[x][baseChars])
|
|
{
|
|
secondaryMatches++;
|
|
}
|
|
}
|
|
|
|
if (secondaryMatches != matches)
|
|
{
|
|
Beep();
|
|
break;
|
|
}
|
|
|
|
/* Inject the character into the entry field. */
|
|
injectCDKEntry (fselect->entryField, list[Index][baseChars]);
|
|
baseChars++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Set the entry field with the found item. */
|
|
setCDKEntryValue (entry, temp);
|
|
drawCDKEntry (entry, ObjOf(entry)->box);
|
|
}
|
|
|
|
/* Clean up. */
|
|
freeCharList (list, fselect->fileCounter);
|
|
freeChar (filename);
|
|
}
|
|
|
|
/*
|
|
* This allows the user to delete a file.
|
|
*/
|
|
void deleteFileCB (EObjectType objectType GCC_UNUSED, void *object, void *clientData)
|
|
{
|
|
/* Declare local variables. */
|
|
CDKSCROLL *fscroll = (CDKSCROLL *)object;
|
|
CDKFSELECT *fselect = (CDKFSELECT *)clientData;
|
|
char *buttons[] = {"No", "Yes"};
|
|
CDKDIALOG *question;
|
|
char *mesg[10], *filename, temp[100];
|
|
|
|
/* Get the filename which is to be deleted. */
|
|
filename = chtype2Char (fscroll->item[fscroll->currentItem]);
|
|
filename[(int)strlen(filename)-1] = '\0';
|
|
|
|
/* Create the dialog message. */
|
|
mesg[0] = "<C>Are you sure you want to delete the file:";
|
|
sprintf (temp, "<C></U>%s?", filename); mesg[1] = copyChar (temp);
|
|
|
|
/* Create the dialog box. */
|
|
question = newCDKDialog (ScreenOf(fselect), CENTER, CENTER,
|
|
mesg, 2, buttons, 2, A_REVERSE,
|
|
TRUE, TRUE, FALSE);
|
|
freeCharList (mesg, 2);
|
|
|
|
/* If the said yes then try to nuke it. */
|
|
if (activateCDKDialog (question, 0) == 1)
|
|
{
|
|
/* If we were successful, reload the scrolling list. */
|
|
if (unlink (filename) == 0)
|
|
{
|
|
/* Set the file selector information. */
|
|
setCDKFselect (fselect, fselect->pwd,
|
|
fselect->fieldAttribute, fselect->fillerCharacter, fselect->highlight,
|
|
fselect->dirAttribute, fselect->fileAttribute,
|
|
fselect->linkAttribute, fselect->sockAttribute,
|
|
ObjOf(fselect)->box);
|
|
}
|
|
else
|
|
{
|
|
/* Pop up a message. */
|
|
#ifdef HAVE_STRERROR
|
|
sprintf (temp, "<C>Can't delete file: <%s>", strerror (errno));
|
|
#else
|
|
sprintf (temp, "<C>Can not delete file. Unknown reason.");
|
|
#endif
|
|
mesg[0] = copyChar (temp);
|
|
mesg[1] = " ";
|
|
mesg[2] = "<C>Press any key to continue.";
|
|
popupLabel (ScreenOf(fselect), mesg, 3);
|
|
freeCharList (mesg, 3);
|
|
}
|
|
}
|
|
|
|
/* Clean up. */
|
|
destroyCDKDialog (question);
|
|
|
|
/* Redraw the file selector. */
|
|
drawCDKFselect (fselect, ObjOf(fselect)->box);
|
|
}
|
|
|
|
/*
|
|
* This function sets the pre-process function.
|
|
*/
|
|
void setCDKFselectPreProcess (CDKFSELECT *fselect, PROCESSFN callback, void *data)
|
|
{
|
|
setCDKEntryPreProcess (fselect->entryField, callback, data);
|
|
setCDKScrollPreProcess (fselect->scrollField, callback, data);
|
|
}
|
|
|
|
/*
|
|
* This function sets the post-process function.
|
|
*/
|
|
void setCDKFselectPostProcess (CDKFSELECT *fselect, PROCESSFN callback, void *data)
|
|
{
|
|
setCDKEntryPostProcess (fselect->entryField, callback, data);
|
|
setCDKScrollPostProcess (fselect->scrollField, callback, data);
|
|
}
|
|
|
|
/*
|
|
* Start of callback functions.
|
|
*/
|
|
static void fselectAdjustScrollCB (EObjectType objectType GCC_UNUSED, void *object GCC_UNUSED, void *clientData, chtype key)
|
|
{
|
|
CDKFSELECT *fselect = (CDKFSELECT *)clientData;
|
|
CDKSCROLL *scrollp = (CDKSCROLL *)fselect->scrollField;
|
|
CDKENTRY *entry = (CDKENTRY *)fselect->entryField;
|
|
char *current, temp[1024];
|
|
int len;
|
|
|
|
/* Move the scrolling list. */
|
|
injectCDKScroll (fselect->scrollField, key);
|
|
|
|
/* Get the currently highlighted filename. */
|
|
current = chtype2Char (scrollp->item[scrollp->currentItem]);
|
|
len = (int)strlen (current);
|
|
current[len-1] = '\0';
|
|
|
|
/* Are we in the root partition. */
|
|
if (strcmp (fselect->pwd, "/") == 0)
|
|
{
|
|
sprintf (temp, "/%s", current);
|
|
}
|
|
else
|
|
{
|
|
sprintf (temp, "%s/%s", fselect->pwd, current);
|
|
}
|
|
freeChar (current);
|
|
|
|
/* Set the value in the entry field. */
|
|
setCDKEntryValue (entry, temp);
|
|
drawCDKEntry (entry, ObjOf(entry)->box);
|
|
}
|
|
|
|
/*
|
|
* This takes a ~ type account name and returns the full
|
|
* pathname.
|
|
*/
|
|
static char *expandFilename (char *filename)
|
|
{
|
|
struct passwd *accountInfo;
|
|
char accountName[256], pathname[1024], fullPath[2048];
|
|
int slashFound = 0;
|
|
int pos = 0;
|
|
int len, x;
|
|
|
|
/* Make sure the filename is not null. */
|
|
if ((filename == 0) || (len = strlen (filename)) == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* Make sure the first character is a tilde. */
|
|
if (filename[0] != '~')
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* Find the account name in the filename. */
|
|
for (x=1; x < len; x++)
|
|
{
|
|
if (filename[x] != '/' && slashFound == 0)
|
|
{
|
|
accountName[pos++] = filename[x];
|
|
}
|
|
else
|
|
{
|
|
if (slashFound == 0)
|
|
{
|
|
accountName[pos] = '\0';
|
|
pos = 0;
|
|
slashFound = 1;
|
|
}
|
|
else
|
|
{
|
|
pathname[pos++] = filename[x];
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Determine if the account name has a home directory. */
|
|
accountInfo = getpwnam (accountName);
|
|
if (accountInfo == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Construct the full pathname. We do this because someone
|
|
* may have had a pathname at the end of the account name
|
|
* and we want to keep it.
|
|
*/
|
|
sprintf (fullPath, "%s/%s", accountInfo->pw_dir, pathname);
|
|
return copyChar (fullPath);
|
|
}
|
|
|
|
/*
|
|
* Store the name of the current working directory.
|
|
*/
|
|
static void setPWD (CDKFSELECT *fselect)
|
|
{
|
|
char buffer[512];
|
|
freeChar (fselect->pwd);
|
|
if (getcwd(buffer, sizeof(buffer)) == 0)
|
|
strcpy(buffer, ".");
|
|
fselect->pwd = copyChar(buffer);
|
|
}
|