/* source: xiohelp.c */ /* Copyright Gerhard Rieger and contributors (see file CHANGES) */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for the help function */ #include "xiosysincludes.h" #include "xioopen.h" #include "xiohelp.h" #if WITH_HELP /* keep consistent with xioopts.h:enum e_types ! */ static const char *optiontypenames[] = { "CONST", "BIN", "BOOL", "BYTE", "INT", "INT/NULL", "LONG", "STRING", "PTRDIFF", "SHORT", "SIZE_T", "SOCKADDR", "UNSIGNED-INT", "UNSIGNED-LONG","UNSIGNED-SHORT","MODE_T", "GID_T", "UID_T", "INT[3]", "STRUCT-TIMEVAL", "STRUCT-TIMESPEC", "DOUBLE", "STRING-NULL", "LONG-LONG", "OFF_T", "OFF64_T", "INT:INT", "INT:INTP", "INT:BIN", "INT:STRING", "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING", "INT:INT:GENERIC", "IP4NAME", "IP4SOCK", #if HAVE_STRUCT_LINGER "STRUCT-LINGER", #endif #if HAVE_STRUCT_IP_MREQN "STRUCT-IP_MREQN", #elif HAVE_STRUCT_IP_MREQ "STRUCT-IP_MREQ", #endif #if HAVE_STRUCT_IP_MREQ_SOURCE "IP-MREQ-SOURCE", #endif "GENERIC", } ; /* keep consistent with xioopts.h:#define GROUP_* ! */ static const char *addressgroupnames[] = { "FD", "FIFO", "CHR", "BLK", "REG", "SOCKET", "READLINE", "undef", "NAMED", "OPEN", "EXEC", "FORK", "LISTEN", "SHELL", "CHILD", "RETRY", "TERMIOS", "RANGE", "PTY", "PARENT", "UNIX", "IP4", "IP6", "INTERFACE", "UDP", "TCP", "SOCKS", "OPENSSL", "PROCESS", "APPL", "HTTP", "undef", "POSIXMQ", "SCTP", "DCCP", "UDPLITE" } ; /* keep consistent with xioopts.h:enum ephase ! */ static char *optionphasenames[] = { "ALL", "INIT", "EARLY", "PREOPEN", "OPEN", "PASTOPEN", "PRESOCKET", "SOCKET", "PASTSOCKET", "PREBIGEN", "BIGEN", "PASTBIGEN", "FD", "PREBIND", "BIND", "PASTBIND", "PRELISTEN", "LISTEN", "PASTLISTEN", "PRECONNECT", "CONNECT", "PASTCONNECT", "PREACCEPT", "ACCEPT", "PASTACCEPT", "CONNECTED", "PREFORK", "FORK", "PASTFORK", "LATE", "LATE2", "PREEXEC", "EXEC", "PASTEXEC", "SPECIFIC", NULL } ; /* print a line about a single option */ static int xiohelp_option(FILE *of, const struct optname *on, const char *name) { int chars; int i, j; groups_t groups; bool occurred; chars = fprintf(of, " %s", name); i = (16 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } fputc('\t', of); fputs("groups=", of); groups = on->desc->group; occurred = false; chars = 7; for (j = 0; j < 8*sizeof(groups_t); ++j) { if (groups & 1) { if (occurred) { fputc(',', of); ++chars; } fputs(addressgroupnames[j], of); chars += strlen(addressgroupnames[j]); occurred = true; } groups >>= 1; } i = (24 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } chars = fprintf(of, "phase=%s", optionphasenames[on->desc->phase]); i = (24 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } fprintf(of, "type=%s", optiontypenames[on->desc->type]); fputc('\n', of); return 0; } const char *xiohelp_opttypename(enum e_types typnum) { if (typnum < 0 || typnum >= TYPE_OVERFLOW) { Warn2("%s(): invalid type number %d", __func__, typnum); return ""; } return optiontypenames[typnum]; } int xioopenhelp(FILE *of, int level /* 0..only addresses, 1..and options */ ) { const struct addrname *an; const struct optname *on; int i, j; groups_t groups; bool occurred; fputs(" bi-address: /* is an address that may act both as data sync and source */\n", of); fputs(" \n", of); fputs(" !!\n", of); fputs(" single-address:\n", of); fputs(" [,]\n", of); fputs(" address-head:\n", of); an = &addressnames[0]; i = 0; while (addressnames[i].name) { if (!strcmp(an->name, an->desc->defname)) { int chars, i; /* it is a canonical address name */ chars = fprintf(of, " %s", an->name); if (an->desc->syntax) { fputs(an->desc->syntax, of); chars += strlen(an->desc->syntax); } i = (40 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } fputs("\tgroups=", of); groups = an->desc->groups; occurred = false; for (j = 0; j < 32; ++j) { if (groups & 1) { if (occurred) { fputc(',', of); } fprintf(of, "%s", addressgroupnames[j]); occurred = true; } groups >>= 1; } fputc('\n', of); } else if (level == 2) { int chars, i; chars = fprintf(of, " %s", an->name); i = (40 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } fprintf(of, "\tis an alias name for %s\n", an->desc->defname); } ++an; ++i; } if (level == 2) { fputs(" is a short form for fd:\n", of); fputs(" is a short form for gopen:\n", of); } if (level <= 0) return 0; fputs(" opts:\n", of); fputs(" {,}:\n", of); fputs(" opt:\n", of); on = optionnames; while (on->name != NULL) { if (on->desc->nickname != NULL && !strcmp(on->name, on->desc->nickname)) { if (level == 2) { int chars, i; chars = fprintf(of, " %s", on->name); i = (16 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } fprintf(of, "\tis an alias for %s\n", on->desc->defname); } else { xiohelp_option(of, on, on->name); } } else if (on->desc->nickname == NULL && !strcmp(on->name, on->desc->defname)) { xiohelp_option(of, on, on->name); } else if (level == 2) { if (!strcmp(on->name, on->desc->defname)) { xiohelp_option(of, on, on->name); } else { int chars, i; chars = fprintf(of, " %s", on->name); i = (16 - chars + 7) / 8; for (; i > 0; --i) { fputc('\t', of); } fprintf(of, "\tis an alias for %s\n", on->desc->defname); } } ++on; } fflush(of); return 0; } /* This function may be used by address handling code to log syntax error */ int xiohelp_syntax( const char *addr, int expectnum, int isnum, const char *syntax) { Error5("%s: wrong number of parameters (%d instead of %d): usage: %s%s", addr, isnum, expectnum, addr, syntax); return -1; } #endif /* WITH_HELP */