2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
24 * $TOG: spc-error.c /main/10 1998/04/10 08:27:30 mgreess $
27 * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
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. *
35 #include <Dt/UserMsg.h>
37 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
42 #include <bms/MemoryMgr.h> /* NOTE: sbport.h must be the first include. */
44 #define X_INCLUDE_TIME_H
45 #define XOS_USE_XT_LOCKING
46 #include <X11/Xos_r.h>
48 #include "DtSvcLock.h"
51 * Log file information (routines near bottom of file)
54 #define TEMPLATE_EXTENSION (XeString)".XXXXXX" /* For mktemp(3c) */
56 XeChar spc_logfile[MAXPATHLEN+1];
57 XeChar spc_logging = FALSE;
58 /* FILE *spc_logF = NULL; -- to bmsglob.c */
62 /* This is the SPC error number variable */
63 /* ------------------------------------- */
64 /* int XeSPCErrorNumber = NULL; --- now in bmsglob.c */
66 /*------------------------------------------------------------------------+*/
68 err_mnemonic(unsigned int errn, char *buff)
69 /*------------------------------------------------------------------------+*/
71 /* Since there is currently no standard way to get an err number */
72 /* mnenonic from the system, we do it the hard way. We can't even */
73 /* use a table as the actual numeric values may differ on machines. */
74 /* Another potential problem is if one of these gets passed across */
75 /* a network connection from a different type of machine that has */
76 /* values that differ than the machine this routine runs on, we */
77 /* could have problems. I don't think anycode does that now. */
78 /* ---------------------------------------------------------------- */
84 /* These are all in POSIX 1003.1 and/or X/Open XPG3 */
85 /* ---------------------------------------------------- */
86 case EPERM : s = (XeString)"EPERM"; break;
87 case ENOENT : s = (XeString)"ENOENT"; break;
88 case ESRCH : s = (XeString)"ESRCH"; break;
89 case EINTR : s = (XeString)"EINTR"; break;
90 case EIO : s = (XeString)"EIO"; break;
91 case ENXIO : s = (XeString)"ENXIO"; break;
92 case E2BIG : s = (XeString)"E2BIG"; break;
93 case ENOEXEC : s = (XeString)"ENOEXEC"; break;
94 case EBADF : s = (XeString)"EBADF"; break;
95 case ECHILD : s = (XeString)"ECHILD"; break;
96 case EAGAIN : s = (XeString)"EAGAIN"; break;
97 case ENOMEM : s = (XeString)"ENOMEM"; break;
98 case EACCES : s = (XeString)"EACCES"; break;
99 case EFAULT : s = (XeString)"EFAULT"; break;
100 case ENOTBLK : s = (XeString)"ENOTBLK"; break;
101 case EBUSY : s = (XeString)"EBUSY"; break;
102 case EEXIST : s = (XeString)"EEXIST"; break;
103 case EXDEV : s = (XeString)"EXDEV"; break;
104 case ENODEV : s = (XeString)"ENODEV"; break;
105 case ENOTDIR : s = (XeString)"ENOTDIR"; break;
106 case EISDIR : s = (XeString)"EISDIR"; break;
107 case EINVAL : s = (XeString)"EINVAL"; break;
108 case ENFILE : s = (XeString)"ENFILE"; break;
109 case EMFILE : s = (XeString)"EMFILE"; break;
110 case ENOTTY : s = (XeString)"ENOTTY"; break;
111 case ETXTBSY : s = (XeString)"ETXTBSY"; break;
112 case EFBIG : s = (XeString)"EFBIG"; break;
113 case ENOSPC : s = (XeString)"ENOSPC"; break;
114 case ESPIPE : s = (XeString)"ESPIPE"; break;
115 case EROFS : s = (XeString)"EROFS"; break;
116 case EMLINK : s = (XeString)"EMLINK"; break;
117 case EPIPE : s = (XeString)"EPIPE"; break;
118 case ENOMSG : s = (XeString)"ENOMSG"; break;
119 case EIDRM : s = (XeString)"EIDRM"; break;
120 case EDEADLK : s = (XeString)"EDEADLK"; break;
121 case ENOLCK : s = (XeString)"ENOLCK"; break;
123 case ENOTEMPTY : s = (XeString)"ENOTEMPTY"; break;
125 case ENAMETOOLONG : s = (XeString)"ENAMETOOLONG"; break;
126 case ENOSYS : s = (XeString)"ENOSYS"; break;
128 /* You could include machine specific stuff here ... */
129 /* ---------------------------------------------------- */
132 /* ---------------------------------------------------- */
133 default : s = XeString_NULL; break;
138 sprintf(buff, "%s (%d)",s,errn);
140 sprintf(buff, "(%d)",errn);
145 /*----------------------------------------------------------------------+*/
146 XeString SPC_copy_string(XeString str)
147 /*----------------------------------------------------------------------+*/
153 return(XeString_NULL);
157 tmp_str=(XeString)XeMalloc(len+1);
158 strcpy(tmp_str, str);
162 /*----------------------------------------------------------------------+*/
163 void SPC_Error (int error, ...)
164 /*----------------------------------------------------------------------+*/
173 err=SPC_Lookup_Error(error);
183 va_start(ap, error); /** Start varargs **/
184 arg1=va_arg(ap, XeString);
188 /* The argument on the stack may be holding an int or a char pointer. */
189 /* Always popping off a long into the value of arg2 works fine */
190 /* because the subsequent call to sprintf does the proper conversion via */
192 arg2=va_arg(ap, long);
196 arg1 = XeString_Empty;
200 buffer = (XeChar*) malloc(sizeof(XeChar) * SPC_BUFSIZ);
203 sprintf(buffer, err->format, arg1, arg2);
204 err->text=SPC_copy_string(buffer);
207 va_end(ap); /** End varargs **/
210 XeSPCErrorNumber=error;
211 if (SPC_who_am_i == SPC_I_AM_A_DAEMON){
213 SPC_Format_Log((XeString)"DTSPCD error (%d): %s",
214 XeSPCErrorNumber, err->text);
218 unsigned int errn = errno;
220 errname = err_mnemonic(errn, buff);
222 if (!(errmsg = strerror(errn)))
223 errmsg = (XeString) "unknown";
225 SPC_Format_Log((XeString)" [%s] %s", errname, errmsg);
227 if(err->severity == XeFatalError || err->severity == XeInternalError) {
228 SPC_Format_Log((XeString)"Exiting server ...");
230 _DtSvcProcessUnlock();
235 _DtSimpleError(XeProgName, XeError, XeString_NULL, err->text);
237 _DtSvcProcessUnlock();
244 * Note: Current restriction of only one log file open at a time.
247 /*----------------------------------------------------------------------+*/
249 SPC_Make_Log_Filename(XeString name,
250 int unique) /* When TRUE, make name unique */
251 /*----------------------------------------------------------------------+*/
253 /* Make a log filename based on the passed name (and perhaps process id) */
255 XeString log_file_path = NULL;
258 /* first build the log file path */
259 if (!name || !*name) {
260 log_file_path = XeSBTempPath((XeString)"DTSPCD_log");
261 strcpy(spc_logfile, log_file_path);
264 if (strlen(name) > MAXPATHLEN)
265 _DtSimpleError(XeProgName, XeInternalError, XeString_NULL,
266 (XeString)"String too long in DTSPCD_Make_Log_Filename()");
268 strcpy(spc_logfile, name);
272 /* Add the extension. No strlen checking is done */
273 strcat(spc_logfile, TEMPLATE_EXTENSION);
275 cp = (XeString) mktemp(spc_logfile);
277 /* Sorry, but this is the best we can do */
278 strcpy(spc_logfile, (log_file_path) ? log_file_path : name);
282 /* free the strings allocated for the path */
283 if (log_file_path) XeFree(log_file_path);
284 _DtSvcProcessUnlock();
288 /*----------------------------------------------------------------------+*/
290 SPC_Open_Log(XeString filename,
291 int unique) /* When TRUE, make filename unique */
292 /*----------------------------------------------------------------------+*/
294 /* Open the SPC log file */
296 /* Use the filename if one was passed to make a log filename */
297 SPC_Make_Log_Filename(filename, unique);
299 /* Open the logfile */
301 spc_logF = fopen(spc_logfile, "a+");
303 _DtSvcProcessUnlock();
308 SPC_Format_Log((XeString)"*** DTSPCD logging started, file: `%s'", spc_logfile);
310 _DtSvcProcessUnlock();
314 /*----------------------------------------------------------------------+*/
317 /*----------------------------------------------------------------------+*/
319 /* Close the current log file */
321 SPC_Format_Log((XeString)"*** DTSPCD logging stopped");
331 _DtSvcProcessUnlock();
335 /*----------------------------------------------------------------------+*/
337 SPC_Write_Log(XeString str)
338 /*----------------------------------------------------------------------+*/
340 /* Write the passed message to the log file */
342 _Xctimeparams ctime_buf;
346 if (spc_logging && spc_logF) {
348 result = _XCtime(&t, ctime_buf);
349 fprintf(spc_logF, "%s: %s", str, result);
353 _DtSvcProcessUnlock();
358 /*----------------------------------------------------------------------+*/
359 int SPC_Format_Log (XeString format, ...)
360 /*----------------------------------------------------------------------+*/
362 /* Format the passed message to the log file */
365 _Xctimeparams ctime_buf;
369 if (spc_logging && spc_logF) {
370 /* First the message */
371 va_start(args, format);
372 vfprintf(spc_logF, format, args);
375 /* Now a time stamp */
377 result = _XCtime(&t, ctime_buf);
378 fprintf(spc_logF, ": %s", result);
382 _DtSvcProcessUnlock();
388 ** This next routine used to be such a nice little guy... Once upon a
389 ** time I had all the error messages in a very
390 ** compact representation. It was a vector of SPCError structures.
391 ** When I wanted to go from the integer representation of an error to
392 ** its textual form, I simply did a table lookup. Unfortunately,
393 ** that method did not work at all well with the NLS scheme cooked up
394 ** by the Excalibur team. This scheme was nice for programs which
395 ** just had the strings in the text. It basically searched the
396 ** source program for a string with a funny symbol and replaced it
397 ** with a function call. Well, to make a long story short, I decided
398 ** to go with that scheme. Thus this function.
402 SPCError spc_error_struct;
404 /*----------------------------------------------------------------------+*/
405 SPCError *SPC_Lookup_Error(int errornum)
406 /*----------------------------------------------------------------------+*/
411 case SPC_Out_Of_Memory:
412 spc_error_struct.format = (XeString) "><Unable to allocate memory for internal SPC operation\n Perhaps you need to add more swap space to the system";
413 spc_error_struct.severity = XeFatalError;
414 spc_error_struct.use_errno = FALSE;
417 case SPC_Bad_Argument:
418 spc_error_struct.format = (XeString) "><Bad argument to DTSPCD call";
419 spc_error_struct.severity = XeError;
420 spc_error_struct.use_errno = FALSE;
423 case SPC_Active_Channel:
424 spc_error_struct.format = (XeString) "><Channel already active";
425 spc_error_struct.severity = XeError;
426 spc_error_struct.use_errno = FALSE;
429 case SPC_Inactive_Channel:
430 spc_error_struct.format = (XeString) "><Channel is not active";
431 spc_error_struct.severity = XeError;
432 spc_error_struct.use_errno = FALSE;
435 case SPC_Internal_Error:
436 spc_error_struct.format = (XeString) "><Internal SPC Error";
437 spc_error_struct.severity = XeError;
438 spc_error_struct.use_errno = FALSE;
441 case SPC_Cannot_Fork:
442 spc_error_struct.format = (XeString) "><Cannot fork";
443 spc_error_struct.severity = XeError;
444 spc_error_struct.use_errno = TRUE;
447 case SPC_Cannot_Exec:
448 spc_error_struct.format = (XeString) "><Cannot exec file %s.\nPerhaps your PATH variable is incorrect.\nUse the following errno value to further diagnose the problem.";
449 spc_error_struct.severity = XeError;
450 spc_error_struct.use_errno = TRUE;
454 spc_error_struct.format = (XeString) "><Cannot get pipe";
455 spc_error_struct.severity = XeError;
456 spc_error_struct.use_errno = TRUE;
460 spc_error_struct.format = (XeString) "><Unable to allocate pty for a DTSPCD channel.\nTry cleaning up some currently running processes to release their ptys,\nor reconfigure your kernel to increase the pty limit.";
461 spc_error_struct.severity = XeError;
462 spc_error_struct.use_errno = TRUE;
465 case SPC_Bad_Connector:
466 spc_error_struct.format = (XeString) "><Bad connector";
467 spc_error_struct.severity = XeError;
468 spc_error_struct.use_errno = FALSE;
472 spc_error_struct.format = (XeString) "><Unexpected error reading data on connection to host %s.\nUse the following errno value to correct the problem.";
473 spc_error_struct.severity = XeError;
474 spc_error_struct.use_errno = TRUE;
478 spc_error_struct.format = (XeString) "><Unexpected error writing data on channel";
479 spc_error_struct.severity = XeError;
480 spc_error_struct.use_errno = TRUE;
483 case SPC_Bad_Service:
484 spc_error_struct.format = (XeString) "><Unknown internet service %s/%s.\nMake an entry in your /etc/services file";
485 spc_error_struct.severity = XeError;
486 spc_error_struct.use_errno = TRUE;
489 case SPC_Unknown_Host:
490 spc_error_struct.format = (XeString) "><Unable to find a host entry for %s.\nTry adding an entry in /etc/hosts for it.";
491 spc_error_struct.severity = XeError;
492 spc_error_struct.use_errno = FALSE;
496 spc_error_struct.format = (XeString) "><Socket failed";
497 spc_error_struct.severity = XeError;
498 spc_error_struct.use_errno = TRUE;
501 case SPC_Bad_Connect:
502 spc_error_struct.format = (XeString) "><Connect call failed to remote host %s\nPerhaps the desktop is not installed on the remote host,\nor the remote inetd program needs to be restarted (via 'inetd -c'),\nor the remote file /etc/inetd.conf does not have an entry for the dtspcd process.\n";
503 spc_error_struct.severity = XeError;
504 spc_error_struct.use_errno = FALSE;
508 spc_error_struct.format = (XeString) "><Bind failed";
509 spc_error_struct.severity = XeError;
510 spc_error_struct.use_errno = TRUE;
514 spc_error_struct.format = (XeString) "><Accept failed";
515 spc_error_struct.severity = XeError;
516 spc_error_struct.use_errno = TRUE;
520 spc_error_struct.format = (XeString) "><Reuse socket option failed";
521 spc_error_struct.severity = XeError;
522 spc_error_struct.use_errno = TRUE;
526 spc_error_struct.format = (XeString) "><Cannot open file";
527 spc_error_struct.severity = XeError;
528 spc_error_struct.use_errno = TRUE;
531 case SPC_Connection_EOF:
532 if (SPC_who_am_i == SPC_I_AM_A_DAEMON)
533 spc_error_struct.format = (XeString) "><Client has disconnected (received EOF).";
535 spc_error_struct.format = (XeString) "><The dtspcd process on host '%s' has terminated.";
536 spc_error_struct.severity = XeError;
537 spc_error_struct.use_errno = FALSE;
541 spc_error_struct.format = (XeString) "><Internal timeout expired";
542 spc_error_struct.severity = XeError;
543 spc_error_struct.use_errno = FALSE;
547 spc_error_struct.format = (XeString) "><Illegal protocol request";
548 spc_error_struct.severity = XeError;
549 spc_error_struct.use_errno = FALSE;
552 case SPC_Unexpected_Reply:
553 spc_error_struct.format = (XeString) "><Protocol error: unexpected reply";
554 spc_error_struct.severity = XeError;
555 spc_error_struct.use_errno = FALSE;
559 spc_error_struct.format = (XeString) "><Cannot initialize channel";
560 spc_error_struct.severity = XeError;
561 spc_error_struct.use_errno = FALSE;
564 case SPC_Illegal_Iomode:
565 spc_error_struct.format = (XeString) "><Inconsistent iomode value specified";
566 spc_error_struct.severity = XeError;
567 spc_error_struct.use_errno = FALSE;
570 case SPC_No_Signal_Handler:
571 spc_error_struct.format = (XeString) "><Cannot set SIGCLD handler";
572 spc_error_struct.severity = XeError;
573 spc_error_struct.use_errno = TRUE;
576 case SPC_Bad_Operation:
577 spc_error_struct.format = (XeString) "><Illegal operation";
578 spc_error_struct.severity = XeError;
579 spc_error_struct.use_errno = FALSE;
583 spc_error_struct.format = (XeString) "><Bad file descriptor";
584 spc_error_struct.severity = XeError;
585 spc_error_struct.use_errno = FALSE;
589 spc_error_struct.format = (XeString) "><ioctl call failed";
590 spc_error_struct.severity = XeError;
591 spc_error_struct.use_errno = TRUE;
595 spc_error_struct.format = (XeString) "><select call failed";
596 spc_error_struct.severity = XeError;
597 spc_error_struct.use_errno = TRUE;
600 case SPC_Bind_Timeout:
601 spc_error_struct.format = (XeString) "><Timeout on bind";
602 spc_error_struct.severity = XeWarning;
603 spc_error_struct.use_errno = FALSE;
606 case SPC_Arg_Too_Long:
607 spc_error_struct.format = (XeString) "><Argument %.50s... to DTSPCD system call is too long, max. length is %d";
608 spc_error_struct.severity = XeError;
609 spc_error_struct.use_errno = FALSE;
613 spc_error_struct.format = (XeString) "><Error writing protocol request to host %s.\nPerhaps the remote server has crashed.\nUse the following errno value to diagnose the problem.";
614 spc_error_struct.severity = XeError;
615 spc_error_struct.use_errno = TRUE;
618 case SPC_Bad_Username:
619 spc_error_struct.format = (XeString) "><Incorrect user name";
620 spc_error_struct.severity = XeFatalError;
621 spc_error_struct.use_errno = FALSE;
624 case SPC_Bad_Password:
625 spc_error_struct.format = (XeString) "><Incorrect password";
626 spc_error_struct.severity = XeFatalError;
627 spc_error_struct.use_errno = FALSE;
630 case SPC_Client_Not_Valid:
631 spc_error_struct.format = (XeString) "><Client not valid";
632 spc_error_struct.severity = XeError;
633 spc_error_struct.use_errno = FALSE;
636 case SPC_Cannot_Open_Slave:
637 spc_error_struct.format = (XeString) "><Unable to open slave pty %s.\nUse the following errno value to correct the problem";
638 spc_error_struct.severity = XeError;
639 spc_error_struct.use_errno = TRUE;
642 case SPC_Protocol_Abort:
643 spc_error_struct.format = (XeString) "><Received ABORT protocol request on connection to %s.";
644 spc_error_struct.severity = XeFatalError;
645 spc_error_struct.use_errno = FALSE;
648 case SPC_Env_Too_Big:
649 spc_error_struct.format = (XeString) "><Environment variable %.50s... too big,\nmaximum size is %d\n";
650 spc_error_struct.severity = XeError;
651 spc_error_struct.use_errno = FALSE;
654 case SPC_Unlink_Logfile:
655 spc_error_struct.format = (XeString) "><Cannot unlink logfile";
656 spc_error_struct.severity = XeError;
657 spc_error_struct.use_errno = TRUE;
660 case SPC_Closed_Channel:
661 spc_error_struct.format = (XeString) "><Channel already closed";
662 spc_error_struct.severity = XeError;
663 spc_error_struct.use_errno = FALSE;
666 case SPC_Bad_Authentication:
667 spc_error_struct.format = (XeString) "><Cannot open user authentication file";
668 spc_error_struct.severity = XeFatalError;
669 spc_error_struct.use_errno = FALSE;
672 case SPC_Cannot_Open_Log:
673 spc_error_struct.format = (XeString) "><Unable to open log file %s\nUse the following errno value to correct the problem";
674 spc_error_struct.severity = XeError;
675 spc_error_struct.use_errno = FALSE;
678 case SPC_Connection_Reset:
679 spc_error_struct.format = (XeString) "><Remote data connection to %s reset by peer\nRemote host may not have an entry for the local host in /usr/adm/inetd.sec.";
680 spc_error_struct.severity = XeError;
681 spc_error_struct.use_errno = FALSE;
684 case SPC_Register_Username:
685 spc_error_struct.format = (XeString) "><Cannot register user --\nImproper password or uid for user '%s' on remote host '%s'.";
686 spc_error_struct.severity = XeError;
687 spc_error_struct.use_errno = FALSE;
690 case SPC_Register_Netrc:
691 spc_error_struct.format = (XeString) "><Cannot register user --\nUnable to create a pathname to the authentication file '%s' on host '%s'.";
692 spc_error_struct.severity = XeError;
693 spc_error_struct.use_errno = FALSE;
696 case SPC_Register_Open:
697 spc_error_struct.format = (XeString) "><Cannot register user --\nUnable to open authentication file '%s' on host '%s'.\nUse the following errno value to diagnose the problem.";
698 spc_error_struct.severity = XeError;
699 spc_error_struct.use_errno = TRUE;
702 case SPC_Register_Handshake:
703 spc_error_struct.format = (XeString) "><Cannot register user --\nPerhaps user '%s' does not have the same uid on host '%s'.";
704 spc_error_struct.severity = XeError;
705 spc_error_struct.use_errno = FALSE;
708 case SPC_Bad_Termios_Mode :
709 spc_error_struct.format = (XeString) "><An error has been detected in the TERMIOS_REQUEST data.\nThe item '%s' is not recognized as a valid item for the Mode flags.\nThe item has been ignored.\n";
710 spc_error_struct.severity = XeError;
711 spc_error_struct.use_errno = FALSE;
714 case SPC_Bad_Termios_Speed :
715 spc_error_struct.format = (XeString) "><An error has been detected in the TERMIOS_REQUEST data.\nThe item '%s' is not recognized as a valid item for a speed setting.\nThe item has been ignored.\n";
716 spc_error_struct.severity = XeError;
717 spc_error_struct.use_errno = FALSE;
720 case SPC_Bad_Termios_CC :
721 spc_error_struct.format = (XeString) "><An error has been detected in the TERMIOS_REQUEST data.\nThe item '%s' is not recognized as a valid item for a Control Character name/value pair.\nThe item has been ignored.\n";
722 spc_error_struct.severity = XeError;
723 spc_error_struct.use_errno = FALSE;
726 case SPC_Bad_Termios_Proto :
727 spc_error_struct.format = (XeString) "><An error has been detected in the TERMIOS_REQUEST data.\nThe string does not have the correct number of fields -- %s.\n";
728 spc_error_struct.severity = XeError;
729 spc_error_struct.use_errno = FALSE;
732 case SPC_Bad_Signal_Name :
733 spc_error_struct.format = (XeString) "><The signal '%s' is not supported on this machine.\nThe DTSPCD signal request has been ignored.\n";
734 spc_error_struct.severity = XeError;
735 spc_error_struct.use_errno = FALSE;
738 case SPC_Bad_Signal_Value :
739 spc_error_struct.format = (XeString) "><The signal %d is not supported by the XeSignalToName() routine.\nIt can not be sent via DTSPCD to a remote machine.\n";
740 spc_error_struct.severity = XeError;
741 spc_error_struct.use_errno = FALSE;
744 case SPC_Bad_Signal_Format :
745 spc_error_struct.format = (XeString) "><The APPLICATION_SIGNAL DTSPCD data '%s' is not recognized.\nIt is expected to be a signal name or a signal number.\n";
746 spc_error_struct.severity = XeError;
747 spc_error_struct.use_errno = FALSE;
750 case SPC_Bad_tc_Call :
751 spc_error_struct.format = (XeString) "><The terminal control call to '%s' failed.";
752 spc_error_struct.severity = XeError;
753 spc_error_struct.use_errno = TRUE;
756 case SPC_cannot_Chdir :
757 spc_error_struct.format = (XeString) "><Cannot cd to directory '%s'.";
758 spc_error_struct.severity = XeError;
759 spc_error_struct.use_errno = TRUE;
762 case SPC_Bad_Permission :
763 spc_error_struct.format = (XeString) "><Incorrect permission on DTSPCD Authentication file.";
764 spc_error_struct.severity = XeError;
765 spc_error_struct.use_errno = TRUE;
768 case SPC_Cannot_Create_Netfilename :
769 spc_error_struct.format = (XeString) "><Cannot create a pathname to the current working\ndirectory '%s' from host '%s'.";
770 spc_error_struct.severity = XeError;
771 spc_error_struct.use_errno = FALSE;
774 case SPC_Protocol_Version_Error:
775 spc_error_struct.format = (XeString) "><SPC protocol version mismatch. The local version is %d, but the version of the SPC Daemon is %d. This operation requires equivalent protocol versions.";
776 spc_error_struct.severity = XeError;
777 spc_error_struct.use_errno = FALSE;
780 /* JET - buffer overflow attempt */
782 case SPC_Buffer_Overflow:
783 spc_error_struct.format = (XeString) "><Attempted Buffer Overflow from host %s.\nConnection dropped.";
784 spc_error_struct.severity = XeError;
785 spc_error_struct.use_errno = FALSE;
790 spc_error_struct.format = (XeString) "><Unknown error code";
791 spc_error_struct.severity = XeError;
792 spc_error_struct.use_errno = FALSE;
796 _DtSvcProcessUnlock();
797 return(&spc_error_struct);