Fix typo in license headers
[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 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 /*
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, 0, sizeof(Wire));
55
56   tmp_wire->master_name=(XeString)XeMalloc(PTY_NAMLEN);
57   memset(tmp_wire->master_name, 0, PTY_NAMLEN);
58   tmp_wire->slave_name =(XeString)XeMalloc(PTY_NAMLEN);
59   memset(tmp_wire->slave_name,  0, 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 int
100 spc_close(int fd)
101 /*----------------------------------------------------------------------+*/
102 {
103   /* Close a file descriptor which was referenced through an SPC structure */
104   if(fd != -1)
105     close(fd);
106   
107   return(fd);
108   
109 }
110
111 /*----------------------------------------------------------------------+*/
112 int
113 spc_dup2(int from, int to)
114 /*----------------------------------------------------------------------+*/
115 {
116   int retval;
117   
118   /* Dup file descriptors.  If a null descriptor, then use /dev/null */
119   static int devnull = 0;
120
121   if (from == to)
122     return(TRUE);
123   
124   if (from == -1) {
125     _DtSvcProcessLock();
126     if (!devnull)
127       devnull = open("/dev/null", 0);
128     /* Use /dev/null when no source file descriptor */
129     from = devnull;
130     _DtSvcProcessUnlock();
131   }
132   
133   /* Now do the dup2 */
134   retval=dup2(from, to);
135   return(retval);
136 }
137
138 /*----------------------------------------------------------------------+*/
139 int
140 SPC_fd_to_connector(SPC_Channel_Ptr channel,
141                     int fd)
142 /*----------------------------------------------------------------------+*/
143 {
144   if(Stdout(channel) == fd)
145     return(STDOUT);
146   if(Stdin(channel) == fd)
147     return(STDIN);
148   if(Stderr(channel) == fd)
149     return(STDERR);
150   return(ERROR);
151 }
152
153 XeString *Alloc_Argv(int n)
154 {
155   /* Allocate an array to hold argv list */
156   XeString *av;
157   
158   av = (XeString *)XeMalloc((n + 1) * sizeof(XeString));
159   
160   /* Zero the space so we don't have to worry about trailing NULL */
161   memset((XeString) av, 0, (n + 1) * sizeof(XeString));
162   
163   return(av);
164 }
165
166 /*
167  ***
168  *** Toolkit integration stuff, without direct calls to the toolkit.
169  ***
170 */
171
172 int break_on_termination=FALSE;
173
174 /*----------------------------------------------------------------------+*/
175 void SPC_Conditional_Packet_Handler(void      * UNUSED_PARM(client_data),
176                                    int        * source,
177                                    SPCInputId * UNUSED_PARM(id))
178 /*----------------------------------------------------------------------+*/
179 {
180
181   SPC_Channel_Ptr channel;
182   
183   channel = XeSPCHandleTerminator(*source);
184   
185   /* Okay, blast out of our wait */
186   _DtSvcProcessLock();
187   if( (channel==SPC_ERROR || !IS_ACTIVE(channel)) &&
188       break_on_termination)
189     SPC_XtBreak();
190   _DtSvcProcessUnlock();
191   /* return(TRUE); */
192 }
193
194 /*----------------------------------------------------------------------+*/
195 int sprintf_len (XeString s, XeString format, ...)
196 /*----------------------------------------------------------------------+*/
197 {
198   va_list ap;
199
200   va_start(ap, format);
201   if (s) *s = XeChar_NULL;
202   vsprintf(s, format, ap);
203   return(strlen(s));
204 }
205
206 /*
207  ***
208  *** _path_search is a generalized function used for parsing the PATH
209  *** environment variable wrt a passed filename.  It will run down the
210  *** passed path variable looking for ':'.  When it finds one (or hits
211  *** the end of the string), it will concatenate the substring with
212  *** filename, passing the result to the passed path_search_predicate.
213  *** If this predicate returns true, the function will return with a
214  *** true value.  If all elements of the path are processed with no
215  *** true result from the predicate, the function will return false.
216  ***
217  *** A few special cases:
218  ***  - If the filename begins with '/' (an absolute path), the
219  ***    funciton will return the value of the predicate on the
220  ***    filename (e.g. PATH processing will not be done).
221  ***  - a NULL value of any path component will be interpreted as the
222  ***    current directory ('.').
223  ***  - a NULL value for the path parameter means use the PATH
224  ***    environment variable.
225  ***  - a NULL value for filename will return FALSE
226  ***
227 */
228
229 /*
230  ***
231  *** MAXPATHLEN is defined in sbstdinc.h
232  ***
233 */ 
234
235 /*----------------------------------------------------------------------+*/
236 Boolean _path_search (XeString path, XeString filename, path_search_predicate p)
237 /*----------------------------------------------------------------------+*/
238 {
239
240   XeString path_rest, next_colon=NULL;
241   XeChar buffer[MAXPATHLEN+1];
242   XeChar path_component[MAXPATHLEN+1];
243   int path_component_len;
244   int filename_len;
245   int component_seperator=(int)':';  /* this is here because strchr takes an in */
246   
247   if(!filename)
248     return(FALSE);
249   
250   if(*filename == '/')
251     return((*p)(filename, NULL, filename));
252
253   filename_len = strlen(filename);
254   if(!path)
255     path=getenv("PATH");
256
257   for( (path_rest=path ,
258         next_colon=strchr(path_rest, component_seperator));
259       path_rest && *path_rest;
260       next_colon=strchr(path_rest, component_seperator)) {
261     
262     /*
263      ** Copy path component into buffer
264      */
265     
266     if(next_colon) { /* found colon */
267       path_component_len = next_colon-path_rest;
268       strncpy(buffer, path_rest, path_component_len);
269       buffer[path_component_len]='\0';
270       path_rest=next_colon+1;
271       if(!*path_rest)
272         /* We've seen a ':' at the end of the string.  Make path_rest be "."
273            next go-round */
274         path_rest=".";
275     } else {         /* no colon */
276       path_component_len = strlen(path_rest);
277       strcpy(buffer, path_rest);
278       path_rest=NULL;
279     }
280
281     /*
282      ** if path component is NULL, use default ('.');
283      */
284
285     if(!buffer[0]) {
286       buffer[0] = '.';
287       buffer[1] = '\0';
288     }
289     
290     /*
291      ** Concatenate filename
292      */
293
294     if((path_component_len + filename_len + 1) < MAXPATHLEN) {
295       path_component[0]=0;
296       strcat(path_component, buffer);
297       strcat(buffer, "/");
298       strcat(buffer, filename);
299       
300       /*
301        ** Check this file.  If the predicate returns true, we return true.
302        */
303       
304       if((*p)(buffer, path_component, filename))
305         return(TRUE);
306     }
307   }
308
309   /*
310    ** We've checked all components.  Return False.
311    */
312
313   return(FALSE);
314 }