dtcm: Resolve CID 87408
[oweals/cde.git] / cde / programs / dtcm / libDtCmP / cmfns.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 **
25 **  cmfns.c
26 **
27 **  $XConsortium: cmfns.c /main/3 1995/11/03 10:37:19 rswiston $
28 **
29 **  RESTRICTED CONFIDENTIAL INFORMATION:
30 **
31 **  The information in this document is subject to special
32 **  restrictions in a confidential disclosure agreement between
33 **  HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
34 **  document outside HP, IBM, Sun, USL, SCO, or Univel without
35 **  Sun's specific written approval.  This document and all copies
36 **  and derivative works thereof must be returned or destroyed at
37 **  Sun's request.
38 **
39 **  Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40 **
41 *******************************************************************************/
42
43 /*                                                                      *
44  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
45  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
46  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
47  * (c) Copyright 1993, 1994 Novell, Inc.                                *
48  */
49
50
51 #ifndef lint
52 static  char sccsid[] = "@(#)cmfns.c 1.3 94/11/07 Copyr 1993 Sun Microsystems, Inc.";
53 #endif
54
55 /*
56  * Copyright 1993 Sun Microsystems, Inc.  All rights reserved
57  */
58
59 #ifdef FNS
60
61 #include <EUSCompat.h>
62 #include <sys/stat.h>
63 #include <unistd.h>
64 #include <stdio.h>
65 #include <fcntl.h>
66 #include <string.h>
67 #include <stdlib.h>
68 #include <netdb.h>
69
70 #include "cm_tty.h"
71 #include "debug.h"
72 #include "props.h"
73 #include "dtfns.h"
74 #include "cmfns.h"
75
76 extern char *strdup(const char *);
77 extern FILE     *fdopen(int, const char *);
78
79 /*
80  * Returns 1 if we can use FNS, else 0
81  *
82  * The first call to this routine can be a little costly.  Subsequent calls
83  * are very cheap.  So avoid calling this routine at startup.
84  */
85 int
86 cmfns_use_fns(Props *p)
87
88 {
89         static int      init = 1;
90         static int      fns_available;
91         static boolean_t        use_fns;
92
93         if (init) {
94                 use_fns = convert_boolean_str(get_char_prop(p, CP_USEFNS));
95                 if ((fns_available = dtfns_available()) == -1) {
96                         fns_available = 0;
97                 }
98                 init = 0;
99         }
100
101         if (use_fns && fns_available) {
102                 return 1;
103         } else {
104                 return 0;
105         }
106 }
107
108 /*
109  * Takes an absolute FNS name and attempts to generate an English
110  * description for it.  I.e:
111  *
112  *      org:ssi.eng:user:dipol          -> dipol (in ssi.eng)
113  *      org:ssi.eng:site:b21            -> b21 (a Site in ssi.eng)
114  *      org:ssi.eng                     -> ssi.eng (Organization)
115  *      host:sidewinder                 -> sidewinder (Host)
116  *      dipol                           -> dipol
117  *      dipol@sidewinder                -> dipol@sidewinder
118  *      org:ssi.eng:host:sidewinder     -> sideiwnder (a Host in ssi.eng)
119  *
120  * Returns
121  *              -1      buf not big enough
122  *              0       name is not an FNS name.  No description generated
123  *              1       Success.  Description is paced in buf
124  */
125 int
126 cmfns_description(
127         const char      *name,
128         char*           buf,
129         int             size)   /* FNS name to generate description for */
130
131 {
132         char    *tmp_buf;
133         char    *head;
134         char    *tail;
135         char    *s = NULL;
136         char    *org = NULL;
137         char    len;
138         char    *a_user_in = " (in %s)";
139         char    *a_site_in = " (a Site in %s)";
140         char    *a_host_in = " (a Host in %s)";
141         char    *an_org   = " (Organization)";
142         char    *a_host    = " (Host)";
143         char    *a_site    = " (Site)";
144         char    *thisuser  = "Me";
145         char    *myorg     = "My Organization";
146         char    *hostorg   = "This Host's Organization";
147
148
149         buf[size - 1] = '\0';
150         tmp_buf = strdup(name);
151         head = tmp_buf;
152         if ((tail = strchr(head, DTFNS_SEPERATOR)) == NULL) {
153                 /*
154                  * No colon.  Either one of the special FNS names or
155                  * it is not an FNS name
156                  */
157                 if (strcmp(head, DTFNS_MYORG_NAME) == 0) {
158                         strncpy(buf, myorg, size);
159                 } else if (strcmp(head, DTFNS_HOSTORG_NAME) == 0) {
160                         strncpy(buf, hostorg, size);
161                 } else if (strcmp(head, DTFNS_THISUSER_NAME) == 0) {
162                         strncpy(buf, thisuser, size);
163                 } else {
164                         /* Not an FNS name */
165                         free(tmp_buf);
166                         return 0;
167                 }
168                 goto EXIT;
169         }
170
171         *tail = '\0';
172         tail++;
173
174         if (strcmp(head, DTFNS_ORG_NAME) == 0) {
175                 /* Starts with org:.  Get org */
176                 head = tail;
177                 if ((tail = strchr(head, DTFNS_SEPERATOR)) == NULL) {
178                         /* just org:orgname */
179                         strncpy(buf, head, size);
180                         size -= strlen(buf);
181                         strncat(buf, an_org, size);
182                         goto EXIT;
183                 }
184
185                 *tail = '\0';
186                 org = head;
187                 head = tail + 1;
188
189                 if ((tail = strchr(head, DTFNS_SEPERATOR)) == NULL) {
190                         /*
191                          * Hmmm... We have "org:orgname:something" 
192                          * Just return the description for an organization
193                          */
194                         strncpy(buf, org, size);
195                         size -= strlen(buf);
196                         strncat(buf, an_org, size);
197                         goto EXIT;
198                 }
199
200                 *tail = '\0';
201                 tail++;
202         }
203                         
204         if (strcmp(head, DTFNS_USER_NAME) == 0) {
205                 s = org ? a_user_in : "";
206         } else if (strcmp(head, DTFNS_HOST_NAME) == 0) {
207                 s = org ? a_host_in : a_host;
208         } else if (strcmp(head, DTFNS_SITE_NAME) == 0) {
209                 s = org ? a_site_in : a_site;
210         }
211         
212
213         if (s != NULL) {
214                 strncpy(buf, tail, size);
215                 len = strlen(buf);
216                 size -= len;
217
218                 if (org) {
219                         if (size > (int)(strlen(org) + strlen(s) + 2)) {
220                                 sprintf(buf + len, s, org);
221                         } else {
222                                 /* Buffer too small */
223                                 goto ERROR_EXIT;
224                         }
225                 } else {
226                         strncat(buf, s, size);
227                 }
228         }
229
230 EXIT:
231         free(tmp_buf);
232         return 1;
233
234 ERROR_EXIT:
235
236         free(tmp_buf);
237         return -1;
238 }
239
240 /*
241  *
242  *      Get a calendar address from FNS
243  *
244  *      'name' may  be an absolute Helix name:
245  *              user:smith
246  *              org:ssi.eng:user:smith
247  *              user:smith:service
248  *
249  *      'name' may be an FNS shorthand name:
250  *              dipol
251  *              dipol@ssi.eng
252  *
253  *      'name' may be a calendar address:
254  *              dipol@sidewinder
255  *      In which case it is copied unmodified into addr_buf.
256  *
257  *      'buf' is a buffer provided by the caller in which the calendar address
258  *      is placed.
259  *
260  *      'size' is the size of 'buf'
261  *
262  *
263  * Returns
264  *
265  *      -1      Name not found / Error
266  *      0       FNS not available
267  *      1       Success
268  *
269  */
270 int
271 cmfns_lookup_calendar(
272         const char      *name,
273         char            *addr_buf,
274         int             addr_size
275 )
276
277 {
278         int     rcode;
279         char    fns_name[256];
280         char    *types[4];
281         char    *name_buf;
282         char    *org, *tmp, *p;
283
284         DP(("cmfns_lookup_calendar: Looking up %s\n", name));
285
286         name_buf = strdup(name);
287
288         strncpy(addr_buf, name, addr_size);
289
290         addr_buf[addr_size - 1] = '\0';
291         if ((org = strchr(name_buf, '@')) != NULL) {
292                 /* Either a calendar address or FNS shorthand */
293                 *org = '\0';
294                 org++;
295                 if (gethostbyname(org) != NULL) {
296                         /* Old style address.  Just return it */
297                         free(name_buf);
298                         return 1;
299                 }
300         }
301
302         /* Expand name to point at a calendar service */
303         rcode = dtfns_service_name(name_buf, "user", CMFNS_CALENDAR_SERVICE,
304                 CMFNS_CALENDAR_TYPE, org, fns_name, sizeof(fns_name));
305
306         if (rcode <= 0) {
307                 return rcode;
308         }
309
310         /* Specify the address types we support */
311         types[0] = CMFNS_CALENDAR_ADDR_TYPE;
312         types[1] = "SUNW_calendar";
313         types[2] = "SUNW_cal_deskset";
314         types[3] = NULL;
315
316         /* Get string bound to calendar service name */
317         rcode = dtfns_lookup_str(fns_name, types,  addr_buf, addr_size,
318                         NULL, 0);
319
320         if (rcode <= 0) {
321                 return rcode;
322         }
323
324         if (strchr(addr_buf, '@') == NULL) {
325                 /*
326                  * Just the location (host) is bound in FNS.  Pull
327                  * the name of the object (user) out of the FNS
328                  * name
329                  */
330                 tmp = strdup(addr_buf);
331                 if ((p = strstr(fns_name, ":service:")) == NULL) {
332                         return -1;
333                 }
334
335                 *p = '\0';
336                 while (*p != ':')
337                         p--;
338                 sprintf(addr_buf, "%s@%s", p + 1, tmp);
339         }
340
341         if (org != NULL) {
342                 /*
343                  * Crossing organizations. Is host qualified
344                  * by domain?
345                  */
346                 p = strchr(addr_buf, '@');
347                 p++;
348                 if (strchr(p, '.') == NULL) {
349                         /*
350                          * Host does not appear to have domain
351                          * name.  Add it
352                          */
353                         strcat(addr_buf, ".");
354                         strcat(addr_buf, org);
355                 }
356         }
357
358         DP(("cmfns_lookup_calendar: FNS Lookup complete. address=%s",
359                 addr_buf));
360         return rcode;
361 }
362
363 /*
364  * Register a calendar location in FNS.
365  */
366 int
367 cmfns_register_calendar(const char *username, const char *location)
368
369 {
370         char    buf[256];
371         int     rcode;
372         char    *types[4];
373         char    *user;
374         char    *p;
375
376         user = strdup(username);
377
378         if ((p = strchr(user, '@')) != NULL) {
379                 *p = '\0';
380         }
381
382         DP(("register_calendar: Generating service name for %s\n", user));
383         /* Expand name to point at a calendar service */
384         rcode = dtfns_service_name(user, DTFNS_USER_NAME,
385                 CMFNS_CALENDAR_SERVICE, CMFNS_CALENDAR_TYPE, NULL,
386                 buf, sizeof(buf));
387
388         free(user);
389
390         if (rcode < 1)
391                 return rcode;
392
393         types[0] = CMFNS_CALENDAR_ADDR_TYPE;
394         types[1] = "SUNW_calendar";
395         types[2] = "SUNW_cal_deskset";
396         types[3] = NULL;
397
398         DP(("register_calendar: Binding %s to %s\n", location, buf));
399         return dtfns_bind_str(buf, CMFNS_CALENDAR_TYPE, types, location);
400 }
401 #endif /* FNS */