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