Merge branch 'master' of ssh://git.code.sf.net/p/cdesktopenv/code
[oweals/cde.git] / cde / programs / dtfile / Find.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: Find.c /main/10 1999/12/09 13:06:33 mgreess $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  *
27  *   FILE:           Find.c
28  *
29  *   COMPONENT_NAME: Desktop File Manager (dtfile)
30  *
31  *   Description:    Source file for the find file dialog.
32  *
33  *   FUNCTIONS: AlternateInputHandler
34  *              AlternateInputHandler
35  *              AlternateInputHandler
36  *              Create
37  *              Destroy
38  *              EnterStopBttn
39  *              ExecuteFind
40  *              ExecuteGrep
41  *              ExtractDirectory
42  *              FindProcessStarted
43  *              FindPutOnDesktop
44  *              FreeMatchInfo
45  *              FreeValues
46  *              GetDefaultValues
47  *              GetFileName
48  *              GetFindValues
49  *              GetResourceValues
50  *              GetValues
51  *              GrowBuffer
52  *              InstallChange
53  *              InstallClose
54  *              InvalidFindMessage
55  *              LeaveStopBttn
56  *              MakeAbsolute
57  *              NewView
58  *              SetActiveItem
59  *              SetFocus
60  *              SetValues
61  *              StartCallback
62  *              StartSearch
63  *              StopCallback
64  *              StopSearch
65  *              WriteResourceValues
66  *              findpopen
67  *
68  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
69  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
70  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
71  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
72  *
73  ****************************************************************************
74  ************************************<+>*************************************/
75
76
77 #include <unistd.h>
78 #include <stdio.h>
79 #include <time.h>
80 #include <limits.h>
81 #include <sys/types.h>
82 #include <sys/stat.h>
83 #include <pwd.h>
84 #include <signal.h>
85
86
87 #ifdef __hpux
88 #include <sys/getaccess.h>
89 #endif /* __hpux */
90 #include <stdlib.h>
91
92 #include <string.h>
93
94 #include <Xm/XmP.h>
95 #include <Xm/DialogS.h>
96 #include <Xm/Form.h>
97 #include <Xm/LabelG.h>
98 #include <Xm/List.h>
99 #include <Xm/Frame.h>
100 #include <Xm/MessageB.h>
101 #include <Xm/PushBG.h>
102 #include <Xm/PushB.h>
103 #include <Xm/RowColumn.h>
104 #include <Xm/ScrolledW.h>
105 #include <Xm/TextF.h>
106 #include <Xm/ToggleBG.h>
107 #include <Xm/SeparatoG.h>
108 #include <Xm/VendorSEP.h>
109 #include <Xm/MwmUtil.h>
110 #include <Xm/Protocols.h>
111
112 #include <Dt/TitleBox.h>
113
114 #include <X11/ShellP.h>
115 #include <X11/Xatom.h>
116
117 #include <Dt/Connect.h>
118 #include <Dt/DtNlUtils.h>
119 #include <Dt/HourGlass.h>
120 #include <Dt/Dts.h>
121 #include <Dt/SharedProcs.h>
122
123 #include <Tt/tttk.h>
124
125 #include <Xm/XmPrivate.h> /* _XmStringUngenerate */
126
127 #include "Encaps.h"
128 #include "SharedProcs.h"
129 #include "FileMgr.h"
130 #include "Desktop.h"
131 #include "Main.h"
132 #include "Common.h"
133 #include "Find.h"
134 #include "Help.h"
135 #include "SharedMsgs.h"
136
137
138 typedef struct _Dummy {
139    Boolean       displayed;
140    Position      x;
141    Position      y;
142    Dimension     width;
143    Dimension     height;
144
145    String string;
146 } Dummy, *DummyPtr;
147
148
149 /* Error message defines */
150
151 #define BAD_DIR_NAME               0
152 #define NO_DIR_ACCESS              1
153 #define NO_EXISTANCE               2
154 #define NO_FILE_OR_FOLDER_ARG      3
155
156
157 /* More string defines */
158 static char * PRINT_OPTION = " -print ";
159 static char * FIND_COMMAND = "find ";
160 static char * GREP_COMMAND = "grep -i -l ";
161 static char * NAME_OPTION =  " -name ";
162 #if defined(__hpux) || defined(sun)
163 static char * FOLLOW_OPTION = " -follow";
164 #endif /* __hpux */
165 static char * REDIRECTOR =   " 2>&-";
166 static char * TYPEDIR = " -type d";
167 static char * FIND_FILE = "FindFile";
168
169 #define NEW_VIEW     0
170 #define CURRENT_VIEW 1
171
172
173
174 /*  Resource definitions for the find file dialog  */
175
176 static DialogResource resources[] =
177 {
178    { "folders", XmRString, sizeof(String),
179      XtOffset(FindDataPtr, directories),
180      (XtPointer) NULL, _DtStringToString },
181
182    { "name", XmRString, sizeof(String),
183      XtOffset(FindDataPtr, filter),
184      (XtPointer) NULL, _DtStringToString },
185
186    { "selectedItem", XmRInt, sizeof(int),
187      XtOffset(FindDataPtr, selected_item),
188      (XtPointer) -1, _DtIntToString },
189
190    { "content", XmRString, sizeof(String),
191      XtOffset(FindDataPtr, content),
192      (XtPointer) NULL, _DtStringToString },
193 };
194
195
196 static DialogResource match_resources[] =
197 {
198    { "matchData", XmRString, sizeof(String),
199      XtOffset(DummyPtr, string),
200      (XtPointer) NULL, _DtStringToString },
201 };
202
203 /********    Static Function Declarations    ********/
204
205 static void Create(
206                         Display *display,
207                         Widget parent,
208                         Widget *return_widget,
209                         XtPointer *dialog) ;
210 static void InstallChange(
211                         FindRec *find_rec,
212                         XtCallbackProc callback,
213                         XtPointer client_data) ;
214 static void InstallClose(
215                         FindRec *find_rec,
216                         XtCallbackProc callback,
217                         XtPointer client_data) ;
218 static void Destroy(
219                         FindRec *find_rec) ;
220 static XtPointer GetValues(
221                         FindRec *find_rec) ;
222 static XtPointer GetDefaultValues( void ) ;
223 static XtPointer GetResourceValues(
224                         XrmDatabase data_base,
225                         char **name_list) ;
226 static void SetValues(
227                         FindRec *find_rec,
228                         FindData *find_data) ;
229 static void WriteResourceValues(
230                         DialogData *values,
231                         int fd,
232                         char **name_list) ;
233 static void FreeValues(
234                         FindData *find_data) ;
235 static Boolean GetFindValues(
236                         FindRec *find_rec,
237                         FindData *find_data,
238                         Boolean validate) ;
239 static void InvalidFindMessage(
240                         FindRec *find_rec,
241                         int messageIndex,
242                         String extra_string) ;
243 static void FreeMatchInfo(
244                         String *matches,
245                         int numMatches) ;
246 static void LeaveStopBttn(
247                         Widget w,
248                         FindRec * find_rec,
249                         XEvent * event) ;
250 static void EnterStopBttn(
251                         Widget w,
252                         FindRec * find_rec,
253                         XEvent * event) ;
254 static void StopSearch(
255                         Widget w,
256                         FindRec *find_rec) ;
257 static void StartSearch(
258                         Widget w,
259                         FindRec *find_rec) ;
260 static void StartCallback(
261                         Widget w,
262                         XtPointer client_data,
263                         XtPointer call_data) ;
264 static void StopCallback(
265                         Widget w,
266                         XtPointer client_data,
267                         XtPointer call_data) ;
268 static String GrowBuffer(
269                         String buf,
270                         int *size,
271                         int extra) ;
272 static String MakeAbsolute(
273                         String current_directory,
274                         String path) ;
275 static Boolean FindProcessStarted(
276                         FindRec *find_rec,
277                         FindData *find_data) ;
278 static Boolean ExecuteFind(
279                         FindRec *find_rec,
280                         FindData *find_data,
281                         FileMgrData *file_mgr_data) ;
282 static Boolean ExecuteGrep(
283                         FindRec * find_rec) ;
284 static void AlternateInputHandler(
285                         XtPointer client_data,
286                         int *source,
287                         XtInputId *id) ;
288 static void AlternateInputHandler2(
289                         XtPointer client_data,
290                         int *source,
291                         XtInputId *id) ;
292 static void AlternateInputHandler3(
293                         XtPointer client_data,
294                         int *source,
295                         XtInputId *id) ;
296 static void GetFileName(
297                         Widget list,
298                         int selectedItem,
299                         String *host,
300                         String *path,
301                         FileMgrData *file_mgr_data) ;
302 static Boolean ExtractDirectory(
303                         String host,
304                         String path,
305                         char **file_name) ;
306 static void NewView(
307                         Widget widget,
308                         XtPointer client_data,
309                         XtPointer call_data) ;
310 static void FindPutOnDesktop(
311                         Widget widget,
312                         XtPointer client_data,
313                         XtPointer call_data) ;
314 static void SetActiveItem(
315                         Widget widget,
316                         XtPointer client_data,
317                         XtPointer call_data) ;
318 static void SetFocus(
319                         FindRec *find_rec,
320                         FindData *find_data ) ;
321 FILE *findpopen(char *,char *,int *);
322
323 /********    End Static Function Declarations    ********/
324
325
326 /*
327  *  The Dialog Class structure.
328  */
329
330 static DialogClass findClassRec =
331 {
332    resources,
333    XtNumber(resources),
334    Create,
335    (DialogInstallChangeProc) InstallChange,
336    (DialogInstallCloseProc) InstallClose,
337    (DialogDestroyProc) Destroy,
338    (DialogGetValuesProc) GetValues,
339    GetDefaultValues,
340    GetResourceValues,
341    (DialogSetValuesProc) SetValues,
342    WriteResourceValues,
343    (DialogFreeValuesProc) FreeValues,
344    (DialogMapWindowProc) _DtGenericMapWindow,
345    (DialogSetFocusProc) SetFocus,
346 };
347
348 DialogClass * findClass = (DialogClass *) &findClassRec;
349 char *buffer;
350 static char *ptr;
351
352
353 /************************************************************************
354  *
355  *  Create
356  *
357  ************************************************************************/
358
359 static void
360 Create(
361         Display *display,
362         Widget parent,
363         Widget *return_widget,
364         XtPointer *dialog )
365 {
366    FindRec * find_rec;
367    Widget shell, form, form1, form2;
368    Widget newFM, outputSeparator;
369    Widget headLabel, contentLabel, contentText;
370    Widget filterText, filterLabel, listLabel, scrolledList, dirName, dirLabel;
371 #if defined(__hpux) || defined(sun)
372    Widget followLink, followLinkPD;
373 #endif
374    Widget putOnDT, separator;
375    Widget start, stop, close, help;
376    XmString label_string;
377
378    Arg args[12];
379    int n;
380    XtTranslations trans_table;
381    char * tmpStr;
382
383    /* Initialize some global varibles */
384    buffer = NULL;
385    ptr = NULL;
386
387    /*  Allocate the find file dialog instance record.  */
388
389    find_rec = (FindRec *) XtMalloc (sizeof (FindRec));
390
391    /*  Create the shell and form used for the dialog.  */
392
393    n = 0;
394    XtSetArg (args[n], XmNmwmFunctions, MWM_FUNC_MOVE |
395              MWM_FUNC_CLOSE );                                  ++n;
396    XtSetArg (args[n], XmNmwmDecorations, MWM_DECOR_BORDER |
397              MWM_DECOR_TITLE);                                ++n;
398    XtSetArg (args[n], XmNallowShellResize, False);              ++n;
399    shell = XmCreateDialogShell (parent, "find_files", args, n);
400
401    /* Set the useAsyncGeo on the shell */
402    XtSetArg (args[0], XmNuseAsyncGeometry, True);
403    XtSetValues (XtParent(shell), args, 1);
404
405    trans_table = XtParseTranslationTable(translations_space);
406
407    n = 0;
408    XtSetArg (args[n], XmNmarginWidth, 1);                               n++;
409    XtSetArg (args[n], XmNmarginHeight, 1);                              n++;
410    XtSetArg (args[n], XmNshadowThickness, 1);                   n++;
411    XtSetArg (args[n], XmNshadowType, XmSHADOW_OUT);                     n++;
412    XtSetArg (args[n], XmNautoUnmanage, False);                  n++;
413    form = XmCreateForm (shell, "form", args, n);
414    XtAddCallback(form, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
415                  HELP_FIND_DIALOG_STR);
416
417    label_string = XmStringCreateLocalized ((GETMESSAGE(15,47, "Fill in one or more fields to specify which items to find:")));
418    n = 0;
419    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
420    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
421    XtSetArg (args[n], XmNleftOffset, 5);                                n++;
422    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);                 n++;
423    XtSetArg (args[n], XmNtopOffset, 14);                                n++;
424    XtSetArg (args[n], XmNtraversalOn, False);                           n++;
425    headLabel = XmCreateLabelGadget (form, "hdlb", args, n);
426    XtManageChild (headLabel);
427    XmStringFree (label_string);
428
429    label_string = XmStringCreateLocalized ((GETMESSAGE(15,31, "File or Folder Name: ")));
430    n = 0;
431    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
432    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
433    XtSetArg (args[n], XmNleftOffset, 5);                                n++;
434    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
435    XtSetArg (args[n], XmNtopWidget, headLabel);                         n++;
436    XtSetArg (args[n], XmNtopOffset, 15);                                n++;
437    XtSetArg (args[n], XmNtraversalOn, False);                           n++;
438    filterLabel = XmCreateLabelGadget (form, "file_name_label", args, n);
439    XtManageChild (filterLabel);
440    XmStringFree (label_string);
441    XtAddCallback(filterLabel, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
442                  HELP_FIND_DIALOG_STR);
443
444    n = 0;
445    XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);              n++;
446    XtSetArg (args[n], XmNleftWidget, filterLabel);                      n++;
447    XtSetArg (args[n], XmNleftOffset, 0);                                n++;
448    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
449    XtSetArg (args[n], XmNtopWidget, headLabel);                         n++;
450    XtSetArg (args[n], XmNtopOffset, 10);                                n++;
451    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
452    XtSetArg (args[n], XmNrightOffset, 10);                              n++;
453    filterText = XmCreateTextField (form, "file_name_text", args, n);
454    XtManageChild (filterText);
455    XtAddCallback(filterText, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
456                  HELP_FIND_DIALOG_STR);
457
458    /* set up translations in the filter text edit widget */
459    XtOverrideTranslations(filterText, trans_table);
460
461    label_string = XmStringCreateLocalized ((GETMESSAGE(15,32, "File Contents:")));
462    n = 0;
463    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
464    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
465    XtSetArg (args[n], XmNleftOffset, 5);                                n++;
466    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
467    XtSetArg (args[n], XmNtopWidget, filterText);                        n++;
468    XtSetArg (args[n], XmNtopOffset, 15);                                n++;
469    XtSetArg (args[n], XmNtraversalOn, False);                           n++;
470    contentLabel = XmCreateLabelGadget (form, "content_label", args, n);
471    XtManageChild (contentLabel);
472    XmStringFree (label_string);
473    XtAddCallback(contentLabel, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
474                  HELP_FIND_DIALOG_STR);
475
476    n = 0;
477    XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);              n++;
478    XtSetArg (args[n], XmNleftWidget, contentLabel);                     n++;
479    XtSetArg (args[n], XmNleftOffset, 0);                                n++;
480    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
481    XtSetArg (args[n], XmNtopWidget, filterText);                        n++;
482    XtSetArg (args[n], XmNtopOffset, 10);                                n++;
483    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
484    XtSetArg (args[n], XmNrightOffset, 10);                              n++;
485    contentText = XmCreateTextField (form, "content_text", args, n);
486    XtManageChild (contentText);
487    XtAddCallback(contentText, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
488                  HELP_FIND_DIALOG_STR);
489
490 #if defined(__hpux) || defined(sun)
491    n = 0;
492    XtSetArg (args[n], XmNmarginWidth, 1);                               n++;
493    XtSetArg (args[n], XmNmarginHeight, 1);                              n++;
494    XtSetArg (args[n], XmNshadowThickness, 0);                           n++;
495    XtSetArg (args[n], XmNautoUnmanage, False);                          n++;
496    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
497    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
498    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
499    XtSetArg (args[n], XmNtopWidget, contentText);                       n++;
500    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
501    form1 = XmCreateForm (form, "form1", args, n);
502    XtManageChild (form1);
503
504     /* Create a Pulldown MenuPane that will contain the font sizes */
505    followLinkPD = XmCreatePulldownMenu(form1, "fLinkPD", args, 0);
506
507    label_string = XmStringCreateLocalized ((GETMESSAGE(15,33, "On")));
508    XtSetArg(args[0], XmNmarginHeight, 2);
509    XtSetArg(args[1], XmNmarginWidth, 12);
510    XtSetArg(args[2], XmNlabelString, label_string); n++;
511    find_rec->widgArry[0] =
512                   XmCreatePushButtonGadget(followLinkPD, "On", args, 3);
513    XmStringFree(label_string);
514
515    label_string = XmStringCreateLocalized ((GETMESSAGE(15,34, "Off")));
516    XtSetArg(args[2], XmNlabelString, label_string);
517    find_rec->widgArry[1] =
518                   XmCreatePushButtonGadget(followLinkPD, "Off", args, 3);
519    XmStringFree(label_string);
520
521    XtManageChildren(find_rec->widgArry, 2);
522
523    label_string = XmStringCreateLocalized ((GETMESSAGE(15,35, "Follow Links: ")));
524    /* create the Option Menu and attach it to the Pulldown MenuPane */
525    n = 0;
526    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
527    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
528    XtSetArg (args[n], XmNleftOffset, 30);                               n++;
529    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);                 n++;
530    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
531    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);              n++;
532    XtSetArg (args[n], XmNbottomOffset, 5);                              n++;
533    XtSetArg(args[n], XmNsubMenuId, followLinkPD); n++;
534    XtSetArg(args[n], XmNmenuHistory, find_rec->widgArry[OFF]); n++;
535    followLink = XmCreateOptionMenu(form1, "fLink", args, n);
536    XtManageChild (followLink);
537    XtAddCallback(followLink, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
538                  HELP_FIND_DIALOG_STR);
539
540 #endif
541
542    n = 0;
543    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
544    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
545    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
546 #if defined(__hpux) || defined(sun)
547    XtSetArg (args[n], XmNtopWidget, form1);                             n++;
548 #else
549    XtSetArg (args[n], XmNtopWidget, contentText);                       n++;
550 #endif
551    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
552    outputSeparator = XmCreateSeparatorGadget (form, "opSeparator", args, n);
553    XtManageChild (outputSeparator);
554
555    /* Create the field for collecting the directory names to search */
556
557    label_string = XmStringCreateLocalized (((char *)GETMESSAGE(15, 42, "Search Folder: ")));
558    n = 0;
559    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
560    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
561    XtSetArg (args[n], XmNleftOffset, 5);                                n++;
562    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
563    XtSetArg (args[n], XmNtopWidget, outputSeparator);                   n++;
564    XtSetArg (args[n], XmNtopOffset, 15);                                n++;
565    XtSetArg (args[n], XmNtraversalOn, False);                           n++;
566    dirLabel = XmCreateLabelGadget (form, "folder_name_label", args, n);
567    XtManageChild (dirLabel);
568    XmStringFree (label_string);
569    XtAddCallback(dirLabel, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
570                  HELP_FIND_DIALOG_STR);
571
572    n = 0;
573    XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);              n++;
574    XtSetArg (args[n], XmNleftWidget, dirLabel);                         n++;
575    XtSetArg (args[n], XmNleftOffset, 0);                                n++;
576    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
577    XtSetArg (args[n], XmNrightOffset, 10);                              n++;
578    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
579    XtSetArg (args[n], XmNtopWidget, outputSeparator);                   n++;
580    XtSetArg (args[n], XmNtopOffset, 10);                                n++;
581    dirName = XmCreateTextField (form, "folder_name_text", args, n);
582    XtManageChild (dirName);
583    XtAddCallback(dirName, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
584                  HELP_FIND_DIALOG_STR);
585
586    /* set up translations in the search directory text edit widget */
587    XtOverrideTranslations(dirName, trans_table);
588
589    /* Create the widgets showing the matching files */
590
591    n = 0;
592    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
593    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
594    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
595    XtSetArg (args[n], XmNtopWidget, dirLabel);                          n++;
596    XtSetArg (args[n], XmNtopOffset, 15);                                n++;
597    outputSeparator = XmCreateSeparatorGadget (form, "outputSeparator", args, n);
598    XtManageChild (outputSeparator);
599
600    label_string = XmStringCreateLocalized (GetSharedMessage(FILES_FOUND_LABEL));
601    n = 0;
602    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
603    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
604    XtSetArg (args[n], XmNleftOffset, 5);                                n++;
605    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
606    XtSetArg (args[n], XmNtopWidget, outputSeparator);                   n++;
607    XtSetArg (args[n], XmNtopOffset, 10);                                n++;
608    XtSetArg (args[n], XmNtraversalOn, False);                           n++;
609    listLabel = XmCreateLabelGadget (form, "files_found", args, n);
610    XtManageChild (listLabel);
611    XmStringFree (label_string);
612    XtAddCallback(listLabel, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
613                  HELP_FIND_DIALOG_STR);
614
615    n = 0;
616    XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT);                   n++;
617    XtSetArg (args[n], XmNscrollBarDisplayPolicy, XmSTATIC);             n++;
618    XtSetArg (args[n], XmNvisibleItemCount, 5);                          n++;
619    scrolledList = XmCreateScrolledList (form, "file_list", args, n);
620    XtManageChild (scrolledList);
621
622    XtAddCallback (scrolledList, XmNbrowseSelectionCallback,
623                                         SetActiveItem, (XtPointer) find_rec);
624    XtAddCallback (scrolledList, XmNdefaultActionCallback,
625                                               NewView, (XtPointer) find_rec);
626    XtAddCallback(XtParent(scrolledList), XmNhelpCallback,
627                  (XtCallbackProc)HelpRequestCB,
628                  HELP_FIND_DIALOG_STR);
629
630
631    n = 0;
632    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
633    XtSetArg (args[n], XmNtopWidget, listLabel);                         n++;
634    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
635    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
636    XtSetArg (args[n], XmNleftOffset, 10);                               n++;
637    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
638    XtSetArg (args[n], XmNrightPosition, 10);                            n++;
639    XtSetValues (XtParent (scrolledList), args, n);
640
641    n = 0;
642    XtSetArg (args[n], XmNmarginWidth, 1);                               n++;
643    XtSetArg (args[n], XmNmarginHeight, 1);                              n++;
644    XtSetArg (args[n], XmNshadowThickness, 0);                           n++;
645    XtSetArg (args[n], XmNautoUnmanage, False);                          n++;
646    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
647    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
648    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
649    XtSetArg (args[n], XmNtopWidget, scrolledList);                      n++;
650    XtSetArg (args[n], XmNtopOffset, 10);                                n++;
651    form2 = XmCreateForm (form, "form2", args, n);
652    XtManageChild (form2);
653 /*
654    XtAddCallback(form2, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
655                  HELP_FIND_DIALOG_STR);
656 */
657
658    label_string = XmStringCreateLocalized ((GETMESSAGE(15,48, "Open Folder")));
659
660    n = 0;
661    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
662    XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);            n++;
663    XtSetArg (args[n], XmNleftPosition, 10);                             n++;
664    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);                 n++;
665    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
666    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);              n++;
667    XtSetArg (args[n], XmNbottomOffset, 5);                              n++;
668    XtSetArg (args[n], XmNmarginHeight, 4);                              n++;
669    XtSetArg (args[n], XmNmarginWidth, 10);                              n++;
670    newFM = XmCreatePushButtonGadget (form2, "new_view", args, n);
671    XtManageChild (newFM);
672    XtAddCallback (newFM, XmNactivateCallback, NewView, (XtPointer) find_rec);
673    XtAddCallback(newFM, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
674                  HELP_FIND_DIALOG_STR);
675    XmStringFree (label_string);
676
677    XtSetArg (args[0], XmNdefaultButton, newFM);
678    XtSetValues (form2, args, 1);
679
680    label_string = XmStringCreateLocalized ((GETMESSAGE(15,37, "Put In Workspace")));
681    n = 0;
682    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
683    XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);            n++;
684    XtSetArg (args[n], XmNleftPosition, 55);                             n++;
685    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM);                 n++;
686    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
687    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);              n++;
688    XtSetArg (args[n], XmNbottomOffset, 5);                              n++;
689    XtSetArg (args[n], XmNmarginHeight, 4);                              n++;
690    XtSetArg (args[n], XmNmarginHeight, 4);                              n++;
691    XtSetArg (args[n], XmNmarginWidth, 10);                              n++;
692    putOnDT = XmCreatePushButtonGadget (form2, "putInWorkspace", args, n);
693    XtManageChild (putOnDT);
694    XtAddCallback (putOnDT, XmNactivateCallback, FindPutOnDesktop,
695                   (XtPointer) find_rec);
696    XtAddCallback(putOnDT, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
697                  HELP_FIND_DIALOG_STR);
698    XmStringFree (label_string);
699
700    /*  Create a separator between the buttons  */
701
702    n = 0;
703    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);                n++;
704    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);               n++;
705    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
706    XtSetArg (args[n], XmNtopWidget, form2);                             n++;
707    XtSetArg (args[n], XmNtopOffset, 10);                                n++;
708    separator =  XmCreateSeparatorGadget (form, "separator", args, n);
709    XtManageChild (separator);
710
711
712    /*  Create the action buttons  */
713
714    label_string = XmStringCreateLocalized (((char *)GETMESSAGE(15, 14, "Start")));
715    n = 0;
716    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
717    XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);            n++;
718    XtSetArg (args[n], XmNleftPosition, 1);                              n++;
719    XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);           n++;
720    XtSetArg (args[n], XmNrightPosition, 24);                            n++;
721    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
722    XtSetArg (args[n], XmNtopWidget, separator);                         n++;
723    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
724    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM);              n++;
725    XtSetArg (args[n], XmNbottomOffset, 5);                              n++;
726    XtSetArg (args[n], XmNmarginHeight, 4);                              n++;
727    start = XmCreatePushButtonGadget (form, "start", args, n);
728    XtAddCallback (start, XmNactivateCallback, StartCallback,
729                                                         (XtPointer) find_rec);
730    XtAddCallback(start, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
731                  HELP_FIND_DIALOG_STR);
732    XtManageChild (start);
733    XmStringFree (label_string);
734
735    label_string = XmStringCreateLocalized (((char *)GETMESSAGE(15, 15, "Stop")));
736    n = 0;
737    XtSetArg (args[n], XmNlabelString, label_string);                    n++;
738    XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);            n++;
739    XtSetArg (args[n], XmNleftPosition, 26);                             n++;
740    XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);           n++;
741    XtSetArg (args[n], XmNrightPosition, 49);                            n++;
742    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
743    XtSetArg (args[n], XmNtopWidget, separator);                         n++;
744    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
745    XtSetArg (args[n], XmNmarginHeight, 4);                              n++;
746    stop = XmCreatePushButton (form, "stop", args, n);
747    XtAddCallback (stop, XmNactivateCallback, StopCallback,
748                                                    (XtPointer) find_rec);
749    XtAddCallback(stop, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
750                  HELP_FIND_DIALOG_STR);
751    XtManageChild (stop);
752    XtSetSensitive (stop, False);
753    XmStringFree (label_string);
754
755    n = 0;
756    XtSetArg (args[n], XmNlabelString, cancelXmString);                  n++;
757    XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);            n++;
758    XtSetArg (args[n], XmNleftPosition, 51);                             n++;
759    XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);           n++;
760    XtSetArg (args[n], XmNrightPosition, 74);                            n++;
761    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
762    XtSetArg (args[n], XmNtopWidget, separator);                         n++;
763    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
764    XtSetArg (args[n], XmNmarginHeight, 4);                              n++;
765    close = XmCreatePushButtonGadget (form, "close", args, n);
766    XtManageChild (close);
767    XtAddCallback(close, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
768                  HELP_FIND_DIALOG_STR);
769
770
771    n = 0;
772    XtSetArg (args[n], XmNlabelString, helpXmString);                    n++;
773    XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);            n++;
774    XtSetArg (args[n], XmNleftPosition, 76);                             n++;
775    XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);           n++;
776    XtSetArg (args[n], XmNrightPosition, 99);                            n++;
777    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);               n++;
778    XtSetArg (args[n], XmNtopWidget, separator);                         n++;
779    XtSetArg (args[n], XmNtopOffset, 5);                                 n++;
780    XtSetArg (args[n], XmNmarginHeight, 4);                              n++;
781    help = XmCreatePushButton (form, "help", args, n);
782    XtManageChild (help);
783    XtAddCallback(help, XmNactivateCallback, (XtCallbackProc)HelpRequestCB,
784                  HELP_FIND_DIALOG_STR);
785    XtAddCallback(help, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
786                  HELP_FIND_DIALOG_STR);
787
788
789
790    XtSetArg (args[0], XmNdefaultButton, start);
791    XtSetArg (args[1], XmNcancelButton, close);
792    XtSetValues (form, args, 2);
793
794    /* Fill in our instance structure */
795
796    find_rec->shell = shell;
797    find_rec->form = form;
798    find_rec->fileNameFilter = filterText;
799    find_rec->content = contentText;
800 #if defined(__hpux) || defined(sun)
801    find_rec->followLink = followLink;
802 #else
803    find_rec->followLink = NULL;
804 #endif
805    find_rec->listLabel = listLabel;
806    find_rec->matchList = scrolledList;
807    find_rec->searchDirectory = dirName;
808    find_rec->newFM = newFM;
809    find_rec->putOnDT = putOnDT;
810    find_rec->start = start;
811    find_rec->stop = stop;
812    find_rec->close = close;
813    find_rec->help = help;
814
815    find_rec->selectedItem = -1;
816    find_rec->popenId = NULL;
817    find_rec->childpid = -1;
818    find_rec->alternateInputId = 0;
819    find_rec->searchInProgress = False;
820    find_rec->fileMgrRec = NULL;
821
822
823    /*  Set the return values for the dialog widget and dialog instance.  */
824
825    *return_widget = form;
826    *dialog = (XtPointer) find_rec;
827 }
828
829
830
831 /************************************************************************
832  *
833  *  InstallChange
834  *
835  ************************************************************************/
836
837 static void
838 InstallChange(
839         FindRec *find_rec,
840         XtCallbackProc callback,
841         XtPointer client_data )
842 {
843    FindApply * apply_data;
844
845
846    /*  Setup the callback data to be sent to the most of our */
847    /*  actions callbacks.                                    */
848
849    apply_data = (FindApply *) XtMalloc (sizeof (FindApply));
850    apply_data->callback = callback;
851    apply_data->client_data = client_data;
852    apply_data->find_rec = (XtPointer) find_rec;
853    find_rec->apply_data = apply_data;
854 }
855
856
857
858
859 /************************************************************************
860  *
861  *  InstallClose
862  *
863  ************************************************************************/
864
865 static void
866 InstallClose(
867         FindRec *find_rec,
868         XtCallbackProc callback,
869         XtPointer client_data )
870 {
871    Atom delete_window_atom;
872
873    XtAddCallback (find_rec->close, XmNactivateCallback, callback, client_data);
874
875    delete_window_atom = XmInternAtom (XtDisplay(find_rec->shell), "WM_DELETE_WINDOW", True);
876    XmRemoveWMProtocols( find_rec->shell, &delete_window_atom, 1 );
877    XmAddWMProtocolCallback( find_rec->shell, delete_window_atom, callback,
878                             (XtPointer) client_data );
879 }
880
881
882
883
884 /************************************************************************
885  *
886  *  Destroy
887  *
888  ************************************************************************/
889
890 static void
891 Destroy(
892         FindRec *find_rec )
893 {
894    XtDestroyWidget (find_rec->shell);
895    XtFree ((char *) find_rec->apply_data);
896    XtFree ((char *) find_rec);
897 }
898
899
900
901
902 /************************************************************************
903  *
904  *  GetValues
905  *
906  ************************************************************************/
907
908 static XtPointer
909 GetValues(
910         FindRec *find_rec )
911 {
912    FindData * find_data;
913    Arg args[4];
914
915
916    /*  Allocate and initialize the find file dialog data.  */
917
918    find_data = (FindData *) XtMalloc (sizeof (FindData));
919
920    find_data->displayed = True;
921
922    XtSetArg (args[0], XmNx, &find_data->x);
923    XtSetArg (args[1], XmNy, &find_data->y);
924    XtSetArg (args[2], XmNwidth, &find_data->width);
925    XtSetArg (args[3], XmNheight, &find_data->height);
926    XtGetValues (find_rec->shell, args, 4);
927
928    (void) GetFindValues (find_rec, find_data, False);
929
930    return ((XtPointer) find_data);
931 }
932
933
934
935
936 /************************************************************************
937  *
938  *  GetDefaultValues
939  *
940  ************************************************************************/
941
942 static XtPointer
943 GetDefaultValues( void )
944 {
945    FindData *find_data;
946    char     dirbuf[MAX_DIR_PATH_LEN];
947
948    /*  Allocate and initialize the default find file dialog data.  */
949
950    find_data = (FindData *) XtMalloc (sizeof (FindData));
951
952    find_data->displayed = False;
953    find_data->x = 0;
954    find_data->y = 0;
955    find_data->height = 0;
956    find_data->width = 0;
957
958    (void)getcwd((char *)dirbuf, (unsigned int)MAX_DIR_PATH_LEN);
959    if(restrictMode &&
960            strncmp(users_home_dir, dirbuf, strlen(users_home_dir)) != 0)
961    {
962       find_data->directories = (char *)XtMalloc(strlen(users_home_dir) + 1);
963       strcpy(find_data->directories, users_home_dir);
964    }
965    else
966    {
967       find_data->directories = (char *)XtMalloc(strlen(dirbuf) + 1);
968       strcpy(find_data->directories, dirbuf);
969    }
970
971    find_data->filter = NULL;
972    find_data->content = NULL;
973    find_data->matches = NULL;
974    find_data->num_matches = 0;
975    find_data->selected_item = -1;
976 #if defined(__hpux) || defined(sun)
977    find_data->follow_links = follow_links;
978 #endif
979
980    return ((XtPointer) find_data);
981 }
982
983
984
985
986 /************************************************************************
987  *
988  *  GetResourceValues
989  *
990  ************************************************************************/
991
992 static XtPointer
993 GetResourceValues(
994         XrmDatabase data_base,
995         char **name_list )
996 {
997    FindData * find_data;
998    Dummy dummy;
999    static Boolean convertersAdded = False;
1000
1001
1002    /*  Allocate and get the resources for find file dialog data.  */
1003
1004    find_data = (FindData *) XtCalloc (1, sizeof (FindData));
1005
1006    _DtDialogGetResources (data_base, name_list, FIND_FILE, (char *) find_data,
1007                        resources, findClass->resource_count);
1008
1009    /* Create new strings for any string value we read in from our
1010     * resourceDB.
1011     */
1012    find_data->directories = XtNewString(find_data->directories);
1013    find_data->filter = XtNewString(find_data->filter);
1014    find_data->content = XtNewString(find_data->content);
1015
1016    /*  Do a special read to get the list of matches.                 */
1017    /*  The information is read in as a single string, and then must  */
1018    /*  be converted into the internal array format.                  */
1019
1020    _DtDialogGetResources (data_base, name_list, FIND_FILE, (char *) (&dummy),
1021                        match_resources, XtNumber(match_resources));
1022
1023    CvtStringToStringList (dummy.string, &find_data->matches,
1024                           &find_data->num_matches);
1025
1026    return ((XtPointer) find_data);
1027 }
1028
1029
1030
1031
1032 /************************************************************************
1033  *
1034  *  SetValues
1035  *
1036  ************************************************************************/
1037
1038 static void
1039 SetValues(
1040         FindRec *find_rec,
1041         FindData *find_data )
1042 {
1043    Arg args[2];
1044    XmString * matches;
1045    int i;
1046
1047    XmTextFieldSetString (find_rec->fileNameFilter, find_data->filter);
1048    XmTextFieldSetInsertionPosition(find_rec->fileNameFilter,
1049                         XmTextFieldGetLastPosition(find_rec->fileNameFilter));
1050    XmTextFieldSetString(find_rec->content, find_data->content);
1051    XmTextFieldSetInsertionPosition(find_rec->content,
1052                         XmTextFieldGetLastPosition(find_rec->content));
1053
1054    if(find_data->directories)
1055       XtFree(find_data->directories);
1056    find_data->directories =
1057                  XtNewString(find_data->file_mgr_data->current_directory );
1058
1059    XmTextFieldSetString(find_rec->searchDirectory, find_data->directories);
1060    XmTextFieldSetInsertionPosition(find_rec->searchDirectory,
1061                         XmTextFieldGetLastPosition(find_rec->searchDirectory));
1062    if( find_data->file_mgr_data->restricted_directory )
1063    {
1064       XtAddCallback (find_rec->searchDirectory, XmNmodifyVerifyCallback,
1065                      (XtCallbackProc)TextChange,
1066                      (XtPointer)find_data->file_mgr_data );
1067       XtAddCallback (find_rec->searchDirectory, XmNmotionVerifyCallback,
1068                      (XtCallbackProc)TextChange,
1069                      (XtPointer)find_data->file_mgr_data );
1070    }
1071
1072    /* Update the list of matches */
1073
1074    if (find_data->num_matches > 0)
1075    {
1076       XtSetArg (args[0], XmNitemCount, find_data->num_matches);
1077       matches =
1078          (XmString *) XtMalloc (sizeof (XmString) * find_data->num_matches);
1079
1080       for (i = 0; i < find_data->num_matches; i++)
1081       {
1082          matches[i] = XmStringCreateLocalized (find_data->matches[i]);
1083       }
1084
1085       XtSetArg (args[1], XmNitems, matches);
1086       XtSetValues (find_rec->matchList, args, 2);
1087
1088       for (i = 0; i < find_data->num_matches; i++)
1089          XmStringFree (matches[i]);
1090
1091       XtFree ((char *) matches);
1092
1093       if (find_data->selected_item != -1)
1094       {
1095          XmListSelectPos (find_rec->matchList,
1096                           find_data->selected_item + 1,False);
1097       }
1098    }
1099    else
1100    {
1101       XtSetArg (args[0], XmNitemCount, 0);
1102       XtSetValues (find_rec->matchList, args, 1);
1103    }
1104
1105 #if defined(__hpux) || defined(sun)
1106    /* Set up the Follow links option menu */
1107    if(find_data->follow_links)
1108       XtSetArg(args[0], XmNmenuHistory, find_rec->widgArry[ON]);
1109    else
1110       XtSetArg(args[0], XmNmenuHistory, find_rec->widgArry[OFF]);
1111    XtSetValues (find_rec->followLink, args, 1);
1112 #endif
1113
1114    /* Update button sensitivity, if one of the matches is selected */
1115
1116    if (find_data->selected_item != -1)
1117    {
1118       XtSetSensitive (find_rec->newFM, True);
1119       XtSetSensitive (find_rec->putOnDT, True);
1120    }
1121    else
1122    {
1123       XtSetSensitive (find_rec->newFM, False);
1124       XtSetSensitive (find_rec->putOnDT, False);
1125    }
1126
1127    find_rec->selectedItem = find_data->selected_item;
1128
1129 }
1130
1131
1132
1133
1134 /************************************************************************
1135  *
1136  *  WriteResourceValues
1137  *
1138  ************************************************************************/
1139
1140 static void
1141 WriteResourceValues(
1142         DialogData *values,
1143         int fd,
1144         char **name_list )
1145 {
1146    FindData * find_data = (FindData *) values->data;
1147    FindRec  * find_rec;
1148    Arg args[2];
1149    Dummy dummy;
1150
1151
1152    /*  If the dialog is currently displayed, update the geometry  */
1153    /*  fields to their current values.                            */
1154
1155    if (find_data->displayed == True)
1156    {
1157       _DtGenericUpdateWindowPosition(values);
1158       find_rec = (FindRec *) _DtGetDialogInstance (values);
1159       (void) GetFindValues (find_rec, find_data, False);
1160    }
1161
1162    _DtDialogPutResources (fd, name_list, FIND_FILE, (char *) values->data,
1163                        resources, findClass->resource_count);
1164
1165
1166    /*  Special case for writing the array of matching files.          */
1167    /*  Write all of the information out as a single string, which     */
1168    /*  we'll parse when we read it back in at a later point in time.  */
1169    /*  The format for this string is:                                 */
1170    /*                                                                 */
1171    /*     <match string1>, <match string2>, <match string3>, ...      */
1172
1173    if (find_data->num_matches > 0)
1174    {
1175       dummy.displayed = False;
1176       dummy.string = CvtStringListToString (find_data->matches,
1177                                             find_data->num_matches);
1178
1179       _DtDialogPutResources (fd, name_list, FIND_FILE, (char *) &dummy,
1180                           match_resources, XtNumber (match_resources));
1181
1182       XtFree ((char *) dummy.string);
1183       dummy.string = NULL;
1184    }
1185 }
1186
1187
1188
1189
1190 /************************************************************************
1191  *
1192  *  FreeValues
1193  *
1194  ************************************************************************/
1195
1196 static void
1197 FreeValues(
1198         FindData *find_data )
1199 {
1200    if( find_data )
1201    {
1202       if( find_data->filter )
1203          XtFree ((char *) find_data->filter);
1204       if( find_data->directories )
1205          XtFree ((char *) find_data->directories);
1206       FreeMatchInfo (find_data->matches, find_data->num_matches);
1207       XtFree ((char *) find_data);
1208    }
1209 }
1210
1211
1212 /************************************************************************
1213  *
1214  *  GetFindValues
1215  *      Update the current find file values within the data structure
1216  *      from the current values.
1217  *
1218  ************************************************************************/
1219
1220 static Boolean
1221 GetFindValues(
1222         FindRec *find_rec,
1223         FindData *find_data,
1224         Boolean validate )
1225 {
1226    Arg args[2];
1227    int i;
1228    XmString * stringTable;
1229
1230
1231    /* Get the filename to search for (e.g. Filter) */
1232
1233    find_data->displayed = True;
1234    find_data->content = XmTextFieldGetString (find_rec->content);
1235    find_data->filter = (char *)_DtStripSpaces (
1236                               XmTextFieldGetString (find_rec->fileNameFilter));
1237    if (validate)
1238    {
1239      if ((strlen (find_data->filter) == 0) &&
1240                                          (strcmp(find_data->content, "") == 0))
1241       {
1242          XtFree ((char *) find_data->filter);
1243          find_data->filter = NULL;
1244       }
1245    }
1246
1247    /* Get the list of directories to search */
1248    if(find_data->directories)
1249       XtFree(find_data->directories);
1250    find_data->directories = XmTextFieldGetString (find_rec->searchDirectory);
1251
1252    if (validate)
1253    {
1254       find_data->directories = (char *)_DtStripSpaces (find_data->directories);
1255
1256       if (strlen (find_data->directories) == 0)
1257       {
1258          /* A directory must be supplied */
1259
1260          InvalidFindMessage (find_rec, BAD_DIR_NAME, NULL);
1261          XtFree ((char *) find_data->filter);
1262          find_data->filter = NULL;
1263          XtFree ((char *) find_data->directories);
1264          find_data->directories = NULL;
1265          return (False);
1266       }
1267    }
1268
1269    /* Make a copy of the array of matching strings */
1270
1271    find_data->selected_item = find_rec->selectedItem;
1272    XtSetArg (args[0], XmNitemCount, &find_data->num_matches);
1273    XtSetArg (args[1], XmNitems, &stringTable);
1274    XtGetValues (find_rec->matchList, args, 2);
1275    if (find_data->num_matches == 0)
1276    {
1277       find_data->matches = NULL;
1278    }
1279    else
1280    {
1281       find_data->matches =
1282          (String *) XtMalloc (sizeof(String) * find_data->num_matches);
1283
1284       for (i = 0; i < find_data->num_matches; i++)
1285       {
1286          find_data->matches[i] = (char *) _XmStringUngenerate(stringTable[i],
1287                                                   XmFONTLIST_DEFAULT_TAG,
1288                                                   XmCHARSET_TEXT, XmCHARSET_TEXT);
1289       }
1290    }
1291
1292 #if defined(__hpux) || defined(sun)
1293    {
1294       Widget menuHistory;
1295
1296       XtSetArg (args[0], XmNmenuHistory, &menuHistory);
1297       XtGetValues (find_rec->followLink, args, 1);
1298
1299       if(menuHistory == find_rec->widgArry[ON])
1300          find_data->follow_links = True;
1301       else
1302          find_data->follow_links = False;
1303    }
1304 #endif
1305
1306    return (True);
1307 }
1308
1309
1310
1311
1312 /************************************************************************
1313  *
1314  *  InvalidFindMessage
1315  *      Display an error message.
1316  *
1317  ************************************************************************/
1318
1319 static void
1320 InvalidFindMessage(
1321         FindRec * find_rec,
1322         int messageIndex,
1323         String extra_string )
1324 {
1325    String string;
1326    String new_string;
1327    char * title;
1328    static String badDirectoryNameMessage = NULL;
1329    static String noDirectoryAccessMessage = NULL;
1330    static String noSearchArgumentMessage = NULL;
1331    static String noExistanceMessage = NULL;
1332    char * tmpStr;
1333
1334    if (noExistanceMessage == NULL)
1335    {
1336       tmpStr = GETMESSAGE(15,44, "Search Folder name argument is missing.\nType in the name of the folder where you want the search to begin.");
1337       badDirectoryNameMessage = XtNewString(tmpStr);
1338
1339       tmpStr = GetSharedMessage(NO_DIR_ACCESS_ERROR);
1340       noDirectoryAccessMessage = XtNewString(tmpStr);
1341
1342       tmpStr = GETMESSAGE(15, 50, "Search Folder name or File Content argument is missing\nType in the name of the folder where you want the search to begin.\nOr type in the string that you want to search.");
1343       noSearchArgumentMessage = XtNewString(tmpStr);
1344
1345       tmpStr = GETMESSAGE(15,45, "The selected file no longer exists.\n\nSomeone deleted the file after the search process completed.");
1346       noExistanceMessage = XtNewString(tmpStr);
1347    }
1348
1349
1350    switch (messageIndex)
1351    {
1352       case BAD_DIR_NAME:
1353            string = badDirectoryNameMessage;
1354            break;
1355       case NO_DIR_ACCESS:
1356            string = noDirectoryAccessMessage;
1357            break;
1358       case NO_EXISTANCE:
1359            string = noExistanceMessage;
1360            break;
1361        case NO_FILE_OR_FOLDER_ARG:
1362            string = noSearchArgumentMessage;
1363            break;
1364    }
1365
1366    if (extra_string)
1367    {
1368       new_string = XtMalloc (strlen(string) + strlen(extra_string) + 1);
1369       (void) sprintf(new_string, string, extra_string);
1370       tmpStr = GetSharedMessage(FIND_ERROR_TITLE);
1371       title = XtNewString(tmpStr);
1372       _DtMessage (find_rec->shell, title, new_string, NULL, HelpRequestCB);
1373       XtFree ((char *) new_string);
1374       XtFree(title);
1375    }
1376    else
1377    {
1378       tmpStr = GetSharedMessage(FIND_ERROR_TITLE);
1379       title = XtNewString(tmpStr);
1380       _DtMessage (find_rec->shell, title, string, NULL, HelpRequestCB);
1381       XtFree(title);
1382    }
1383
1384    _DtTurnOffHourGlass (find_rec->shell);
1385 }
1386
1387
1388
1389
1390 /************************************************************************
1391  *
1392  *  FreeMatchInfo()
1393  *      Free up the space occupied by the array containing the match
1394  *      strings.
1395  *
1396  ************************************************************************/
1397
1398 static void
1399 FreeMatchInfo(
1400         String *matches,
1401         int numMatches )
1402 {
1403    int i;
1404
1405    if (matches == NULL)
1406       return;
1407
1408    for (i = 0; i < numMatches; i++)
1409       XtFree ((char *) matches[i]);
1410
1411
1412    XtFree ((char *) matches);
1413 }
1414
1415
1416
1417 /************************************************************************
1418  *
1419  *  StopSearch()
1420  *      Abort an active search operation.
1421  *
1422  ************************************************************************/
1423
1424 static void
1425 StopSearch(
1426         Widget w,
1427         FindRec *find_rec )
1428 {
1429    Arg args[2];
1430
1431
1432    /* To avoid a race condition where the input processing routine   */
1433    /* detected the end of the find operation and cleaned things up,  */
1434    /* just as the user hit the 'stop' key, we need to check to see   */
1435    /* if the operation is still active.                              */
1436
1437    if (find_rec->popenId != NULL)
1438    {
1439       /* Abort the find process, and remove the alternate input handler */
1440       (void) fclose (find_rec->popenId);
1441       if(find_rec->childpid > 1)  /* trying to be safe */
1442         kill(find_rec->childpid,SIGTERM);  /* Ignore errors */
1443       find_rec->popenId = NULL;
1444       find_rec->childpid = -1;
1445       XtRemoveInput (find_rec->alternateInputId);
1446       find_rec->alternateInputId = 0;
1447       find_rec->searchInProgress = False;
1448    }
1449
1450
1451    /* Change button sensitivities */
1452
1453    XtSetSensitive (find_rec->start, True);
1454    XtSetSensitive (find_rec->close, True);
1455    XtSetSensitive (find_rec->stop, False);
1456
1457    XtSetArg (args[0], XmNdefaultButton, find_rec->start);
1458    XtSetValues (find_rec->form, args, 1);
1459
1460    /*
1461     */
1462
1463    XtRemoveEventHandler (find_rec->stop, LeaveWindowMask, FALSE, (XtEventHandler)LeaveStopBttn, find_rec);
1464    XtRemoveEventHandler (find_rec->stop, EnterWindowMask, FALSE, (XtEventHandler)EnterStopBttn, find_rec);
1465
1466    _DtTurnOffHourGlass (find_rec->shell);
1467    XmUpdateDisplay (w);
1468    XtFree(buffer);
1469    buffer = NULL;
1470    ptr = NULL;
1471 }
1472
1473
1474
1475
1476 /************************************************************************
1477  *
1478  *  StartSearch()
1479  *      Start an active search operation.
1480  *
1481  ************************************************************************/
1482
1483 static void
1484 StartSearch(
1485         Widget w,
1486         FindRec *find_rec )
1487 {
1488    FindData * find_data;
1489    Arg args[3];
1490
1491    _DtTurnOnHourGlass (find_rec->shell);
1492
1493    /* Extract current dialog values; continue only if data is valid */
1494
1495    find_data = (FindData *) XtMalloc (sizeof (FindData));
1496
1497    if (!GetFindValues (find_rec, find_data, True))
1498    {
1499       /* Dialog contained bogus values; abort request */
1500
1501       XtFree ((char *) find_data);
1502       return;
1503    }
1504
1505
1506    /* Desensitize buttons we don't want working during a search */
1507
1508    XtSetSensitive (find_rec->stop, True);
1509    XtSetSensitive (find_rec->start, False);
1510    XtSetSensitive (find_rec->close, False);
1511    XtSetSensitive (find_rec->newFM, False);
1512    XtSetSensitive (find_rec->putOnDT, False);
1513
1514    XtSetArg (args[0], XmNdefaultButton, find_rec->stop);
1515    XtSetArg (args[1], XmNcancelButton, find_rec->close);
1516    XtSetValues (find_rec->form, args, 2);
1517
1518    /* Clean out the match list */
1519
1520    find_rec->selectedItem = -1;
1521    XtSetArg (args[0], XmNitemCount, 0);
1522    XtSetValues (find_rec->matchList, args, 1);
1523
1524    XmUpdateDisplay (w);
1525
1526
1527    /* Start the find process; not much we can say if it fails! */
1528
1529    if (!FindProcessStarted (find_rec, find_data))
1530    {
1531       XtSetSensitive (find_rec->close, True);
1532       XtSetSensitive (find_rec->newFM, False);
1533       XtSetSensitive (find_rec->putOnDT, False);
1534       XtSetSensitive (find_rec->start, True);
1535       XtSetSensitive (find_rec->stop, False);
1536
1537       XtSetArg (args[0], XmNdefaultButton, find_rec->start);
1538       XtSetArg (args[1], XmNcancelButton, find_rec->close);
1539       XtSetValues (find_rec->form, args, 2);
1540
1541       XmUpdateDisplay (w);
1542    }
1543    else
1544    {
1545       find_rec->searchInProgress = True;
1546
1547       /* This event handlers will be called when user is moving his mouse
1548          over the Find dialog's stop button.
1549       */
1550       XtAddEventHandler( find_rec->stop, LeaveWindowMask, FALSE, (XtEventHandler)LeaveStopBttn, find_rec );
1551       XtAddEventHandler( find_rec->stop, EnterWindowMask, FALSE, (XtEventHandler)EnterStopBttn, find_rec );
1552    }
1553
1554    /* Free up the dialog values we allocated */
1555
1556    FreeValues (find_data);
1557 }
1558
1559
1560 /************************************************************************
1561  *
1562  *  EnterStopBttn()
1563  *
1564  ************************************************************************/
1565
1566 static void
1567 EnterStopBttn(
1568               Widget w,
1569               FindRec * find_rec,
1570               XEvent * event )
1571 {
1572   _DtTurnOffHourGlass (find_rec->shell);
1573 }
1574
1575
1576 /************************************************************************
1577  *
1578  *  LeaveStopBttn()
1579  *
1580  ************************************************************************/
1581
1582 static void
1583 LeaveStopBttn(
1584               Widget w,
1585               FindRec * find_rec,
1586               XEvent * event )
1587 {
1588   _DtTurnOnHourGlass (find_rec->shell);
1589 }
1590
1591
1592 /************************************************************************
1593  *
1594  *  StartCallback()
1595  *      Start a search operation.
1596  *
1597  ************************************************************************/
1598
1599 static void
1600 StartCallback(
1601         Widget w,
1602         XtPointer client_data,
1603         XtPointer call_data )
1604 {
1605    StartSearch (w, (FindRec *) client_data);
1606 }
1607
1608
1609
1610
1611 /************************************************************************
1612  *
1613  *  StopCallback
1614  *      Stop an active search operation.
1615  *
1616  ************************************************************************/
1617
1618 static void
1619 StopCallback(
1620         Widget w,
1621         XtPointer client_data,
1622         XtPointer call_data )
1623 {
1624    StopSearch (w, (FindRec *) client_data);
1625 }
1626
1627
1628
1629
1630 /************************************************************************
1631  *
1632  *  GrowBuffer
1633  *
1634  ************************************************************************/
1635
1636 static String
1637 GrowBuffer(
1638         String buf,
1639         int *size,
1640         int extra )
1641 {
1642    if (strlen (buf) + 1 + extra >= *size)
1643    {
1644       *size = strlen(buf) + extra + 1025;
1645       buf = XtRealloc (buf, *size);
1646    }
1647
1648    return (buf);
1649 }
1650
1651
1652
1653
1654 /************************************************************************
1655  *
1656  *  MakeAbsolute()
1657  *      Change relative path to absolute one.
1658  *
1659  ************************************************************************/
1660
1661 static String
1662 MakeAbsolute(
1663         String current_directory,
1664         String path )
1665 {
1666    String absPath;
1667
1668    absPath = XtMalloc (strlen (path) + strlen (current_directory) + 2);
1669    (void) strcpy (absPath, current_directory);
1670    (void) strcat (absPath, "/");
1671    (void) strcat (absPath, path);
1672
1673    return (absPath);
1674 }
1675
1676
1677
1678
1679 /************************************************************************
1680  *
1681  *  FindProcessStarted()
1682  *      Determine whether to do a 'find' or a 'grep'.
1683  *
1684  ************************************************************************/
1685
1686 static Boolean
1687 FindProcessStarted(
1688         FindRec *find_rec,
1689         FindData *find_data )
1690 {
1691    FileMgrData * file_mgr_data;
1692    DialogData * dialog_data;
1693
1694    dialog_data = _DtGetInstanceData ((XtPointer) (find_rec->fileMgrRec));
1695    file_mgr_data = (FileMgrData *) dialog_data->data;
1696
1697    return(ExecuteFind(find_rec, find_data, file_mgr_data));
1698
1699 }
1700
1701 /************************************************************************
1702  *
1703  *  ExecuteFind()
1704  *      Create the command string for invoking the 'find' process,
1705  *      and then execute it.
1706  *
1707  ************************************************************************/
1708
1709 static Boolean
1710 ExecuteFind(
1711    FindRec * find_rec,
1712    FindData * find_data,
1713    FileMgrData *file_mgr_data)
1714 {
1715    int commandLen;
1716    String command;
1717    String findptr;
1718    String host;
1719    String path;
1720    int access_priv;
1721    XmString label_string;
1722    char *tmpStr;
1723    Arg args[1];
1724 #if defined (SVR4)  || defined(_AIX) || defined(sco)
1725 /* needed for getaccess () call */
1726    int save_ruid;
1727    int save_rgid;
1728 #endif /* SVR4 */
1729    char *link_path;
1730    void (*oldSig)();
1731    Tt_status tt_status;
1732 #ifdef __osf__
1733    extern void sigchld_handler(int);
1734 #endif /* __osf__ */
1735
1736    if(strcmp(find_data->content, "") == 0)
1737    {
1738       label_string = XmStringCreateLocalized (GetSharedMessage(FILES_FOUND_LABEL));
1739    }
1740    else if(strcmp(find_data->filter, "") == 0)
1741    {
1742       tmpStr = GETMESSAGE(15,38, "Files Found (by Contents):");
1743       label_string = XmStringCreateLocalized (tmpStr);
1744    }
1745    else
1746    {
1747       tmpStr = (GETMESSAGE(15,39, "Files Found (by Name and Contents):"));
1748       label_string = XmStringCreateLocalized (tmpStr);
1749    }
1750    XtSetArg (args[0], XmNlabelString, label_string);
1751    XtSetValues (find_rec->listLabel, args, 1);
1752    XmStringFree(label_string);
1753
1754    if(find_data->filter == NULL )
1755    {
1756      InvalidFindMessage (find_rec, NO_FILE_OR_FOLDER_ARG, NULL);
1757      return( False );
1758    }
1759
1760
1761    /* Construct the 'find' command */
1762
1763    commandLen = 1024;
1764    command = XtMalloc (commandLen);
1765    (void) strcpy (command, FIND_COMMAND);
1766
1767
1768    /* Convert directory names from external to internal (nfs) format */
1769
1770    findptr = find_data->directories;
1771
1772
1773    /*  Search for the end of the directory component  */
1774
1775    _DtPathFromInput(findptr, file_mgr_data->current_directory, &host, &path);
1776
1777    if (path == NULL)
1778    {
1779      InvalidFindMessage (find_rec, NO_DIR_ACCESS, findptr);
1780      return( False );
1781    }
1782
1783    link_path = _DtFollowLink(path);
1784    XtFree(path);
1785    path = XtNewString(link_path);
1786
1787    if(path == NULL)
1788    {
1789       XtFree(command);
1790       return False;
1791    }
1792    /* Verify that the path exists and is accessible */
1793 #if defined (SVR4)  || defined(_AIX) || defined(sco)
1794 /* needed for getaccess () call */
1795    save_ruid = getuid();
1796 #if !defined(SVR4) && ! defined(sco)
1797    setreuid(geteuid(),-1);
1798 #else
1799    setuid(geteuid());
1800 #endif
1801    save_rgid = getgid();
1802 #if !defined(SVR4) && !defined(sco)
1803    setregid(getegid(),-1);
1804 #else
1805    setgid(getegid());
1806 #endif
1807    access_priv = access (path, R_OK);
1808 #if !defined(SVR4) && !defined(sco)
1809    setreuid(save_ruid,-1);
1810    setregid(save_rgid,-1);
1811 #else
1812    setuid(save_ruid);
1813    setgid(save_rgid);
1814 #endif
1815    if (access_priv == -1 && geteuid() != root_user)
1816    {
1817 #else
1818 #  if defined(__hp_osf) || defined(__ultrix) || defined(__osf__) || defined(linux) || defined(CSRG_BASED)
1819    setreuid(geteuid(),-1);
1820    if (access ((char *) path, R_OK) == -1)
1821    {
1822 #  else
1823 #    ifdef BLS
1824    setresuid(geteuid(),-1,-1);
1825    if (access ((char *) path, R_OK) == -1)
1826    {
1827 #    else
1828    if ((((access_priv = getaccess (path, UID_EUID, NGROUPS_EGID_SUPP,
1829                                       0, (void *) 0, (void *) 0)) == -1) ||
1830              !(access_priv & R_OK)) && (geteuid () != root_user))
1831    {
1832 #    endif /* BLS */
1833 #  endif /* Apollo & OSF */
1834 #endif /* SVR4 */
1835       /* Post an error dialog, and then terminate the request */
1836
1837       InvalidFindMessage (find_rec, NO_DIR_ACCESS, findptr);
1838       XtFree ((char *) path);
1839       XtFree ((char *) command);
1840       return (False);
1841    }
1842
1843
1844    /* See if the buffer needs to grow */
1845
1846    command = GrowBuffer (command, &commandLen, (int) strlen (path));
1847
1848
1849    /* Add path to the command string */
1850
1851    (void) strcat (command, path);
1852    (void) strcat (command, " ");
1853    XtFree ((char *) path);
1854
1855    /* Add on the rest of the search constraints */
1856
1857    if(strcmp(find_data->content, "") != 0)
1858    {
1859       command = GrowBuffer (command, &commandLen, (int) strlen (TYPEDIR));
1860       (void) strcat (command, TYPEDIR);
1861    }
1862    else
1863    {
1864        /* File name regular expression */
1865        if (find_data->filter)
1866        {
1867           command =
1868              GrowBuffer (command, &commandLen, (int)strlen (find_data->filter) +
1869                                                 (int) strlen (NAME_OPTION) + 2);
1870
1871           /* The string needs to be quoted */
1872           (void) strcat (command, NAME_OPTION);
1873           (void) strcat (command, "\"");
1874           (void) strcat (command, find_data->filter);
1875           (void) strcat (command, "\" ");
1876        }
1877
1878    }
1879
1880 #if defined(__hpux) || defined(sun)
1881    {
1882       Widget menuHistory;
1883
1884       XtSetArg (args[0], XmNmenuHistory, &menuHistory);
1885       XtGetValues (find_rec->followLink, args, 1);
1886
1887       if(menuHistory == find_rec->widgArry[ON])
1888       {
1889          /* Add the option to follow a link */
1890
1891          command = GrowBuffer (command, &commandLen,
1892                                     (int) strlen (FOLLOW_OPTION));
1893          (void) strcat (command, FOLLOW_OPTION);
1894       }
1895    }
1896 #endif
1897
1898    /* Add the -print to get the results of the find */
1899
1900    command = GrowBuffer (command, &commandLen, (int) strlen (PRINT_OPTION));
1901    (void) strcat (command, PRINT_OPTION);
1902
1903
1904    /* Add the redirector for stderr, so it is disabled */
1905
1906    command = GrowBuffer (command, &commandLen, (int) strlen (REDIRECTOR));
1907    (void) strcat (command, REDIRECTOR);
1908
1909
1910    /* Start the 'find' process */
1911
1912 #ifdef __osf__
1913    oldSig = signal(SIGCHLD, sigchld_handler);
1914 #else
1915    oldSig = signal(SIGCHLD, SIG_DFL);
1916 #endif /* __osf__ */
1917    find_rec->popenId = findpopen(command, "r",&(find_rec->childpid));
1918    signal (SIGCHLD, oldSig);
1919
1920    if (find_rec->popenId == NULL)
1921    {
1922       XtFree ((char *) command);
1923       return (False);
1924    }
1925
1926
1927    /* Set up the alternate input source handler */
1928
1929    if(strcmp(find_data->content, "") != 0)
1930    {
1931       find_rec->alternateInputId =
1932          XtAddInput (fileno (find_rec->popenId), (XtPointer)XtInputReadMask,
1933                   (XtInputCallbackProc)AlternateInputHandler2, find_rec);
1934    }
1935    else
1936    {
1937       find_rec->alternateInputId =
1938          XtAddInput (fileno (find_rec->popenId), (XtPointer)XtInputReadMask,
1939                   (XtInputCallbackProc)AlternateInputHandler, find_rec);
1940    }
1941
1942    /* printf ("%s\n", command); */
1943
1944    XtFree ((char *) command);
1945
1946    return (True);
1947 }
1948
1949
1950 /************************************************************************
1951  *
1952  *  ExecuteGrep()
1953  *      Create the command string for invoking the 'grep' process,
1954  *      and then execute it.
1955  *
1956  ************************************************************************/
1957 static Boolean
1958 ExecuteGrep( FindRec * find_rec)
1959 {
1960    int commandLen;
1961    String command;
1962    Arg args[1];
1963    char *contents;
1964    char *ptr2;
1965    int item_count;
1966    char * title;
1967    char * msg;
1968
1969    /* Construct the 'grep' command */
1970    commandLen = 1024;
1971    command = XtMalloc (commandLen);
1972    (void) strcpy (command, GREP_COMMAND);
1973
1974    contents = XmTextFieldGetString (find_rec->content);
1975
1976    command = GrowBuffer (command, &commandLen, strlen(contents) + 4);
1977
1978    (void) strcat (command, "\"");
1979    (void) strcat (command, contents);
1980    (void) strcat (command, "\"");
1981    (void) strcat (command, " ");
1982
1983    if( ptr == NULL)
1984       ptr = buffer;
1985
1986    ptr2 = DtStrchr(ptr, ',');
1987    if(ptr2 == NULL)
1988    {
1989       XtFree ((char *) command);
1990       XtFree(buffer);
1991       buffer = NULL;
1992       ptr = NULL;
1993       if(find_rec->popenId != NULL)
1994          (void) fclose (find_rec->popenId);
1995       find_rec->popenId = NULL;
1996       find_rec->alternateInputId = 0;
1997
1998       find_rec->searchInProgress = False;
1999
2000       /* Reset button sensitivity */
2001
2002       XtSetSensitive (find_rec->close, True);
2003       XtSetSensitive (find_rec->start, True);
2004       XtSetSensitive (find_rec->stop, False);
2005
2006       XtSetArg (args[0], XmNitemCount, &item_count);
2007       XtGetValues (find_rec->matchList, args, 1);
2008
2009       XtSetArg (args[0], XmNdefaultButton, find_rec->start);
2010       XtSetValues (find_rec->form, args, 1);
2011
2012       if (item_count == 0)
2013       {
2014          char * tmpStr;
2015
2016          tmpStr = GetSharedMessage(FIND_ERROR_TITLE);
2017          title = XtNewString(tmpStr);
2018          tmpStr = GetSharedMessage(NO_FILES_FOUND_ERROR);
2019          msg = XtNewString(tmpStr);
2020          _DtMessage (find_rec->shell, title, msg, NULL, HelpRequestCB);
2021          XtFree(title);
2022          XtFree(msg);
2023       }
2024       else
2025       {
2026          XmListSelectPos(find_rec->matchList, 1, True);
2027          XmProcessTraversal(find_rec->matchList, XmTRAVERSE_CURRENT);
2028       }
2029
2030       _DtTurnOffHourGlass (find_rec->shell);
2031       return(True);
2032    }
2033    else
2034    {
2035       *ptr2 = '\0';
2036       command = GrowBuffer (command, &commandLen, (int) strlen (ptr) + 3);
2037
2038       /* Add buffer to the command string */
2039
2040       (void) strcat (command, ptr);
2041       (void) strcat (command, " ");
2042       *ptr2 = ',';
2043       *ptr2++;
2044       ptr = ptr2;
2045    }
2046
2047    /* Add the redirector for stderr, so it is disabled */
2048
2049    command = GrowBuffer (command, &commandLen, (int) strlen (REDIRECTOR));
2050    (void) strcat (command, REDIRECTOR);
2051
2052
2053    /* Start the 'grep' process */
2054
2055    if ((find_rec->popenId = popen (command, "r")) == NULL)
2056    {
2057       XtFree ((char *) command);
2058       return (False);
2059    }
2060
2061
2062    /* Set up the alternate input source handler */
2063
2064    find_rec->alternateInputId =
2065       XtAddInput (fileno (find_rec->popenId), (XtPointer)XtInputReadMask,
2066                   (XtInputCallbackProc)AlternateInputHandler3, find_rec);
2067
2068    /* printf ("%s\n", command); */
2069
2070    XtFree ((char *) command);
2071
2072    if(ptr == NULL)
2073    {
2074       XtFree(buffer);
2075       buffer = NULL;
2076       ptr = NULL;
2077    }
2078    return (True);
2079 }
2080
2081
2082
2083 /************************************************************************
2084  *
2085  *  AlternateInputHandler()
2086  *      When a 'find' operation is taking place, this function will be
2087  *      invoked whenever the 'find' process has some data to send to us.
2088  *      The function will extract a single line from the pipe, and then
2089  *      add it to the list of matches, if it matches the selected file
2090  *      types.
2091  *
2092  ************************************************************************/
2093
2094 static void
2095 AlternateInputHandler(
2096         XtPointer client_data,
2097         int *source,
2098         XtInputId *id )
2099 {
2100    static int bufSize = 0;
2101    static char * buf = NULL;
2102    FindRec * find_rec = (FindRec *) client_data;
2103    FileMgrData *file_mgr_data;
2104    DialogData * dialog_data;
2105    int offset = 0;
2106    char next;
2107    XmString string;
2108    int count;
2109    Arg args[1];
2110    char * findptr;
2111    char * end;
2112    struct stat stat_data;
2113    int item_count;
2114    char * title;
2115    char * msg;
2116    char * file_type;
2117
2118    /* Abort if the pipe has already been closed */
2119
2120    if (find_rec->popenId == NULL) {
2121       XtSetArg (args[0], XmNdefaultButton, find_rec->start);
2122       XtSetValues (find_rec->form, args, 1);
2123       _DtTurnOffHourGlass (find_rec->shell);
2124       return;
2125    }
2126
2127
2128    /* Allocate some buffer, if this is the first time here */
2129
2130    if (bufSize == 0)
2131    {
2132       bufSize = 512;
2133       buf = XtMalloc (bufSize);
2134    }
2135
2136    dialog_data=_DtGetInstanceData((XtPointer)find_rec->fileMgrRec);
2137    file_mgr_data = (FileMgrData *) dialog_data->data;
2138
2139    /* Extract the next line, upto a NewLine or EOF */
2140
2141    while (1)
2142    {
2143       while ((offset < bufSize - 1) &&
2144           ((count = fread (&next, sizeof (char), 1, find_rec->popenId)) == 1) &&
2145           (next != '\n'))
2146       {
2147           buf[offset++] = next;
2148       }
2149
2150
2151       /* See if we broke out because the buffer needs to grow */
2152
2153       if (offset >= bufSize)
2154       {
2155          bufSize += 512;
2156          buf = XtRealloc (buf, bufSize);
2157          continue;
2158       }
2159
2160
2161       /* Save the string we just extracted */
2162
2163       if (offset > 0)
2164       {
2165          buf[offset] = '\0';
2166          buf = (String) DtEliminateDots (buf);
2167
2168          if ((stat (buf, &stat_data) == 0) ||
2169              (lstat (buf, &stat_data) == 0))
2170          {
2171             findptr = buf;
2172
2173             /* Strip out any invisible files */
2174             if (findptr)
2175             {
2176                file_type = (char *) DtDtsDataToDataType(findptr, NULL, 0, NULL,
2177                                                         NULL, NULL, NULL);
2178                if (_DtCheckForDataTypeProperty(file_type, "invisible"))
2179                   findptr = NULL;
2180             }
2181
2182             /*  Add string to the scrolled list of matches  */
2183             /*  Add to the scrolled list of matches         */
2184
2185             if (findptr &&
2186                     strncmp(desktop_dir, findptr, strlen(desktop_dir)) != 0)
2187             {
2188                if(file_mgr_data->restricted_directory != NULL)
2189                   string = XmStringCreateLocalized (findptr +
2190                          strlen(file_mgr_data->restricted_directory));
2191                else
2192                   string =
2193                          XmStringCreateLocalized (findptr);
2194                XmListAddItemUnselected (find_rec->matchList, string, 0);
2195                XmStringFree (string);
2196             }
2197          }
2198       }
2199
2200       if (count == 0)
2201       {
2202          /* EOF; command is complete */
2203          /* Clean up */
2204
2205          (void) fclose (find_rec->popenId);
2206          find_rec->popenId = NULL;
2207          XtRemoveInput (find_rec->alternateInputId);
2208          XtRemoveEventHandler (find_rec->stop, LeaveWindowMask, FALSE, (XtEventHandler)LeaveStopBttn, find_rec);
2209          XtRemoveEventHandler (find_rec->stop, EnterWindowMask, FALSE, (XtEventHandler)EnterStopBttn, find_rec);
2210          find_rec->alternateInputId = 0;
2211
2212          find_rec->searchInProgress = False;
2213
2214          /* Reset button sensitivity */
2215
2216          XtSetSensitive (find_rec->close, True);
2217          XtSetSensitive (find_rec->start, True);
2218          XtSetSensitive (find_rec->stop, False);
2219
2220          XtSetArg (args[0], XmNitemCount, &item_count);
2221          XtGetValues (find_rec->matchList, args, 1);
2222
2223          XtSetArg (args[0], XmNdefaultButton, find_rec->start);
2224          XtSetValues (find_rec->form, args, 1);
2225
2226          if (item_count == 0)
2227          {
2228             char * tmpStr;
2229
2230             tmpStr = GetSharedMessage(FIND_ERROR_TITLE);
2231             title = XtNewString(tmpStr);
2232             tmpStr = GetSharedMessage(NO_FILES_FOUND_ERROR);
2233             msg = XtNewString(tmpStr);
2234             _DtMessage (find_rec->shell, title, msg, NULL, HelpRequestCB);
2235             XtFree(title);
2236             XtFree(msg);
2237          }
2238          else
2239          {
2240             XmListSelectPos(find_rec->matchList, 1, True);
2241             XmProcessTraversal(find_rec->matchList, XmTRAVERSE_CURRENT);
2242          }
2243
2244          _DtTurnOffHourGlass (find_rec->shell);
2245       }
2246       return;
2247    }
2248 }
2249
2250 static void
2251 AlternateInputHandler2(
2252         XtPointer client_data,
2253         int *source,
2254         XtInputId *id )
2255 {
2256    static int bufSize = 0;
2257    static char * buf = NULL;
2258    FindRec * find_rec = (FindRec *) client_data;
2259    int offset = 0;
2260    char next;
2261    int count;
2262    char * findptr;
2263    struct stat stat_data;
2264    char * content;
2265
2266    content = XmTextFieldGetString (find_rec->fileNameFilter);
2267    if(strcmp(content, "") == 0)
2268       content = XtNewString("*");
2269
2270   /* Abort if the pipe has already been closed */
2271
2272    if (find_rec->popenId == NULL) {
2273       Arg args[1];
2274
2275       _DtTurnOffHourGlass (find_rec->shell);
2276       XtSetArg (args[0], XmNdefaultButton, find_rec->start);
2277       XtSetValues (find_rec->form, args, 1);
2278
2279       return;
2280    }
2281
2282    /* Allocate some buffer, if this is the first time here */
2283
2284    if (bufSize == 0)
2285    {
2286       bufSize = 512;
2287       buf = XtMalloc (bufSize);
2288    }
2289
2290
2291    /* Extract the next line, upto a NewLine or EOF */
2292
2293    while (1)
2294    {
2295       while ((offset < bufSize - 1) &&
2296           ((count = fread (&next, sizeof (char), 1, find_rec->popenId)) == 1) &&
2297           (next != '\n'))
2298       {
2299           buf[offset++] = next;
2300       }
2301
2302
2303       /* See if we broke out because the buffer needs to grow */
2304
2305       if (offset >= bufSize)
2306       {
2307          bufSize += 512;
2308          buf = XtRealloc (buf, bufSize);
2309          continue;
2310      }
2311
2312
2313       /* Save the string we just extracted */
2314
2315       if (offset > 0)
2316       {
2317          buf[offset] = '\0';
2318          buf = (String) DtEliminateDots (buf);
2319
2320          if ((stat (buf, &stat_data) == 0) ||
2321              (lstat (buf, &stat_data) == 0))
2322          {
2323             findptr = buf;
2324
2325             if (findptr)
2326             {
2327                /* save it with the content, */
2328                if(buffer == NULL)
2329                {
2330                   buffer = (char *)XtMalloc(strlen(findptr) + strlen(content) + 3);
2331                   strcpy(buffer, findptr);
2332                }
2333                else
2334                {
2335                   int size;
2336                   size = strlen(findptr) + strlen(buffer) + strlen(content) +4;
2337                   buffer = (char *)XtRealloc(buffer, size);
2338                   strcat(buffer, findptr);
2339                }
2340                strcat(buffer, "/");
2341                strcat(buffer, content);
2342                strcat(buffer, ",");
2343             }
2344          }
2345       }
2346
2347       if (count == 0)
2348       {
2349          /* EOF; command is complete */
2350          /* Clean up */
2351
2352          (void) fclose (find_rec->popenId);
2353          find_rec->popenId = NULL;
2354          XtRemoveInput (find_rec->alternateInputId);
2355          XtRemoveEventHandler (find_rec->stop, LeaveWindowMask, FALSE, (XtEventHandler)LeaveStopBttn, find_rec);
2356          XtRemoveEventHandler (find_rec->stop, EnterWindowMask, FALSE, (XtEventHandler)EnterStopBttn, find_rec);
2357          find_rec->alternateInputId = 0;
2358
2359          ExecuteGrep(find_rec);
2360       }
2361
2362       XtFree(content);
2363       return;
2364    }
2365 }
2366
2367
2368 static void
2369 AlternateInputHandler3(
2370         XtPointer client_data,
2371         int *source,
2372         XtInputId *id )
2373 {
2374    static int bufSize = 0;
2375    static char * buf = NULL;
2376    FindRec * find_rec = (FindRec *) client_data;
2377    FileMgrData *file_mgr_data;
2378    DialogData * dialog_data;
2379    int offset = 0;
2380    char next;
2381    XmString string;
2382    int count;
2383    Arg args[1];
2384    char * findptr;
2385    struct stat stat_data;
2386    int item_count;
2387    char * title;
2388    char * msg;
2389
2390   /* Abort if the pipe has already been closed */
2391
2392    if (find_rec->popenId == NULL) {
2393       _DtTurnOffHourGlass (find_rec->shell);
2394
2395       XtSetArg (args[0], XmNdefaultButton, find_rec->start);
2396       XtSetValues (find_rec->form, args, 1);
2397       return;
2398    }
2399
2400    /* Allocate some buffer, if this is the first time here */
2401
2402    if (bufSize == 0)
2403    {
2404       bufSize = 512;
2405       buf = XtMalloc (bufSize);
2406    }
2407
2408    dialog_data=_DtGetInstanceData((XtPointer)find_rec->fileMgrRec);
2409    file_mgr_data = (FileMgrData *) dialog_data->data;
2410
2411    /* Extract the next line, upto a NewLine or EOF */
2412    while (1)
2413    {
2414       while ((offset < bufSize - 1) &&
2415           ((count = fread (&next, sizeof (char), 1, find_rec->popenId)) == 1) &&
2416           (next != '\n'))
2417       {
2418           buf[offset++] = next;
2419       }
2420
2421
2422       /* See if we broke out because the buffer needs to grow */
2423
2424       if (offset >= bufSize)
2425       {
2426          bufSize += 512;
2427          buf = XtRealloc (buf, bufSize);
2428          continue;
2429      }
2430
2431
2432       /* Save the string we just extracted */
2433
2434       if (offset > 0)
2435       {
2436          buf[offset] = '\0';
2437          buf = (String) DtEliminateDots (buf);
2438
2439          if ((stat (buf, &stat_data) == 0) ||
2440              (lstat (buf, &stat_data) == 0))
2441          {
2442             findptr = buf;
2443
2444             if (findptr)
2445             {
2446                /* Make sure its nots a directory */
2447                if(!((stat_data.st_mode & S_IFMT) == S_IFDIR) &&
2448                      strncmp(desktop_dir, findptr, strlen(desktop_dir)) != 0)
2449                {
2450                   if(file_mgr_data->restricted_directory != NULL)
2451                      string = XmStringCreateLocalized (findptr +
2452                             strlen(file_mgr_data->restricted_directory));
2453                   else
2454                      string =
2455                         XmStringCreateLocalized (findptr);
2456                   XmListAddItemUnselected (find_rec->matchList, string, 0);
2457                   XmStringFree (string);
2458                }
2459             }
2460          }
2461       }
2462
2463       if (count == 0)
2464       {
2465          /* EOF; command is complete */
2466          /* Clean up */
2467
2468          (void) fclose (find_rec->popenId);
2469          find_rec->popenId = NULL;
2470          XtRemoveInput (find_rec->alternateInputId);
2471          XtRemoveEventHandler (find_rec->stop, LeaveWindowMask, FALSE, (XtEventHandler)LeaveStopBttn, find_rec);
2472          XtRemoveEventHandler (find_rec->stop, EnterWindowMask, FALSE, (XtEventHandler)EnterStopBttn, find_rec);
2473          find_rec->alternateInputId = 0;
2474
2475          if(buffer != NULL)
2476             ExecuteGrep(find_rec);
2477          else
2478          {
2479             find_rec->searchInProgress = False;
2480
2481             /* Reset button sensitivity */
2482
2483             XtSetSensitive (find_rec->close, True);
2484             XtSetSensitive (find_rec->start, True);
2485             XtSetSensitive (find_rec->stop, False);
2486
2487             XtSetArg (args[0], XmNitemCount, &item_count);
2488             XtGetValues (find_rec->matchList, args, 1);
2489             XtSetArg (args[0], XmNdefaultButton, find_rec->start);
2490             XtSetValues (find_rec->form, args, 1);
2491
2492             if (item_count == 0)
2493             {
2494                char * tmpStr;
2495
2496                tmpStr = GetSharedMessage(FIND_ERROR_TITLE);
2497                title = XtNewString(tmpStr);
2498                tmpStr = GetSharedMessage(NO_FILES_FOUND_ERROR);
2499                msg = XtNewString(tmpStr);
2500                _DtMessage (find_rec->shell, title, msg, NULL, HelpRequestCB);
2501                XtFree(title);
2502                XtFree(msg);
2503             }
2504             else
2505             {
2506                XmListSelectPos(find_rec->matchList, 1, True);
2507                XmProcessTraversal(find_rec->matchList, XmTRAVERSE_CURRENT);
2508             }
2509
2510             _DtTurnOffHourGlass (find_rec->shell);
2511          }
2512       }
2513
2514       return;
2515    }
2516 }
2517
2518 /************************************************************************
2519  *
2520  *  GetFileName
2521  *      Get host/dir for selected match item
2522  *
2523  ************************************************************************/
2524
2525 static void
2526 GetFileName(
2527         Widget list,
2528         int selectedItem,
2529         String *host,
2530         String *path,
2531         FileMgrData *file_mgr_data)
2532 {
2533    Arg args[2];
2534    int count;
2535    XmString * items;
2536    String temp;
2537    char * tmpptr;
2538
2539    XtSetArg (args[0], XmNitemCount, &count);
2540    XtSetArg (args[1], XmNitems, &items);
2541    XtGetValues (list, args, 2);
2542
2543    temp =  (char *) _XmStringUngenerate(items[selectedItem],
2544                                         XmFONTLIST_DEFAULT_TAG,
2545                                         XmCHARSET_TEXT, XmCHARSET_TEXT);
2546    *host = NULL;
2547    *path = temp;
2548    if(file_mgr_data->restricted_directory != NULL)
2549    {
2550       tmpptr = (char *)XtMalloc(
2551                       strlen(file_mgr_data->restricted_directory) +
2552                                                      strlen(*path) + 1);
2553       strcpy(tmpptr, file_mgr_data->restricted_directory);
2554       strcat(tmpptr, *path);
2555       if(*host == NULL)
2556          XtFree(*path);
2557       *path = (String)tmpptr;
2558    }
2559    else if (*host != NULL)
2560    {
2561       *path = XtNewString(*path);
2562    }
2563 }
2564
2565
2566
2567
2568 /************************************************************************
2569  *
2570  *  ExtractDirectory
2571  *      Check if the path specifies a directory or a file.  If its a
2572  *      file, then extract out the directory portion, since thats all
2573  *      we want.
2574  *
2575  ************************************************************************/
2576
2577 static Boolean
2578 ExtractDirectory(
2579         String host,
2580         String path,
2581         char **file_name )
2582 {
2583    String realPath;
2584    String findptr;
2585    Tt_status tt_status;
2586    struct stat statData;
2587
2588    realPath = (String) ResolveLocalPathName (host, path, NULL, home_host_name, &tt_status);
2589    if( TT_OK != tt_status )
2590      return( False );
2591    else
2592    {
2593      if( stat (realPath, &statData ) != 0 )
2594      {
2595        if( lstat (realPath, &statData) != 0 )
2596        {
2597          XtFree(realPath);
2598          return(False);
2599        }
2600      }
2601    }
2602    XtFree(realPath);
2603
2604    /* Path already is a directory */
2605
2606    if ((statData.st_mode & S_IFMT) == S_IFDIR)
2607    {
2608       *file_name = NULL;
2609       return (True);
2610    }
2611
2612    if(findptr = strrchr (path, '/'))
2613    {
2614      *findptr = '\0';
2615      findptr++;
2616      *file_name = findptr;
2617      return (True);
2618    }
2619    else
2620    {
2621       *file_name = NULL;
2622       return (True);
2623    }
2624 }
2625
2626
2627
2628
2629 /************************************************************************
2630  *
2631  *  NewView
2632  *      Do the real work of viewing a directory.
2633  *
2634  ************************************************************************/
2635
2636 static void
2637 NewView(
2638         Widget widget,
2639         XtPointer client_data,
2640         XtPointer call_data )
2641 {
2642    FindRec       *find_rec;
2643    FileMgrData   *file_mgr_data;
2644    DialogData    *file_mgr_dialog_data;
2645    DialogData    *dialog_data;
2646    DirectorySet  *directory_data;
2647    FileViewData  *file_view_data;
2648    char          *file_name;
2649    String        path, host;
2650    int           j;
2651
2652    find_rec = (FindRec *)client_data;
2653    file_mgr_dialog_data =
2654       (DialogData *) _DtGetInstanceData ((XtPointer) find_rec->fileMgrRec);
2655    file_mgr_data = (FileMgrData *) (file_mgr_dialog_data->data);
2656
2657    GetFileName (find_rec->matchList, find_rec->selectedItem, &host, &path,
2658                                                                file_mgr_data);
2659
2660    dialog_data = NULL;
2661    if (host == NULL)
2662    {
2663       /* No host specified, use the one associated with the view */
2664
2665       if (ExtractDirectory (file_mgr_data->host, path, &file_name))
2666       {
2667          initiating_view = (XtPointer) file_mgr_data;
2668          if(file_mgr_data->restricted_directory == NULL)
2669             dialog_data = GetNewView (file_mgr_data->host, path, NULL, NULL, 0);
2670          else
2671          {
2672             special_view = True;
2673             special_treeType = file_mgr_data->show_type;
2674             special_viewType = file_mgr_data->view;
2675             special_orderType = file_mgr_data->order;
2676             special_directionType = file_mgr_data->direction;
2677             special_randomType = file_mgr_data->positionEnabled;
2678             special_restricted =
2679                    XtNewString(file_mgr_data->restricted_directory);
2680             if(file_mgr_data->title == NULL)
2681                special_title = NULL;
2682             else
2683                special_title = XtNewString(file_mgr_data->title);
2684             special_helpVol = XtNewString(file_mgr_data->helpVol);
2685             if(file_mgr_data->toolbox)
2686                dialog_data = GetNewView (file_mgr_data->host, path,
2687                               file_mgr_data->restricted_directory, NULL, 0);
2688             else
2689                dialog_data = GetNewView (file_mgr_data->host,
2690                                          path, NULL, NULL, 0);
2691          }
2692       }
2693       else
2694         InvalidFindMessage (find_rec, NO_EXISTANCE, NULL);
2695    }
2696    else
2697    {
2698       if (ExtractDirectory (host, path, &file_name))
2699       {
2700          initiating_view = (XtPointer) file_mgr_data;
2701          if(file_mgr_data->restricted_directory == NULL)
2702             dialog_data = GetNewView (host, path, NULL, NULL, 0);
2703          else
2704          {
2705             special_view = True;
2706             special_treeType = file_mgr_data->show_type;
2707             special_viewType = file_mgr_data->view;
2708             special_orderType = file_mgr_data->order;
2709             special_directionType = file_mgr_data->direction;
2710             special_randomType = file_mgr_data->positionEnabled;
2711             special_restricted =
2712                   XtNewString(file_mgr_data->restricted_directory);
2713             if(file_mgr_data->title == NULL)
2714                special_title = NULL;
2715             else
2716                special_title = XtNewString(file_mgr_data->title);
2717             special_helpVol = XtNewString(file_mgr_data->helpVol);
2718             if(file_mgr_data->toolbox)
2719                dialog_data = GetNewView (file_mgr_data->host, path,
2720                                file_mgr_data->restricted_directory, NULL, 0);
2721             else
2722                dialog_data = GetNewView (file_mgr_data->host,
2723                                          path, NULL, NULL, 0);
2724          }
2725       }
2726       else
2727         InvalidFindMessage  (find_rec, NO_EXISTANCE, NULL);
2728    }
2729
2730    if(dialog_data != NULL)
2731    {
2732       file_mgr_data = (FileMgrData *) dialog_data->data;
2733       directory_data = file_mgr_data->directory_set[0];
2734
2735       for (j = 0; j < directory_data->file_count; j++)
2736       {
2737          file_view_data = directory_data->file_view_data[j];
2738
2739          if (file_view_data->filtered != True &&
2740             strcmp(file_name, file_view_data->file_data->file_name) == 0)
2741             {
2742                SelectFile (file_mgr_data, file_view_data);
2743                PositionFileView(file_view_data, file_mgr_data);
2744                break;
2745             }
2746       }
2747       if (!directory_data->file_count)
2748          file_mgr_data->desktop_file = XtNewString(file_name);
2749       else
2750          file_mgr_data->desktop_file = NULL;
2751    }
2752    if(file_mgr_data->selection_list[0] != NULL)
2753       ActivateSingleSelect ((FileMgrRec *) file_mgr_data->file_mgr_rec,
2754                     file_mgr_data->selection_list[0]->file_data->logical_type);
2755
2756    XtFree ((char *) host);
2757    XtFree ((char *) path);
2758 }
2759
2760
2761
2762 /************************************************************************
2763  *
2764  *  FindPutOnDesktop
2765  *      Put the found file/directory on the Desktop
2766  *
2767  ************************************************************************/
2768
2769 static void
2770 FindPutOnDesktop(
2771         Widget widget,
2772         XtPointer client_data,
2773         XtPointer call_data )
2774 {
2775    FindRec *find_rec = (FindRec *)client_data;
2776    FileMgrData   *file_mgr_data;
2777    DialogData    *file_mgr_dialog_data;
2778    char          *file_name;
2779    char          *fileptr;
2780    String        path, host;
2781    Boolean       result;
2782    int EndIndex  = desktop_data->numIconsUsed;
2783
2784    file_mgr_dialog_data =
2785       (DialogData *) _DtGetInstanceData ((XtPointer) find_rec->fileMgrRec);
2786    file_mgr_data = (FileMgrData *) (file_mgr_dialog_data->data);
2787
2788    GetFileName (find_rec->matchList, find_rec->selectedItem, &host, &path,
2789                                                                file_mgr_data);
2790
2791    if (file_mgr_data->toolbox)
2792       path = _DtResolveAppManPath(path, file_mgr_data->restricted_directory);
2793
2794    if( host == NULL)
2795        result =  ExtractDirectory (file_mgr_data->host, path, &file_name);
2796    else
2797        result = ExtractDirectory (host, path, &file_name);
2798
2799    if(!result)
2800    {
2801       InvalidFindMessage (find_rec, NO_EXISTANCE, NULL);
2802       XtFree((char *)path);
2803       XtFree((char *)host);
2804       return;
2805    }
2806
2807    if(file_name == NULL)
2808    {
2809       fileptr = strrchr (path, '/');
2810       *fileptr = '\0';
2811       file_name = fileptr + 1;
2812    }
2813
2814    if( host == NULL)
2815    {
2816       SetupDesktopWindow (XtDisplay(widget), NULL,
2817                           (FileMgrRec *)file_mgr_data->file_mgr_rec,
2818                           file_name, file_mgr_data->host, path, -1, -1,
2819                           file_mgr_data->restricted_directory,EndIndex);
2820    }
2821    else
2822    {
2823       SetupDesktopWindow (XtDisplay(widget), NULL,
2824                           (FileMgrRec *)file_mgr_data->file_mgr_rec,
2825                           file_name, host, path, -1, -1,
2826                           file_mgr_data->restricted_directory,EndIndex);
2827    }
2828    XtFree((char *)path);
2829    XtFree((char *)host);
2830 }
2831
2832 /************************************************************************
2833  *
2834  *  SetActiveItem()
2835  *      Saves the index of the selected item
2836  *
2837  ************************************************************************/
2838
2839 static void
2840 SetActiveItem(
2841         Widget widget,
2842         XtPointer client_data,
2843         XtPointer call_data )
2844 {
2845    FindRec * find_rec = (FindRec *) client_data;
2846    XmListCallbackStruct * cb = (XmListCallbackStruct *) call_data;
2847
2848    find_rec->selectedItem = cb->item_position - 1;
2849
2850    XtSetSensitive (find_rec->newFM, True);
2851    XtSetSensitive (find_rec->putOnDT, True);
2852 }
2853
2854
2855 static void
2856 SetFocus(
2857         FindRec *find_rec,
2858         FindData *find_data )
2859 {
2860    /* Force the focus to the text field */
2861    XmProcessTraversal(find_rec->fileNameFilter, XmTRAVERSE_CURRENT);
2862 }
2863
2864 FILE *
2865 findpopen(cmd,mode,childpid)
2866    char *cmd;
2867    char *mode;
2868    int *childpid;
2869 {
2870    static char *pname = "findpopen";
2871    int     fd[2];
2872    register int parentside, childside;
2873
2874    if(pipe(fd) < 0)
2875         return(NULL);
2876    parentside = (mode[0] == 'r')? fd[0]:fd[1];
2877    childside = (mode[0] == 'r')? fd[1]:fd[0];
2878    if((*childpid = fork()) == 0)
2879    {
2880       int     read_or_write;
2881
2882       DBGFORK(("%s:  child forked, pipe %d\n", pname, childside));
2883
2884       /* Child has to select the stdin or stdout based on the mode */
2885       read_or_write = (mode[0] == 'r')? 1:0;
2886       (void) close(parentside);
2887       /* Dup the stdin or stdout based on the mode */
2888       if ( read_or_write != childside )  /* If what we got is already stdin */
2889       {                                  /* or stdout then no need to close */
2890          (void) close(read_or_write);
2891          (void) fcntl(childside, F_DUPFD, read_or_write);
2892          (void) close(childside);        /* Save a file descriptor */
2893       }
2894       (void) execl(KORNSHELL, "ksh", "-c", cmd, (char *)0);
2895      /* Need to process the error return */
2896
2897       DBGFORK(("%s:  child exiting\n", pname));
2898       exit(1);
2899    }
2900
2901    if(*childpid == -1)
2902       return(NULL);
2903
2904    DBGFORK(("%s:  forked child<%d>, pipe %d\n", pname, childpid, parentside));
2905
2906    (void) close(childside);  /* We don't need child side, so close it */
2907    return(fdopen(parentside, mode));
2908 }