/* files.c */
#include "ml.h"
Widget append_shell;
Menu dir_option_menu[] = {
{ NULL, "hide_dot", NUL_TERM,
dir_hide_dot, NULL, 0,
NULL, NULL, BTN_HIDEDOT },
{ NULL, "show_dot", NUL_TERM,
dir_show_dot, NULL, 0,
NULL, NULL, BTN_NOHIDEDOT },
};
Menu dir_menu[] = {
{ NULL, "accept", NUL_TERM,
dir_accept, NULL, 0,
NULL, NULL, BTN_ON },
{ NULL, "cancel", NUL_TERM,
dir_cancel, NULL, 0,
NULL, NULL, BTN_ON },
{ NULL, "option_menu", NUL_TERM,
NULL, dir_option_menu, XtNumber(dir_option_menu),
NULL, NULL, BTN_ON },
{ NULL, "dir_HELP", NUL_TERM,
dir_help, NULL, 0,
NULL, NULL, BTN_ON },
};
Menu append_menu[] = {
{ NULL, "cancel", NUL_TERM,
append_cancel, NULL, 0,
NULL, NULL, BTN_ON },
{ NULL, "overwrite", NUL_TERM,
append_overwrite, NULL, 0,
NULL, NULL, BTN_ON },
{ NULL, "append", NUL_TERM,
append_append, NULL, 0,
NULL, NULL, BTN_ON },
{ NULL, "append_HELP", NUL_TERM,
append_help, NULL, 0,
NULL, NULL, BTN_ON },
};
#ifdef __STDC__
Dir_Struct *new_dir_struct(void)
#else
Dir_Struct *new_dir_struct()
#endif
{
Dir_Struct *dir_struct = (Dir_Struct *) fs_get(sizeof(Dir_Struct));
dir_struct->name = NULL;
dir_struct->directory = FALSE;
dir_struct->next = NULL;
return(dir_struct);
}
#ifdef __STDC__
void free_dir_structs(Dir_Struct *dir_struct)
#else
void free_dir_structs(dir_struct)
Dir_Struct *dir_struct;
#endif
{
if(dir_struct == NULL)
return;
free_dir_structs(dir_struct->next);
if(dir_struct->name)
fs_give((void **) &dir_struct->name);
fs_give((void **) &dir_struct);
return;
}
#ifdef __STDC__
char *file_select(Widget w, char *initial_dir, char *initial_pattern,
char *initial_file, Boolean op_write, Boolean *op_append)
#else
char *file_select(w,initial_dir,initial_pattern,initial_file,
op_write,op_append)
Widget w;
char *initial_dir;
char *initial_pattern;
char *initial_file;
Boolean op_write;
Boolean *op_append;
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
XtTranslations translations;
char *filename = NULL;
int append_mode;
Dirview *dirview;
Widget form, menubar, label1, label2;
set_watch_cursors();
dirview = (Dirview *) fs_get(sizeof(Dirview));
dirview->done = 0;
dirview->recurse = 0;
dirview->ignore_dot = TRUE;
dirview->button_state = BTN_HIDEDOT;
/*
* Preliminary preposterous position. We'll move it later.
* We don't want it flashing elsewhere on the screen
* because we're gonna' move it soon, and it has to be
* realized before we can find out if it will fit where
* we want it. Jumping widgets probably aren't Politically Correct.
*/
XtSetArg(args[n], XmNx, -1000); n ++;
XtSetArg(args[n], XmNy, -1000); n ++;
XtSetArg (args[n], XmNdeleteResponse, XmDO_NOTHING); n++;
dirview->shell = XtCreatePopupShell("fileselect", topLevelShellWidgetClass,
w, args, n );
AddDestroyCallback (dirview->shell);
n = 0;
setup_editres(dirview->shell);
if(pirate_icon != (Pixmap) None)
XtVaSetValues(dirview->shell,
XmNiconPixmap,pirate_icon,
NULL);
form = XmCreateForm(dirview->shell, "form", args, n); n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
menubar = XmCreateMenuBar(form,"menubar", args, n); n = 0;
XtManageChild(menubar);
create_buttons(NULL, menubar,
dir_menu, XtNumber(dir_menu),
BTN_ON, (XtPointer) dirview, ROOTMENULEVEL);
if(initial_dir)
dirview->cwd = cpystr(initial_dir);
else {
if(session->last_dir != NULL)
dirview->cwd = cpystr(session->last_dir);
else
dirview->cwd = cpystr(local_auth.homedir);
}
dirview->dir_struct = NULL;
dirview->dir_path =
create_text_field(form, menubar,
"directory", dirview->cwd,
0, (XtPointer) dir_dir_enter, (XtPointer) dirview);
dirview->dir_pattern =
create_text_field(form, dirview->dir_path,
"pattern",
(initial_pattern)
? initial_pattern
: preferences.default_file_pattern,
0, (XtPointer) dir_select_filter, (XtPointer) dirview);
dirview->dir_file =
create_text_field(form,dirview->dir_pattern,
"filename", initial_file,
0, (XtPointer) dir_accept, (XtPointer) dirview );
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET ); n ++;
XtSetArg(args[n], XmNtopWidget, dirview->dir_file ); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM ); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION ); n ++;
XtSetArg(args[n], XmNrightPosition, 50 ); n ++;
XtSetArg(args[n], XmNborderWidth, 0 ); n ++;
label1 = XmCreateLabel(form, "directories_lbl", args, n); n = 0;
XtManageChild(label1);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET ); n ++;
XtSetArg(args[n], XmNtopWidget, dirview->dir_file ); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION ); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM ); n ++;
XtSetArg(args[n], XmNleftPosition, 50 ); n ++;
XtSetArg(args[n], XmNborderWidth, 0 ); n ++;
label2 = XmCreateLabel(form, "files_lbl", args, n); n = 0;
XtManageChild(label2);
XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n ++;
XtSetArg(args[n], XmNlistSizePolicy,XmCONSTANT); n ++;
XtSetArg(args[n], XmNselectionPolicy,XmSINGLE_SELECT); n ++;
dirview->dir_dirlist = XmCreateScrolledList(form,"dirlist",args,n);
n = 0;
XtAddCallback(dirview->dir_dirlist, XmNsingleSelectionCallback,
(XtCallbackProc) dir_dir_select, dirview);
XtAddCallback(dirview->dir_dirlist, XmNdefaultActionCallback,
(XtCallbackProc) dir_dir_select, dirview);
translations =
XtParseTranslationTable(GLOBAL_modal_list_translations);
XtOverrideTranslations(dirview->dir_dirlist,translations);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, label1); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n ++;
XtSetArg(args[n], XmNrightPosition, 50); n ++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++;
XtSetValues(XtParent(dirview->dir_dirlist), args, n); n = 0;
XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n ++;
XtSetArg(args[n], XmNlistSizePolicy,XmCONSTANT); n ++;
XtSetArg(args[n], XmNselectionPolicy,XmSINGLE_SELECT); n ++;
dirview->dir_filelist =
XmCreateScrolledList(form,"filelist",args,n); n = 0;
XtAddCallback(dirview->dir_filelist, XmNsingleSelectionCallback,
(XtCallbackProc) dir_file_select, dirview);
XtAddCallback(dirview->dir_filelist, XmNdefaultActionCallback,
(XtCallbackProc) dir_accept, dirview);
translations =
XtParseTranslationTable(GLOBAL_modal_list_translations);
XtOverrideTranslations(dirview->dir_filelist,translations);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, label2); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n ++;
XtSetArg(args[n], XmNleftPosition, 50); n ++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++;
XtSetValues(XtParent(dirview->dir_filelist), args, n); n = 0;
XtManageChild(dirview->dir_dirlist);
XtManageChild(dirview->dir_filelist);
check_buttons(dir_menu, XtNumber(dir_menu),NULL, dirview->button_state);
XtManageChild(form);
XtManageChild(dirview->shell);
push_cursor(PIRATE_CURSOR);
position_popup_widget(dirview->shell, FALSE);
XtPopup(dirview->shell,XtGrabExclusive);
XmUpdateDisplay(dirview->shell);
dir_stuff(dirview);
modal_main_loop(&dirview->done);
XtPopdown(dirview->shell);
XtDestroyWidget(dirview->shell);
XFlush(display);
if((dirview->pathname) && (*(dirview->pathname) != NUL_TERM)) {
if(*dirview->pathname == PATH_SEPARATOR_CHAR)
filename = cpystr(dirview->pathname);
else {
filename = (char *) fs_get(MAXPATHLEN + 1);
strcpy(filename,(dirview->cwd) ? dirview->cwd : PATH_SEPARATOR_STR);
if(filename[strlen(filename) - 1] != PATH_SEPARATOR_CHAR)
strcat(filename,PATH_SEPARATOR_STR);
strcat(filename,dirview->pathname);
}
}
if(session->last_dir != NULL)
fs_give((void **) &session->last_dir);
if(dirview->cwd != NULL)
session->last_dir = cpystr(dirview->cwd);
free_dir_structs(dirview->dir_struct);
if(dirview->pathname)
fs_give((void **) &dirview->pathname);
if(dirview->cwd)
fs_give((void **) &dirview->cwd);
fs_give((void **) &dirview);
if(filename != NULL && (op_write == TRUE)) {
append_mode = get_append_mode(w,filename);
if(append_mode == (-1)) {
fs_give((void **) &filename);
filename = NULL;
}
if(append_mode == 1)
*op_append = FALSE;
if(append_mode == 2)
*op_append = TRUE;
}
pop_cursor();
return(filename);
}
#ifdef __STDC__
int get_append_mode(Widget w, char *filename)
#else
int get_append_mode(w,filename)
Widget w;
char *filename;
#endif
{
Arg args[ARGLISTSIZE];
int n = 0;
int append_mode = 0;
Widget form, menubar, label;
struct stat st;
if((stat(filename,&st)) == SYSCALL_FAILURE)
return(1);
if(! S_ISREG(st.st_mode)) {
mm_log(MLGetLocalized(XtNmsgNotRegularFile,MsgNotRegularFile),WARN);
return(-1);
}
append_shell = XtCreatePopupShell("append",
topLevelShellWidgetClass, w,
args, n );
AddDestroyCallback (append_shell);
n = 0;
setup_editres(append_shell);
if(pirate_icon != (Pixmap) None)
XtVaSetValues(append_shell,
XmNiconPixmap,pirate_icon,
NULL);
form = XmCreateForm(append_shell, "form", args, n); n = 0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
menubar = XmCreateMenuBar(form,"menubar", args, n); n = 0;
XtManageChild(menubar);
create_buttons(NULL, menubar,
append_menu, XtNumber(append_menu),
BTN_ON, (XtPointer) &append_mode, ROOTMENULEVEL);
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n ++;
XtSetArg(args[n], XmNtopWidget, menubar); n ++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n ++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n ++;
label = XmCreateLabel(form, "append_lbl",
args,n); n = 0;
XtManageChild(label);
XtManageChild(form);
XtManageChild(append_shell);
XtPopup(append_shell, XtGrabExclusive);
position_popup_widget(append_shell, TRUE);
modal_main_loop(&append_mode);
XtPopdown(append_shell);
XtDestroyWidget(append_shell);
XFlush(display);
return(append_mode);
}
#ifdef __STDC__
void append_cancel(Widget w, int *append_mode, XtPointer xp)
#else
void append_cancel(w,append_mode,xp)
Widget w;
int *append_mode;
XtPointer xp;
#endif
{
*append_mode = (-1);
return;
}
#ifdef __STDC__
void append_overwrite(Widget w, int *append_mode, XtPointer xp)
#else
void append_overwrite(w,append_mode,xp)
Widget w;
int *append_mode;
XtPointer xp;
#endif
{
*(append_mode) = 1;
return;
}
#ifdef __STDC__
void append_append(Widget w, int *append_mode, XtPointer xp)
#else
void append_append(w,append_mode,xp)
Widget w;
int *append_mode;
XtPointer xp;
#endif
{
*(append_mode) = 2;
return;
}
#ifdef __STDC__
void append_help(Widget w, int *append_mode, XtPointer xp)
#else
void append_help(w,append_mode,xp)
Widget w;
int *append_mode;
XtPointer xp;
#endif
{
help(append_shell,APPENDHELPFILE);
return;
}
#ifdef __STDC__
void dir_set(Dirview *dirview, char *path)
#else
void dir_set(dirview,path)
Dirview *dirview;
char *path;
#endif
{
if(dirview->cwd)
fs_give((void **) &dirview->cwd);
dirview->cwd = cpystr(path);
XmTextSetString(dirview->dir_path,path);
dir_stuff(dirview);
return;
}
#ifdef __STDC__
void dir_dir_select(Widget w, Dirview *dirview, XmListCallbackStruct *xp)
#else
void dir_dir_select(w,dirview,xp)
Widget w;
Dirview *dirview;
XmListCallbackStruct *xp;
#endif
{
char *str;
char *ptr;
char *newdir;
XmStringGetLtoR(xp->item,XmSTRING_DEFAULT_CHARSET,&str);
if(strcmp(str,MLGetLocalized(XtNmsgFileGoHome,MsgFileGoHome)) == STRMATCH)
newdir = cpystr(local_auth.homedir);
else {
if(strcmp(str,MLGetLocalized(XtNmsgFileGoUp,MsgFileGoUp)) == STRMATCH) {
newdir = GetTextField(dirview->dir_path);
if(((ptr = strrchr(newdir,PATH_SEPARATOR_CHAR)) != NULL)
&& (ptr > newdir))
*ptr = NUL_TERM;
if(ptr == newdir)
*(ptr + 1) = NUL_TERM;
}
else {
AppendText(dirview->dir_path,PATH_SEPARATOR_STR);
AppendText(dirview->dir_path,str);
newdir = GetTextField(dirview->dir_path);
}
}
fs_give((void **) &str);
dir_set(dirview,newdir);
fs_give((void **) &newdir);
return;
}
#ifdef __STDC__
void dir_dir_enter(Widget w, Dirview *dirview, XmListCallbackStruct *xp)
#else
void dir_dir_enter(w,dirview,xp)
Widget w;
Dirview *dirview;
XmListCallbackStruct *xp;
#endif
{
char *newdir = GetTextField(dirview->dir_path);
dir_set(dirview,newdir);
fs_give((void **) &newdir);
XmProcessTraversal(w,XmTRAVERSE_NEXT_TAB_GROUP);
return;
}
#ifdef __STDC__
void dir_file_select(Widget w, Dirview *dirview, XmListCallbackStruct *xp)
#else
void dir_file_select(w,dirview,xp)
Widget w;
Dirview *dirview;
XmListCallbackStruct *xp;
#endif
{
char *str;
XmStringGetLtoR(xp->item,XmSTRING_DEFAULT_CHARSET,&str);
XmTextSetString(dirview->dir_file,str);
fs_give((void **) &str);
XmListDeselectAllItems(dirview->dir_filelist);
return;
}
#ifdef __STDC__
void dir_accept(Widget w, Dirview *dirview, XtPointer xp)
#else
void dir_accept(w,dirview,xp)
Widget w;
Dirview *dirview;
XtPointer xp;
#endif
{
dirview->pathname = XmTextGetString(dirview->dir_file);
if(*dirview->pathname == NUL_TERM) {
fs_give((void **) &dirview->pathname);
dirview->pathname = NULL;
}
dirview->done = 1;
return;
}
#ifdef __STDC__
void dir_cancel(Widget w, Dirview *dirview, XtPointer xp)
#else
void dir_cancel(w,dirview,xp)
Widget w;
Dirview *dirview;
XtPointer xp;
#endif
{
dirview->pathname = NULL;
dirview->done = 1;
return;
}
#ifdef __STDC__
void dir_hide_dot(Widget w, Dirview *dirview, XtPointer xp)
#else
void dir_hide_dot(w,dirview,xp)
Widget w;
Dirview *dirview;
XtPointer xp;
#endif
{
dirview->ignore_dot = TRUE;
dirview->button_state |= BTN_HIDEDOT;
dirview->button_state &= ~(BTN_NOHIDEDOT);
dir_apply_filter(w,dirview,xp);
check_buttons(dir_menu, XtNumber(dir_menu),NULL, dirview->button_state);
return;
}
#ifdef __STDC__
void dir_show_dot(Widget w, Dirview *dirview, XtPointer xp)
#else
void dir_show_dot(w,dirview,xp)
Widget w;
Dirview *dirview;
XtPointer xp;
#endif
{
dirview->ignore_dot = FALSE;
dirview->button_state &= ~(BTN_HIDEDOT);
dirview->button_state |= BTN_NOHIDEDOT;
dir_apply_filter(w,dirview,xp);
check_buttons(dir_menu, XtNumber(dir_menu),NULL, dirview->button_state);
return;
}
#ifdef __STDC__
void dir_select_filter(Widget w, Dirview *dirview, XtPointer xp)
#else
void dir_select_filter(w,dirview,xp)
Widget w;
Dirview *dirview;
XtPointer xp;
#endif
{
dir_apply_filter(w,dirview,xp);
XmProcessTraversal(w,XmTRAVERSE_NEXT_TAB_GROUP);
return;
}
#ifdef __STDC__
void dir_help(Widget w, Dirview *dirview, XtPointer xp)
#else
void dir_help(w,dirview,xp)
Widget w;
Dirview *dirview;
XtPointer xp;
#endif
{
help(dirview->shell,FILEHELPFILE);
return;
}
#ifdef __STDC__
void dir_apply_filter(Widget w, Dirview *dirview, XtPointer xp)
#else
void dir_apply_filter(w,dirview,xp)
Widget w;
Dirview *dirview;
XtPointer xp;
#endif
{
Dir_Struct *dir_struct;
char *pattern;
XmString xstr;
XmListDeselectAllItems(dirview->dir_dirlist);
XmListDeleteAllItems(dirview->dir_dirlist);
XmListDeselectAllItems(dirview->dir_filelist);
XmListDeleteAllItems(dirview->dir_filelist);
pattern = GetTextField(dirview->dir_pattern);
xstr = XmStringCreateSimple(MLGetLocalized(XtNmsgFileGoHome,MsgFileGoHome));
XmListAddItemUnselected(dirview->dir_dirlist,xstr,0);
XmStringFree(xstr);
xstr = XmStringCreateSimple(MLGetLocalized(XtNmsgFileGoUp,MsgFileGoUp));
XmListAddItemUnselected(dirview->dir_dirlist,xstr,0);
XmStringFree(xstr);
for(dir_struct = dirview->dir_struct;
dir_struct;
dir_struct = dir_struct->next) {
if((dirview->ignore_dot) && (*dir_struct->name == '.'))
continue;
if((dir_struct->directory == FALSE)
&& (wildmat(dir_struct->name,pattern) == 0))
continue;
xstr = XmStringCreateSimple(dir_struct->name);
if(dir_struct->directory)
XmListAddItemUnselected(dirview->dir_dirlist,xstr,0);
else
XmListAddItemUnselected(dirview->dir_filelist,xstr,0);
XmStringFree(xstr);
}
return;
}
#ifdef __STDC__
void dir_stuff(Dirview *dirview)
#else
void dir_stuff(dirview)
Dirview *dirview;
#endif
{
DIR *d;
Dir_Struct *dir_struct;
char filename[MAXPATHLEN];
struct stat st;
#ifdef STRICT_BSD
struct direct *e = NULL;
#else
struct dirent *e = NULL;
#endif
XDefineCursor(display,XtWindow(dirview->shell), clock_cursor);
XFlush(display);
/*
* A few precautions. Since the dirview->cwd string and dir_path window
* have already been updated, we don't know where we came from if this fails.
* So we default to going home on failure. BUT, we need to also make
* sure we can do THAT. That's why the recursion counter. If we can't
* go home, no sense going on, so we hardwire a "cancel" operation.
* In any event, let the user know something wierd is going on.
*/
if((d = opendir(dirview->cwd)) == NULL) {
mm_log(MLGetLocalized(XtNmsgChdirFailed,MsgChdirFailed),WARN);
if(dirview->recurse < 2) {
dirview->recurse ++;
dir_set(dirview,local_auth.homedir);
}
else {
mm_log(MLGetLocalized(XtNmsgChdirHomeFailed,MsgChdirHomeFailed),ERROR);
dirview->pathname = NULL;
dirview->done = TRUE;
}
XBell(display,1000);
XUndefineCursor(display,XtWindow(dirview->shell));
XFlush(display);
return;
}
dirview->recurse = 0;
free_dir_structs(dirview->dir_struct);
dirview->dir_struct = NULL;
while((e = readdir(d)) != NULL) {
if((strcmp(e->d_name,THISDIR_STR) == STRMATCH)
|| (strcmp(e->d_name,PARENTDIR_STR) == STRMATCH))
continue;
sprintf(filename,"%s/%s",dirview->cwd,e->d_name);
if(stat(filename,&st) != SYSCALL_SUCCESS)
continue;
dir_struct = new_dir_struct();
dir_struct->name = cpystr(e->d_name);
dir_struct->directory = (S_ISDIR(st.st_mode)) ? TRUE : FALSE;
dir_struct->next = dirview->dir_struct;
dirview->dir_struct = dir_struct;
}
closedir(d);
dir_sort(dirview);
dir_apply_filter(dirview->shell,dirview,NULL);
XUndefineCursor(display,XtWindow(dirview->shell));
XFlush(display);
return;
}
#ifdef __STDC__
int dir_compare(const void *n1, const void *n2)
#else
int dir_compare(n1,n2)
const void *n1;
const void *n2;
#endif
{
Dir_Struct **name1 = (Dir_Struct **) n1;
Dir_Struct **name2 = (Dir_Struct **) n2;
return(strcmp((*(name1))->name,(*(name2))->name));
}
#ifdef __STDC__
void dir_sort(Dirview *dirview)
#else
void dir_sort(dirview)
Dirview *dirview;
#endif
{
Dir_Struct **sort;
Dir_Struct *dir_struct;
int n = 0;
int total = 0;
for(dir_struct = dirview->dir_struct;
dir_struct; dir_struct = dir_struct->next)
total ++;
if(total < 2)
return;
sort = (Dir_Struct **) fs_get(total * sizeof(Dir_Struct *));
for(dir_struct = dirview->dir_struct;
dir_struct; dir_struct = dir_struct->next) {
sort[n] = dir_struct;
n ++;
}
qsort((char *) sort, total, sizeof(Dir_Struct **), dir_compare);
for(n = 0; n < total; n ++) {
dir_struct = sort[n];
if(n == 0)
dirview->dir_struct = dir_struct;
if(n < (total - 1))
dir_struct->next = sort[n + 1];
else
dir_struct->next = NULL;
}
fs_give((void **) &sort);
return;
}
syntax highlighted by Code2HTML, v. 0.9.1