revert between 56095 -> 55830 in arch
[AROS.git] / workbench / network / stacks / AROSTCP / bsdsocket / api / amiga_generic2.c
blob2c6ca8274ad767786640975b73f8a82d88be30ac
1 /*
2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
4 * All rights reserved.
5 * Copyright (C) 2005 - 2007 The AROS Dev Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 * MA 02111-1307, USA.
23 #include <conf.h>
25 #include <aros/libcall.h>
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/syslog.h>
30 #include <sys/errno.h>
32 #include <kern/amiga_includes.h>
34 #include <api/amiga_api.h>
35 #include <api/amiga_libcallentry.h>
36 #include <api/allocdatabuffer.h>
38 #include <api/apicalls.h>
39 #include <api/amiga_kernvars.h>
40 #include <stdarg.h>
42 #include <bsdsocket/socketbasetags.h>
45 * va_set() macro is used to convert from AmigaOS-style arguments array
46 * to standard SVR4 va_list structure. We just fabricate such a structure
47 * where reg_save_area is already ended up and next argument will be
48 * picked up from overflow_arg_area which is our array. Note that we
49 * don't need va_start() and va_end() in this case
51 #ifdef __PPC__
52 #define va_set(ap, args) \
53 ap->gpr = 8; \
54 ap->fpr = 8; \
55 ap->overflow_arg_area = args;
56 #endif
58 #ifdef __x86_64__
59 #define va_set(ap, args) \
60 ap->gp_offset = 48; \
61 ap->fp_offset = 304; \
62 ap->overflow_arg_area = args;
63 #endif
65 #ifdef __arm__
66 #define va_set(ap, args) \
67 ap.__ap = args;
68 #endif
70 #ifndef va_set
71 #define va_set(ap, args) \
72 ap = (va_list)args;
73 #endif
75 extern const char * const __sys_errlist[];
76 extern const int __sys_nerr;
77 extern const char * const h_errlist[];
78 extern const int h_nerr;
79 extern const char * const io_errlist[];
80 extern const short io_nerr;
81 extern const char * const sana2io_errlist[];
82 extern const short sana2io_nerr;
83 extern const char * const sana2wire_errlist[];
84 extern const short sana2wire_nerr;
85 extern STRPTR version;
86 extern struct kernel_var kvars[];
88 /*LONG Errno(
89 REG(a6, struct SocketBase *libPtr))*/
90 AROS_LH0(LONG, Errno,
91 struct SocketBase *, libPtr, 27, UL)
93 AROS_LIBFUNC_INIT
94 return (LONG)readErrnoValue(libPtr);
95 AROS_LIBFUNC_EXIT
98 LONG __SetErrnoPtr(VOID *err_p, UBYTE size, struct SocketBase *libPtr)
100 if (size == 4 || size == 2 || size == 1) {
101 if (size & 0x1 || !((IPTR)err_p & 0x1)) { /* either odd size or address even */
102 libPtr->errnoSize = size;
103 libPtr->errnoPtr = err_p;
104 return 0;
108 writeErrnoValue(libPtr, EINVAL);
109 return -1;
112 AROS_LH2(LONG, SetErrnoPtr,
113 AROS_LHA(VOID *, err_p, A0),
114 AROS_LHA(UBYTE, size, D0),
115 struct SocketBase *, libPtr, 28, UL)
117 AROS_LIBFUNC_INIT
118 return __SetErrnoPtr(err_p, size, libPtr);
119 AROS_LIBFUNC_EXIT
122 /*VOID SAVEDS Syslog(
123 REG(d0, ULONG pri),
124 REG(a0, const char *fmt),
125 REG(a1, va_list ap),
126 REG(a6, struct SocketBase *libPtr))*/
127 AROS_LH3(VOID, Syslog,
128 AROS_LHA(ULONG, pri, D0),
129 AROS_LHA(const char *, fmt, A0),
130 AROS_LHA(IPTR *, ap, A1),
131 struct SocketBase *, libPtr, 43, UL)
133 AROS_LIBFUNC_INIT
134 int saved_errno;
135 char fmt_cpy[1024];
136 char tag_cpy[256];
137 va_list _ap;
138 register char *p = fmt_cpy;
139 char *t = NULL;
140 char *t1;
142 CHECK_TASK_VOID();
144 va_set(_ap, ap);
146 /* check for invalid bits or no priority set */
147 if (!LOG_PRI(pri)) {
148 DSYSLOG(KPrintF("Priority is zero\n");)
149 return;
151 if (pri &~ (LOG_PRIMASK|LOG_FACMASK)) {
152 DSYSLOG(KPrintF("Bad bits in priority/facility value 0x%08lx\n", pri);)
153 return;
155 if (!(LOG_MASK(LOG_PRI(pri)) & libPtr->LogMask)) {
156 DSYSLOG(KPrintF("Priority value %lu is masked out\n", LOG_PRI(pri));)
157 return;
160 saved_errno = readErrnoValue(libPtr);
161 if (saved_errno >= __sys_nerr)
162 saved_errno = 0; /* XXX */
164 /* set default facility if none specified */
165 if ((pri & LOG_FACMASK) == 0)
166 pri |= libPtr->LogFacility;
168 if (libPtr->LogTag) {
169 DSYSLOG(KPrintF("LogTag: %s", libPtr->LogTag);)
170 t = tag_cpy;
171 t1 = tag_cpy;
172 t1 += sprintf(t1, "%s", libPtr->LogTag);
174 DSYSLOG(else KPrintF("LogTag: <NULL>");)
175 DSYSLOG(KPrintF(", message: %s\n", fmt);)
176 if (libPtr->LogStat & LOG_PID) {
177 if (!t) {
178 t = tag_cpy;
179 t1 = tag_cpy;
181 sprintf(t1, "[%p]", libPtr->thisTask);
185 * Build the new format string
187 /*if (libPtr->LogTag) {
188 p += sprintf(p, libPtr->LogTag);
190 if (libPtr->LogStat & LOG_PID) {
191 p += sprintf(p, "[%lx]", libPtr->thisTask);
193 if (libPtr->LogTag) {
194 *p++ = ':';
195 *p++ = ' ';
198 * Substitute error message for %m.
201 char ch;
202 const char *t2;
204 for (t1 = p; ch = *fmt; ++fmt) {
205 if (ch == '%') {
206 if (fmt[1] == '%') {
207 ++fmt;
208 *t1++ = ch;
210 else if (fmt[1] == 'm') {
211 ++fmt;
212 for (t2 = __sys_errlist[saved_errno]; *t1 = *t2++; ++t1)
214 continue;
217 *t1++ = ch;
219 *t1 = '\0';
221 vlog(pri, t, fmt_cpy, _ap);
222 AROS_LIBFUNC_EXIT
225 /*VOID SAVEDS SetSocketSignals(
226 REG(d0, ULONG sigintrmask),
227 REG(d1, ULONG sigiomask),
228 REG(d2, ULONG sigurgmask),
229 REG(a6, struct SocketBase *libPtr))*/
230 AROS_LH3(VOID, SetSocketSignals,
231 AROS_LHA(ULONG, sigintrmask, D0),
232 AROS_LHA(ULONG, sigiomask, D1),
233 AROS_LHA(ULONG, sigurgmask, D2),
234 struct SocketBase *, libPtr, 22, UL)
236 AROS_LIBFUNC_INIT
237 CHECK_TASK_VOID();
238 DSYSCALLS(log(LOG_DEBUG,"SetSocketSignals(0x%08lx, 0x%08lx, 0x%08lx) called", sigintrmask, sigiomask, sigurgmask);)
240 * The operations below are atomic so no need to protect them
242 libPtr->sigIntrMask = sigintrmask;
243 libPtr->sigIOMask = sigiomask;
244 libPtr->sigUrgMask = sigurgmask;
245 AROS_LIBFUNC_EXIT
248 /*LONG getdtablesize(
249 REG(a6, struct SocketBase *libPtr))*/
250 AROS_LH0(LONG, getdtablesize,
251 struct SocketBase *, libPtr, 23, UL)
253 AROS_LIBFUNC_INIT
254 DSYSCALLS(log(LOG_DEBUG,"getdtablesize(): returned %ld", libPtr->dTableSize);)
255 return (LONG)libPtr->dTableSize;
256 AROS_LIBFUNC_EXIT
259 static int getLastSockFd(struct SocketBase *libPtr)
261 int bit, lastmlong = (libPtr->dTableSize - 1) / NFDBITS;
262 ULONG *smaskp, cmask, rmask;
264 for (smaskp = (ULONG *)(libPtr->dTable + libPtr->dTableSize + lastmlong);
265 lastmlong >= 0; smaskp--, lastmlong--)
266 if (*smaskp)
267 break;
269 if (lastmlong < 0)
270 return -1;
272 cmask = *smaskp;
273 if ((rmask = cmask & 0xFFFF0000)) { bit = 16; cmask = rmask; }
274 else bit = 0;
275 if ((rmask = cmask & 0xFF00FF00)) { bit += 8; cmask = rmask; }
276 if ((rmask = cmask & 0xF0F0F0F0)) { bit += 4; cmask = rmask; }
277 if ((rmask = cmask & 0xCCCCCCCC)) { bit += 2; cmask = rmask; }
278 if ((rmask = cmask & 0xAAAAAAAA)) bit += 1;
280 return lastmlong * 32 + bit;
284 * Set size of descriptor tab|e
286 static LONG
287 setdtablesize(struct SocketBase * libPtr, UWORD size)
290 LONG oldsize = (LONG)libPtr->dTableSize;
291 LONG copysize;
292 struct socket ** dTable;
293 int olddmasksize, copydmasksize, dmasksize;
295 if (size < oldsize) {
296 int i;
298 if ((i = getLastSockFd(libPtr)) > size)
299 size = i + 1;
300 copysize = size;
302 else
303 copysize = oldsize;
305 olddmasksize = (oldsize - 1) / NFDBITS + 1;
306 copydmasksize = (copysize - 1) / NFDBITS + 1;
307 dmasksize = (size - 1) / NFDBITS + 1;
309 if ((dTable = AllocMem(size * sizeof (struct socket *) +
310 dmasksize * sizeof (fd_mask),
311 MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
312 return oldsize;
314 aligned_bcopy(libPtr->dTable, dTable, copysize * sizeof (struct socket *));
315 aligned_bcopy(libPtr->dTable + oldsize, dTable + size,
316 copydmasksize * sizeof (fd_mask));
318 FreeMem(libPtr->dTable, oldsize * sizeof (struct socket *) +
319 olddmasksize * sizeof (fd_mask));
321 libPtr->dTable = dTable;
322 libPtr->dTableSize = size;
324 return size;
327 #ifdef __GNUC__
328 /* GNU C 4.x and higher really don't like to
329 * have the l-value type-punned
331 #define IPTR_ASSIGN(s,v) s = (__typeof__(s))(v)
332 #define LONG_ASSIGN(s,v) IPTR_ASSIGN(s, v)
333 #else
334 #define IPTR_ASSIGN(s, v) *(IPTR *)(s) = v
335 #define LONG_ASSIGN(s, v) *(LONG *)(s) = v
336 #endif
338 #define CASE_IPTR(code, baseField)\
339 case (code << SBTB_CODE): /* get */ \
340 *tagData = (IPTR)libPtr->baseField;\
341 break;\
342 case (code << SBTB_CODE) | SBTF_SET: /* set */\
343 IPTR_ASSIGN(libPtr->baseField, *(tagData));\
344 break
346 #define CASE_LONG(code, baseField)\
347 case (code << SBTB_CODE): /* get */ \
348 *tagData = (LONG)libPtr->baseField;\
349 break;\
350 case (code << SBTB_CODE) | SBTF_SET: /* set */\
351 LONG_ASSIGN(libPtr->baseField, *(tagData));\
352 break
354 #define CASE_WORD(code, baseField)\
355 case (code << SBTB_CODE): /* get */ \
356 *tagData = (ULONG)libPtr->baseField;\
357 break;\
358 case (code << SBTB_CODE) | SBTF_SET: /* set */\
359 *(UWORD *)&libPtr->baseField = (UWORD)*tagData;\
360 break
362 #define CASE_BYTE(code, baseField)\
363 case (code << SBTB_CODE): /* get */ \
364 *tagData = (ULONG)libPtr->baseField;\
365 break;\
366 case (code << SBTB_CODE) | SBTF_SET: /* set */\
367 *(UBYTE *)&libPtr->baseField = (UBYTE)*tagData;\
368 break
370 #define CASE_FLAG(code, flag)\
371 case (code << SBTB_CODE): /* get */ \
372 *tagData = ((ULONG)libPtr->flags & (flag)) != 0;\
373 break;\
374 case (code << SBTB_CODE) | SBTF_SET: /* set */\
375 if (*tagData) \
376 *(UBYTE *)&libPtr->flags |= (flag);\
377 else \
378 *(UBYTE *)&libPtr->flags &= ~(flag);\
379 break
381 /****** bsdsocket.library/SocketBaseTagList ***********************************
383 NAME
384 SocketBaseTagList - Set/Get SocketBase attributes.
386 SYNOPSIS
387 #include <amitcp/socketbasetags.h>
389 ULONG SocketBaseTagList(struct TagItem *);
391 error = SocketBaseTagList(taglist)
392 D0 A0
394 error = SocketBaseTags(ULONG tag, ...);
396 FUNCTION
397 Set or get a list of (mostly) SocketBase instance dependent attributes
398 from the AmiTCP.
400 INPUTS
401 These functions expect as their argument a standard tag list, one or
402 several array of struct TagItem as defined in the header file
403 <utility/tagitem.h>. The structure contains two fields: ti_Tag and
404 ti_Data. The ti_Tag field contains tag code, which determines what
405 the SocketBaseTagList() should do with its argument, the ti_Data
406 field.
408 The include file <amitcp/socketbasetags.h> defines macros for base tag
409 code values. Base tag code macros begin with `SBTC_' (as Socket Base
410 Tag Code). The base tag value defines what data item the tag item
411 refers.
413 The tag code contains other information besides the referred data
414 item. It controls, whether the SocketBaseTagList() should set or get
415 the appropriate parameter, and whether the argument of the tag in
416 question is passed by value or by reference.
418 The include file <amitcp/socketbasetags.h> defines the following
419 macros, which are used to construct the ti_Tag values from the base
420 tag codes:
422 SBTM_GETREF(code) - get by reference
423 SBTM_GETVAL(code) - get by value
424 SBTM_SETREF(code) - set by reference
425 SBTM_SETVAL(code) - set by value
427 If the actual data is stored directly into the ti_Data field, you
428 should use the 'by value' macros, SBTM_GETVAL() or SBTM_SETVAL().
429 However, if the ti_Data field contains a pointer to actual data, you
430 should use the 'by reference' macros, SBTM_GETREF() or SBTM_SETREF().
431 In either case the actual data should always be a LONG aligned to even
432 address.
434 According the used tag naming scheme a tag which has "PTR" suffix
435 takes an pointer as its argument. Don't mix the pointer arguments
436 with 'by reference' argument passing. It is possible to pass a
437 pointer by reference (in which case the ti_Data is a pointer to the
438 actual pointer).
440 The list of all defined base tag codes is as follows:
442 SBTC_BREAKMASK Tag data contains the INTR signal mask. If
443 the calling task receives a signal in the
444 INTR mask, the AmiTCP interrupts current
445 function calls and returns with the error
446 code EINTR. The INTR mask defaults to the
447 CTRL-C signal (SIGBREAKF_C, bit 12).
449 SBTC_DTABLESIZE Socket Descriptor Table size. This
450 defaults to 64.
452 SBTC_ERRNO The errno value. The values are defined in
453 <sys/errno.h>.
455 SBTC_ERRNOBYTEPTR
456 SBTC_ERRNOWORDPTR
457 SBTC_ERRNOLONGPTR
458 SBTC_ERRNOPTR(size) Set (only) the pointer to the errno
459 variable defined by the program. AmiTCP
460 defines a value for this by default, but
461 the application must set the pointer (and
462 the size of the errno) with one of these
463 tags, if it wishes to access the errno
464 variable directly.
466 The SBTC_ERRNOPTR(size) is a macro, which
467 expands to one of the other (BYTE, WORD or
468 LONG) tag codes, meaning that only 1, 2
469 and 4 are legal size values.
471 The netlib autoinit.c sets the errno
472 pointer for the application, if the
473 application is linked with it.
475 SBTC_ERRNOSTRPTR Returns an error string pointer describing
476 the errno value given on input. You can not
477 set the error message, only get is allowed.
479 On call the ti_Data must contain the error
480 code number. On return the ti_Data is
481 assigned to the string pointer. (*ti_Data,
482 if passed by reference). See the file
483 <sys/errno.h> for symbolic definitions for
484 the errno codes.
486 SBTC_FDCALLBACK A callback function pointer for coordination
487 of file descriptor usage between AmiTCP and
488 link-library. By default no callback is
489 called and the value of this pointer is
490 NULL. The prototype for the callback
491 function is:
493 int error = fdCallback(int fd, int action);
494 D0 D0 D1
496 where
498 error - 0 for success or one of the error
499 codes in <sys/errno.h> in case of
500 error. The AmiTCP API function
501 that calls the callback usually
502 returns the 'error' back to the
503 caller without any further
504 modification.
506 fd - file descriptor number to take
507 'action' on.
509 action - one of the following actions
510 (defined in
511 <amitcp/socketbasetags.h>):
513 FDCB_FREE - mark the 'fd' as
514 unused on the link
515 library structure. If
516 'fd' represents a
517 file handled by the
518 link library, the
519 error (ENOTSOCK)
520 should be returned.
522 FDCB_ALLOC - mark the 'fd'
523 allocated as a
524 socket.
526 FDCB_CHECK - check if the 'fd' is
527 free. If an error is
528 returned, the 'fd' is
529 marked as used in the
530 AmiTCP/IP structures.
532 The AmiTCP/IP calls the callback every time
533 a socket descriptor is allocated or freed.
534 AmiTCP/IP uses the FDCB_CHECK before actual
535 allocation to check that it agrees with the
536 link library on the next free descriptor
537 number. Thus the link library doesn't need
538 to tell the AmiTCP if it creates a new file
539 handle in open(), for example.
541 See file _chkufb.c on the net.lib sources
542 for an example implementation of the
543 callback function for the SAS/C.
545 SBTC_HERRNO The name resolver error code value. Get
546 this to find out why the gethostbyname()
547 or gethostbyaddr() failed. The values are
548 defined in <netdb.h>
550 SBTC_HERRNOSTRPTR Returns host error string for error number
551 in tag data. Host error is set on
552 unsuccesful gethostbyname() and
553 gethostbyaddr() calls. See the file
554 <netdb.h> for the symbolic definitions for
555 the herrno valus.
557 Notes for the SBTC_ERRNOSTRPTR apply also
558 to this tag code.
560 SBTC_IOERRNOSTRPTR Returns an error string for standard
561 AmigaOS I/O error number as defined in the
562 header file <exec/errors.h>. Note that the
563 error number taken by this tag code is
564 positive, so the error codes must be
565 negated (to be positive). The positive
566 error codes depend on the particular IO
567 device, the standard Sana-II error codes
568 can be retrieved by the tag code
569 SBTC_S2ERRNOSTRPTR.
571 Notes for the SBTC_ERRNOSTRPTR apply also
572 to this tag code.
574 SBTC_LOGFACILITY Facility code for the syslog messages as
575 defined in the header file <sys/syslog.h>.
576 Defaults to LOG_USER.
578 SBTC_LOGMASK Sets the filter mask of the syslog
579 messages. By default the mask is 0xff,
580 meaning that all messages are passed to the
581 log system.
583 SBTC_LOGSTAT Syslog options defined in <sys/syslog.h>.
585 SBTC_LOGTAGPTR A pointer to a string which is used by
586 syslog() to mark individual syslog
587 messages. This defaults to NULL, but is
588 set to the name of the calling program by
589 the autoinit code in netlib:autoinit.c.
590 This is for compatibility with pre-3.0
591 programs.
593 SBTC_S2ERRNOSTRPTR Returns an error string for a Sana-II
594 specific I/O error code as defined in the
595 header file <devices/sana2.h>.
597 Notes for the SBTC_ERRNOSTRPTR apply also
598 to this tag code.
600 SBTC_S2WERRNOSTRPTR Returns an error string for a Sana-II Wire
601 Error code as defined in the header file
602 <devices/sana2.h>.
604 Notes for the SBTC_ERRNOSTRPTR apply also
605 to this tag code.
607 SBTC_SIGIOMASK The calling task is sent the signals
608 specified by mask in tag data when
609 asynhronous I/O is to be notified. The
610 default value is zero, ie. no signal is
611 sent.
613 SBTC_SIGURGMASK The calling task is sent the signals
614 specified by mask in tag data when urgent
615 data for the TCP arrives. The default value
616 is zero, ie. no signal is sent.
618 RESULT
619 Returns 0 on success, and a (positive) index of the failing tag on
620 error. Note that the value 1 means _first_ TagItem, 2 the second one,
621 and so on. The return value is NOT a C-language index, which are 0
622 based.
624 EXAMPLES
625 To be written, see net.lib sources for various examples.
627 NOTES
629 BUGS
630 None known.
632 SEE ALSO
633 <netinclude:amitcp/socketbasetags.h>, <include:utility/tagitem.h>
635 *****************************************************************************
638 #ifdef notyet
640 SBTC_COMPAT43 Tag data is handled as boolean. If it is
641 true, AmiTCP/IP uses 4.3BSD compatible
642 sockaddr structure for this application.
644 The unreleased AS225r2 uses also 4.3BSD-
645 compatible sockaddr structures.
648 #endif
650 /*ULONG SAVEDS SocketBaseTagList(
651 REG(a0, struct TagItem *tags),
652 REG(a6, struct SocketBase *libPtr))*/
653 AROS_LH1(ULONG, SocketBaseTagList,
654 AROS_LHA(struct TagItem *, tags, A0),
655 struct SocketBase *, libPtr, 49, UL)
657 AROS_LIBFUNC_INIT
658 ULONG errIndex = 1;
659 IPTR tag;
660 IPTR *tagData;
661 short tmp;
662 UWORD utmp;
664 static const char * const strErr = "Errlist lookup error";
666 CHECK_TASK();
668 while((tag = tags->ti_Tag) != TAG_END) {
669 if (tag & TAG_USER) { /* TAG_USER is the sign bit */
670 /* get pointer to the actual data */
671 tagData = ((UWORD)tag & SBTF_REF) ?
672 (IPTR *)tags->ti_Data : &tags->ti_Data;
674 #ifdef DEBUG_EVENTS
675 if (((UWORD)tag & ~(SBTF_REF)) == ((SBTC_SIGEVENTMASK << SBTB_CODE) | SBTF_SET))
676 log(LOG_DEBUG,"SBTC_SIGEVENTMASK set to 0x%08lx", *tagData);
677 #endif
679 switch ((UWORD)tag & ~SBTF_REF) {
681 CASE_LONG( SBTC_BREAKMASK, sigIntrMask );
683 CASE_LONG( SBTC_SIGIOMASK, sigIOMask );
685 CASE_LONG( SBTC_SIGURGMASK, sigUrgMask );
687 CASE_LONG( SBTC_SIGEVENTMASK, sigEventMask );
689 case (SBTC_ERRNO << SBTB_CODE): /* get */
690 *tagData = (IPTR)readErrnoValue(libPtr);
691 break;
692 case (SBTC_ERRNO << SBTB_CODE) | SBTF_SET: /* set */
693 writeErrnoValue(libPtr, *tagData);
694 break;
696 case (SBTC_HERRNO << SBTB_CODE): /* get */
697 *tagData = (IPTR)*libPtr->hErrnoPtr;
698 break;
699 case (SBTC_HERRNO << SBTB_CODE) | SBTF_SET: /* set */
700 *libPtr->hErrnoPtr = (IPTR) *tagData;
701 break;
703 case (SBTC_DTABLESIZE << SBTB_CODE): /* get */
704 *tagData = (IPTR)libPtr->dTableSize;
705 break;
706 case (SBTC_DTABLESIZE << SBTB_CODE) | SBTF_SET: /* set */
707 if ((tmp = (WORD)*tagData) > 0)
708 setdtablesize(libPtr, tmp);
709 break;
711 CASE_IPTR( SBTC_FDCALLBACK, fdCallback );
713 CASE_BYTE( SBTC_LOGSTAT, LogStat );
715 CASE_IPTR( SBTC_LOGTAGPTR, LogTag );
717 case (SBTC_LOGFACILITY << SBTB_CODE): /* get */
718 *tagData = (ULONG)libPtr->LogFacility;
719 break;
720 case (SBTC_LOGFACILITY << SBTB_CODE) | SBTF_SET: /* set */
721 if ((utmp = (UWORD)*tagData) != 0 && (utmp &~ LOG_FACMASK) == 0)
722 libPtr->LogFacility = utmp;
723 break;
725 case (SBTC_LOGMASK << SBTB_CODE): /* get */
726 *tagData = (ULONG)libPtr->LogMask;
727 break;
728 case (SBTC_LOGMASK << SBTB_CODE) | SBTF_SET: /* set */
729 if ((utmp = (UWORD)*tagData) != 0)
730 libPtr->LogMask = (UBYTE)utmp;
731 break;
733 case SBTC_ERRNOSTRPTR << SBTB_CODE:
734 /* get index */
735 utmp = (UWORD)*tagData;
736 /* return string pointer */
737 *tagData = (IPTR)((utmp >= __sys_nerr) ?
738 strErr : __sys_errlist[utmp]);
739 break;
740 case SBTC_HERRNOSTRPTR << SBTB_CODE:
741 /* get index */
742 utmp = (UWORD)*tagData;
743 /* return string pointer */
744 *tagData = (IPTR)((utmp >= h_nerr) ?
745 strErr : h_errlist[utmp]);
746 break;
747 case SBTC_IOERRNOSTRPTR << SBTB_CODE:
748 /* get index */
749 utmp = (UWORD)*tagData;
750 /* return string pointer */
751 *tagData = (IPTR)((utmp >= io_nerr) ?
752 strErr : io_errlist[utmp]);
753 break;
754 case SBTC_S2ERRNOSTRPTR << SBTB_CODE:
755 /* get index */
756 utmp = (UWORD)*tagData;
757 /* return string pointer */
758 *tagData = (IPTR)((utmp >= sana2io_nerr) ?
759 strErr : sana2io_errlist[utmp]);
760 break;
761 case SBTC_S2WERRNOSTRPTR << SBTB_CODE:
762 /* get index */
763 utmp = (UWORD)*tagData;
764 /* return string pointer */
765 *tagData = (IPTR)((utmp >= sana2wire_nerr) ?
766 strErr : sana2wire_errlist[utmp]);
767 break;
769 case (SBTC_ERRNOBYTEPTR << SBTB_CODE) | SBTF_SET: /* set */
770 if (__SetErrnoPtr((VOID *)*tagData, 1, libPtr) < 0)
771 return errIndex;
772 break;
773 case (SBTC_ERRNOWORDPTR << SBTB_CODE) | SBTF_SET: /* set */
774 if (__SetErrnoPtr((VOID *)*tagData, 2, libPtr) < 0)
775 return errIndex;
776 break;
777 case (SBTC_ERRNOLONGPTR << SBTB_CODE) | SBTF_SET: /* set */
778 if (__SetErrnoPtr((VOID *)*tagData, 4, libPtr) < 0)
779 return errIndex;
780 break;
782 CASE_IPTR( SBTC_HERRNOLONGPTR, hErrnoPtr );
784 case (SBTC_RELEASESTRPTR << SBTB_CODE): /* get */
785 *tagData = (IPTR)&version[6];
786 break;
788 #ifdef notyet
789 CASE_FLAG( SBTC_COMPAT43, SBFB_COMPAT43 );
790 #endif
792 default:
793 return errIndex;
796 else { /* TAG_USER not set */
797 switch(tags->ti_Tag) {
798 case TAG_IGNORE:
799 break;
800 case TAG_MORE:
801 tags = (struct TagItem *)tags->ti_Data;
802 errIndex++;
803 continue;
804 case TAG_SKIP:
805 tags++; errIndex++;
806 break;
807 default:
808 return errIndex; /* fail */
812 tags++; errIndex++;
814 return 0;
815 AROS_LIBFUNC_EXIT