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