f934e23495e80d354bb8f854f69c1c642845464b
[oweals/cde.git] / cde / lib / DtSvc / DtEncap / spc-util.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * File:         spc-util.c $XConsortium: spc-util.c /main/5 1996/06/21 17:33:16 ageorge $
25  * Language:     C
26  *
27  * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
28  *
29  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
30  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
31  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
32  * (c) Copyright 1993, 1994 Novell, Inc.                                *
33  */
34
35 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
36 #include <stdarg.h>
37
38 #include <SPC/spcP.h>
39 #include <bms/MemoryMgr.h>
40 #include "DtSvcLock.h"
41
42 /* The application's SPC activation list */
43 SPC_Channel_Ptr spc_activation_list = NULL;
44
45 /* Allocate us up a wire */
46
47 /*----------------------------------------------------------------------+*/
48 Wire *get_new_wire(void)
49 /*----------------------------------------------------------------------+*/
50 {
51   Wire *tmp_wire;
52
53   tmp_wire=(Wire *)XeMalloc(sizeof(Wire));
54   memset(tmp_wire, NULL, sizeof(Wire));
55
56   tmp_wire->master_name=(XeString)XeMalloc(PTY_NAMLEN);
57   memset(tmp_wire->master_name, NULL, PTY_NAMLEN);
58   tmp_wire->slave_name =(XeString)XeMalloc(PTY_NAMLEN);
59   memset(tmp_wire->slave_name,  NULL, PTY_NAMLEN);
60   tmp_wire->fd[0] = tmp_wire->fd[1] = (-1);
61   tmp_wire->read_toolkit_id   = (-1);
62   tmp_wire->except_toolkit_id = (-1);
63   return(tmp_wire);
64 }
65
66 /*----------------------------------------------------------------------+*/
67 void free_wire(Wire *wire)
68 /*----------------------------------------------------------------------+*/
69 {
70   free(wire->master_name);
71   free(wire->slave_name);
72   free((char *)wire);
73 }
74
75 /*
76  * Channel object access
77  */
78
79 /*----------------------------------------------------------------------+*/
80 SPC_Channel_Ptr SPC_Find_PID(int pid)
81 /*----------------------------------------------------------------------+*/
82 {
83   /* Attempt to return a channel which currently handles process number PID */
84   SPC_Channel_Ptr spc;
85
86   _DtSvcProcessLock();
87   for (spc = spc_activation_list; spc != NULL; spc = spc->next) {
88     if (spc->pid == pid) break;
89   }
90   _DtSvcProcessUnlock();
91   return spc;                   /* NULL when not found */
92 }
93
94 /*
95  * Miscellaneous
96  */
97
98 /*----------------------------------------------------------------------+*/
99 spc_close(int fd)
100 /*----------------------------------------------------------------------+*/
101 {
102   /* Close a file descriptor which was referenced through an SPC structure */
103   if(fd != -1)
104     close(fd);
105   
106   return(fd);
107   
108 }
109
110 /*----------------------------------------------------------------------+*/
111 spc_dup2(int from, int to)
112 /*----------------------------------------------------------------------+*/
113 {
114   int retval;
115   
116   /* Dup file descriptors.  If a null descriptor, then use /dev/null */
117   static int devnull = NULL;
118
119   if (from == to)
120     return(TRUE);
121   
122   if (from == -1) {
123     _DtSvcProcessLock();
124     if (!devnull)
125       devnull = open("/dev/null", 0);
126     /* Use /dev/null when no source file descriptor */
127     from = devnull;
128     _DtSvcProcessUnlock();
129   }
130   
131   /* Now do the dup2 */
132   retval=dup2(from, to);
133   return(retval);
134 }
135
136 /*----------------------------------------------------------------------+*/
137 SPC_fd_to_connector(SPC_Channel_Ptr channel,
138                     int fd)
139 /*----------------------------------------------------------------------+*/
140 {
141   if(Stdout(channel) == fd)
142     return(STDOUT);
143   if(Stdin(channel) == fd)
144     return(STDIN);
145   if(Stderr(channel) == fd)
146     return(STDERR);
147   return(ERROR);
148 }
149
150 XeString *Alloc_Argv(int n)
151 {
152   /* Allocate an array to hold argv list */
153   XeString *av;
154   
155   av = (XeString *)XeMalloc((n + 1) * sizeof(XeString));
156   
157   /* Zero the space so we don't have to worry about trailing NULL */
158   memset((XeString) av, NULL, (n + 1) * sizeof(XeString));
159   
160   return(av);
161 }
162
163 /*
164  ***
165  *** Toolkit integration stuff, without direct calls to the toolkit.
166  ***
167 */
168
169 int break_on_termination=FALSE;
170
171 /*----------------------------------------------------------------------+*/
172 void SPC_Conditional_Packet_Handler(void      * UNUSED_PARM(client_data),
173                                    int        * source,
174                                    SPCInputId * UNUSED_PARM(id))
175 /*----------------------------------------------------------------------+*/
176 {
177
178   SPC_Channel_Ptr channel;
179   
180   channel = XeSPCHandleTerminator(*source);
181   
182   /* Okay, blast out of our wait */
183   _DtSvcProcessLock();
184   if( (channel==SPC_ERROR || !IS_ACTIVE(channel)) &&
185       break_on_termination)
186     SPC_XtBreak();
187   _DtSvcProcessUnlock();
188   /* return(TRUE); */
189 }
190
191 /*----------------------------------------------------------------------+*/
192 int sprintf_len (XeString s, XeString format, ...)
193 /*----------------------------------------------------------------------+*/
194 {
195   va_list ap;
196
197   va_start(ap, format);
198   if (s) *s = XeChar_NULL;
199   vsprintf(s, format, ap);
200   return(strlen(s));
201 }
202
203 /*
204  ***
205  *** _path_search is a generalized function used for parsing the PATH
206  *** environment variable wrt a passed filename.  It will run down the
207  *** passed path variable looking for ':'.  When it finds one (or hits
208  *** the end of the string), it will concatenate the substring with
209  *** filename, passing the result to the passed path_search_predicate.
210  *** If this predicate returns true, the function will return with a
211  *** true value.  If all elements of the path are processed with no
212  *** true result from the predicate, the function will return false.
213  ***
214  *** A few special cases:
215  ***  - If the filename begins with '/' (an absolute path), the
216  ***    funciton will return the value of the predicate on the
217  ***    filename (e.g. PATH processing will not be done).
218  ***  - a NULL value of any path component will be interpreted as the
219  ***    current directory ('.').
220  ***  - a NULL value for the path parameter means use the PATH
221  ***    environment variable.
222  ***  - a NULL value for filename will return FALSE
223  ***
224 */
225
226 /*
227  ***
228  *** MAXPATHLEN is defined in sbstdinc.h
229  ***
230 */ 
231
232 /*----------------------------------------------------------------------+*/
233 Boolean _path_search (XeString path, XeString filename, path_search_predicate p)
234 /*----------------------------------------------------------------------+*/
235 {
236
237   XeString path_rest, next_colon=NULL;
238   XeChar buffer[MAXPATHLEN+1];
239   XeChar path_component[MAXPATHLEN+1];
240   int path_component_len;
241   int filename_len;
242   int component_seperator=(int)':';  /* this is here because strchr takes an in */
243   
244   if(!filename)
245     return(FALSE);
246   
247   if(*filename == '/')
248     return((*p)(filename, NULL, filename));
249
250   filename_len = strlen(filename);
251   if(!path)
252     path=getenv("PATH");
253
254   for( (path_rest=path ,
255         next_colon=strchr(path_rest, component_seperator));
256       path_rest && *path_rest;
257       next_colon=strchr(path_rest, component_seperator)) {
258     
259     /*
260      ** Copy path component into buffer
261      */
262     
263     if(next_colon) { /* found colon */
264       path_component_len = next_colon-path_rest;
265       strncpy(buffer, path_rest, path_component_len);
266       buffer[path_component_len]=NULL;
267       path_rest=next_colon+1;
268       if(!*path_rest)
269         /* We've seen a ':' at the end of the string.  Make path_rest be "."
270            next go-round */
271         path_rest=".";
272     } else {         /* no colon */
273       path_component_len = strlen(path_rest);
274       strcpy(buffer, path_rest);
275       path_rest=NULL;
276     }
277
278     /*
279      ** if path component is NULL, use default ('.');
280      */
281
282     if(!buffer[0]) {
283       buffer[0] = '.';
284       buffer[1] = NULL;
285     }
286     
287     /*
288      ** Concatenate filename
289      */
290
291     if((path_component_len + filename_len + 1) < MAXPATHLEN) {
292       path_component[0]=0;
293       strcat(path_component, buffer);
294       strcat(buffer, "/");
295       strcat(buffer, filename);
296       
297       /*
298        ** Check this file.  If the predicate returns true, we return true.
299        */
300       
301       if((*p)(buffer, path_component, filename))
302         return(TRUE);
303     }
304   }
305
306   /*
307    ** We've checked all components.  Return False.
308    */
309
310   return(FALSE);
311 }