/* * Set up various conversions in the TTY parameter, including parity, tabs, * returns, echo, and case, according to the termcap entry. */ void set_conversions(TTY * tty_settings) { #ifdef ONLCR tty_settings->c_oflag |= ONLCR; #endif tty_settings->c_iflag |= ICRNL; tty_settings->c_lflag |= ECHO; #ifdef OXTABS tty_settings->c_oflag |= OXTABS; #endif /* OXTABS */ /* test used to be tgetflag("NL") */ if (VALID_STRING(newline) && newline[0] == '\n' && !newline[1]) { /* Newline, not linefeed. */ #ifdef ONLCR tty_settings->c_oflag &= ~((unsigned) ONLCR); #endif tty_settings->c_iflag &= ~((unsigned) ICRNL); } #ifdef OXTABS /* test used to be tgetflag("pt") */ if (VALID_STRING(set_tab) && VALID_STRING(clear_all_tabs)) tty_settings->c_oflag &= ~OXTABS; #endif /* OXTABS */ tty_settings->c_lflag |= (ECHOE | ECHOK); }
static int capcmp(const char *s, const char *t) /* capability comparison function */ { if (!VALID_STRING(s) && !VALID_STRING(t)) return(0); else if (!VALID_STRING(s) || !VALID_STRING(t)) return(1); if (ignorepads) return(_nc_capcmp(s, t)); else return(strcmp(s, t)); }
static int capcmp(PredIdx idx, const char *s, const char *t) /* capability comparison function */ { if (!VALID_STRING(s) && !VALID_STRING(t)) return (s != t); else if (!VALID_STRING(s) || !VALID_STRING(t)) return (1); if ((idx == acs_chars_index) || !ignorepads) return (strcmp(s, t)); else return (_nc_capcmp(s, t)); }
static void init_xterm_mouse(SCREEN *sp) { sp->_mouse_type = M_XTERM; sp->_mouse_xtermcap = tigetstr("XM"); if (!VALID_STRING(sp->_mouse_xtermcap)) sp->_mouse_xtermcap = "\033[?1000%?%p1%{1}%=%th%el%;"; }
static bool to_left_margin(void) { if (VALID_STRING(carriage_return)) { sent_string(carriage_return); } else { out_char('\r'); } return TRUE; }
static bool sent_string(const char *s) { bool sent = FALSE; if (VALID_STRING(s)) { tputs(s, 0, out_char); sent = TRUE; } return sent; }
static void write_it(ENTRY * ep) { unsigned n; int ch; char *s, *d, *t; char result[MAX_ENTRY_SIZE]; /* * Look for strings that contain %{number}, convert them to %'char', * which is shorter and runs a little faster. */ for (n = 0; n < STRCOUNT; n++) { s = ep->tterm.Strings[n]; if (VALID_STRING(s) && strchr(s, L_BRACE) != 0) { d = result; t = s; while ((ch = *t++) != 0) { *d++ = ch; if (ch == '\\') { *d++ = *t++; } else if ((ch == '%') && (*t == L_BRACE)) { char *v = 0; long value = strtol(t + 1, &v, 0); if (v != 0 && *v == R_BRACE && value > 0 && value != '\\' /* FIXME */ && value < 127 && isprint((int) value)) { *d++ = S_QUOTE; *d++ = (int) value; *d++ = S_QUOTE; t = (v + 1); } } } *d = 0; if (strlen(result) < strlen(s)) strcpy(s, result); } } _nc_set_type(_nc_first_name(ep->tterm.term_names)); _nc_curr_line = ep->startline; _nc_write_entry(&ep->tterm); }
/* * Set the hardware tabs on the terminal, using the 'ct' (clear all tabs), * 'st' (set one tab) and 'ch' (horizontal cursor addressing) capabilities. * This is done before 'if' and 'is', so they can recover in case of error. * * Return TRUE if we set any tab stops, FALSE if not. */ static bool reset_tabstops(int wide) { if ((init_tabs != 8) && VALID_NUMERIC(init_tabs) && VALID_STRING(set_tab) && VALID_STRING(clear_all_tabs)) { int c; to_left_margin(); tputs(clear_all_tabs, 0, out_char); if (init_tabs > 1) { if (init_tabs > wide) init_tabs = (short) wide; for (c = init_tabs; c < wide; c += init_tabs) { fprintf(my_file, "%*s", init_tabs, " "); tputs(set_tab, 0, out_char); } to_left_margin(); } return (TRUE); } return (FALSE); }
/* * Returns a "good" value for the erase character. This is loosely based on * the BSD4.4 logic. */ static int default_erase(void) { int result; if (over_strike && VALID_STRING(key_backspace) && strlen(key_backspace) == 1) { result = key_backspace[0]; } else { result = CERASE; } return result; }
NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx NCURSES_CONST char *id, char **area) { char *result = NULL; int i, j; T((T_CALLED("tgetstr(%s,%p)"), id, (void *) area)); if (HasTInfoTerminal(SP_PARM)) { TERMTYPE *tp = &(TerminalOf(SP_PARM)->type); struct name_table_entry const *entry_ptr; entry_ptr = _nc_find_type_entry(id, STRING, TRUE); if (entry_ptr != 0) { j = entry_ptr->nte_index; } #if NCURSES_XNAMES else { j = -1; for_each_ext_string(i, tp) { const char *capname = ExtStrname(tp, i, strcodes); if (same_tcname(id, capname)) { j = i; break; } } } #endif if (j >= 0) { result = tp->Strings[j]; TR(TRACE_DATABASE, ("found match : %s", _nc_visbuf(result))); /* setupterm forces canceled strings to null */ if (VALID_STRING(result)) { if (result == exit_attribute_mode && FIX_SGR0 != 0) { result = FIX_SGR0; TR(TRACE_DATABASE, ("altered to : %s", _nc_visbuf(result))); } if (area != 0 && *area != 0) { (void) strcpy(*area, result); result = *area; *area += strlen(*area) + 1; } } } } returnPtr(result); }
_nc_free_termtype(TERMTYPE *ptr) { T(("_nc_free_termtype(%s)", ptr->term_names)); if (ptr->str_table == 0 || (ptr->term_names < ptr->str_table || ptr->term_names >= ptr->str_table + MAX_ENTRY_SIZE)) { FreeIfNeeded(ptr->term_names); } #if NO_LEAKS else { if (ptr->str_table != 0 && (ptr->term_names < ptr->str_table + MAX_ENTRY_SIZE)) { int j; char *last = ptr->str_table; /* * We should have saved the entry-size someplace. Too late, * but this is useful for the memory-leak checking, though more * work/time than should be in the normal library. */ for (j = 0; j < NUM_STRINGS(ptr); j++) { char *s = ptr->Strings[j]; if (VALID_STRING(s)) { char *t = s + strlen(s) + 1; if (t > last) last = t; } } if (last < ptr->term_names) { FreeIfNeeded(ptr->term_names); } } } #endif FreeIfNeeded(ptr->str_table); FreeIfNeeded(ptr->Booleans); FreeIfNeeded(ptr->Numbers); FreeIfNeeded(ptr->Strings); #if NCURSES_XNAMES FreeIfNeeded(ptr->ext_str_table); FreeIfNeeded(ptr->ext_Names); #endif memset(ptr, 0, sizeof(TERMTYPE)); _nc_free_entry(_nc_head, ptr); }
NET_API_STATUS RxNetShareCheck( IN LPTSTR ServerName, IN LPTSTR DeviceName, OUT LPDWORD Type ) /*++ Routine Description: Attempts to perform the NetShareCheck API on a remote down-level server Arguments: ServerName - where this call will happen DeviceName - the thing we are querying Type - where we store share type in the (unlikely) event of success Return Value: NET_API_STATUS Success = NERR_Success Failure = --*/ { #if DBG // // The ServerName parameter must be a non-NUL(L) string. We know this must // be so since (presumably) the server name was used as the criteria to get // here. Ensure that this is so (in the non-release version) so we trap // stupid mistakes early // NetpAssert(ServerName != NULL); NetpAssert(*ServerName); #endif // // We have to have something in the device name // Ensure that the caller provided us with the address of the place he/she // wants the type info to be left // if (!VALID_STRING(DeviceName) || Type == NULL) { return ERROR_INVALID_PARAMETER; } return RxRemoteApi(API_NetShareCheck, ServerName, // where it will run REMSmb_NetShareCheck_P, // parameter descriptor NULL, // Data descriptor/16-bit NULL, // Data descriptor/32-bit NULL, // Data descriptor/SMB NULL, // Aux descriptor/16-bit NULL, // Aux descriptor/32-bit NULL, // Aux descriptor/SMB FALSE, // this call needs user to be logged on DeviceName, // parm 1 Type // parm 2 ); }
TIC * _ti_compile(char *cap, int flags) { char *token, *p, *e, *name, *desc, *alias; signed char flag; long cnum; short num; ssize_t ind; size_t len; TBUF buf; TIC *tic; _DIAGASSERT(cap != NULL); name = _ti_get_token(&cap, ','); if (name == NULL) { dowarn(flags, "no seperator found: %s", cap); return NULL; } desc = strrchr(name, '|'); if (desc != NULL) *desc++ = '\0'; alias = strchr(name, '|'); if (alias != NULL) *alias++ = '\0'; tic = calloc(sizeof(*tic), 1); if (tic == NULL) return NULL; buf.buf = NULL; buf.buflen = 0; tic->name = strdup(name); if (tic->name == NULL) goto error; if (alias != NULL && flags & TIC_ALIAS) { tic->alias = strdup(alias); if (tic->alias == NULL) goto error; } if (desc != NULL && flags & TIC_DESCRIPTION) { tic->desc = strdup(desc); if (tic->desc == NULL) goto error; } for (token = _ti_get_token(&cap, ','); token != NULL && *token != '\0'; token = _ti_get_token(&cap, ',')) { /* Skip commented caps */ if (!(flags & TIC_COMMENT) && token[0] == '.') continue; /* Obsolete entries */ if (token[0] == 'O' && token[1] == 'T') { if (!(flags & TIC_EXTRA)) continue; token += 2; } /* str cap */ p = strchr(token, '='); if (p != NULL) { *p++ = '\0'; /* Don't use the string if we already have it */ ind = _ti_strindex(token); if (ind != -1 && _ti_find_cap(&tic->strs, 's', ind) != NULL) continue; /* Encode the string to our scratch buffer */ buf.bufpos = 0; if (encode_string(tic->name, token, &buf, p, flags) == -1) goto error; if (buf.bufpos > UINT16_T_MAX) { dowarn(flags, "%s: %s: string is too long", tic->name, token); continue; } if (!VALID_STRING(buf.buf)) { dowarn(flags, "%s: %s: invalid string", tic->name, token); continue; } if (ind == -1) _ti_store_extra(tic, 1, token, 's', -1, -2, buf.buf, buf.bufpos, flags); else { if (!_ti_grow_tbuf(&tic->strs, (sizeof(uint16_t) * 2) + buf.bufpos)) goto error; le16enc(tic->strs.buf + tic->strs.bufpos, ind); tic->strs.bufpos += sizeof(uint16_t); le16enc(tic->strs.buf + tic->strs.bufpos, buf.bufpos); tic->strs.bufpos += sizeof(uint16_t); memcpy(tic->strs.buf + tic->strs.bufpos, buf.buf, buf.bufpos); tic->strs.bufpos += buf.bufpos; tic->strs.entries++; } continue; } /* num cap */ p = strchr(token, '#'); if (p != NULL) { *p++ = '\0'; /* Don't use the number if we already have it */ ind = _ti_numindex(token); if (ind != -1 && _ti_find_cap(&tic->nums, 'n', ind) != NULL) continue; cnum = strtol(p, &e, 0); if (*e != '\0') { dowarn(flags, "%s: %s: not a number", tic->name, token); continue; } if (!VALID_NUMERIC(cnum)) { dowarn(flags, "%s: %s: number out of range", tic->name, token); continue; } num = (short)cnum; if (ind == -1) _ti_store_extra(tic, 1, token, 'n', -1, num, NULL, 0, flags); else { if (_ti_grow_tbuf(&tic->nums, sizeof(uint16_t) * 2) == NULL) goto error; le16enc(tic->nums.buf + tic->nums.bufpos, ind); tic->nums.bufpos += sizeof(uint16_t); le16enc(tic->nums.buf + tic->nums.bufpos, num); tic->nums.bufpos += sizeof(uint16_t); tic->nums.entries++; } continue; } flag = 1; len = strlen(token) - 1; if (token[len] == '@') { flag = CANCELLED_BOOLEAN; token[len] = '\0'; } ind = _ti_flagindex(token); if (ind == -1 && flag == CANCELLED_BOOLEAN) { if ((ind = _ti_numindex(token)) != -1) { if (_ti_find_cap(&tic->nums, 'n', ind) != NULL) continue; if (_ti_grow_tbuf(&tic->nums, sizeof(uint16_t) * 2) == NULL) goto error; le16enc(tic->nums.buf + tic->nums.bufpos, ind); tic->nums.bufpos += sizeof(uint16_t); le16enc(tic->nums.buf + tic->nums.bufpos, (uint16_t)CANCELLED_NUMERIC); tic->nums.bufpos += sizeof(uint16_t); tic->nums.entries++; continue; } else if ((ind = _ti_strindex(token)) != -1) { if (_ti_find_cap(&tic->strs, 's', ind) != NULL) continue; if (_ti_grow_tbuf(&tic->strs, (sizeof(uint16_t) * 2) + 1) == NULL) goto error; le16enc(tic->strs.buf + tic->strs.bufpos, ind); tic->strs.bufpos += sizeof(uint16_t); le16enc(tic->strs.buf + tic->strs.bufpos, 0); tic->strs.bufpos += sizeof(uint16_t); tic->strs.entries++; continue; } } if (ind == -1) _ti_store_extra(tic, 1, token, 'f', flag, 0, NULL, 0, flags); else if (_ti_find_cap(&tic->flags, 'f', ind) == NULL) { if (_ti_grow_tbuf(&tic->flags, sizeof(uint16_t) + 1) == NULL) goto error; le16enc(tic->flags.buf + tic->flags.bufpos, ind); tic->flags.bufpos += sizeof(uint16_t); tic->flags.buf[tic->flags.bufpos++] = flag; tic->flags.entries++; } } free(buf.buf); return tic; error: free(buf.buf); _ti_freetic(tic); return NULL; }
static int write_object(TERMTYPE *tp, char *buffer, unsigned *offset, unsigned limit) { char *namelist; size_t namelen, boolmax, nummax, strmax; char zero = '\0'; size_t i; short nextfree; short offsets[MAX_ENTRY_SIZE / 2]; unsigned char buf[MAX_ENTRY_SIZE]; unsigned last_bool = BOOLWRITE; unsigned last_num = NUMWRITE; unsigned last_str = STRWRITE; #if NCURSES_XNAMES /* * Normally we limit the list of values to exclude the "obsolete" * capabilities. However, if we are accepting extended names, add * these as well, since they are used for supporting translation * to/from termcap. */ if (_nc_user_definable) { last_bool = BOOLCOUNT; last_num = NUMCOUNT; last_str = STRCOUNT; } #endif namelist = tp->term_names; namelen = strlen(namelist) + 1; boolmax = 0; for (i = 0; i < last_bool; i++) { if (tp->Booleans[i] == TRUE) boolmax = i + 1; } nummax = 0; for (i = 0; i < last_num; i++) { if (tp->Numbers[i] != ABSENT_NUMERIC) nummax = i + 1; } strmax = 0; for (i = 0; i < last_str; i++) { if (tp->Strings[i] != ABSENT_STRING) strmax = i + 1; } nextfree = compute_offsets(tp->Strings, strmax, offsets); /* fill in the header */ LITTLE_ENDIAN(buf, MAGIC); LITTLE_ENDIAN(buf + 2, min(namelen, MAX_NAME_SIZE + 1)); LITTLE_ENDIAN(buf + 4, boolmax); LITTLE_ENDIAN(buf + 6, nummax); LITTLE_ENDIAN(buf + 8, strmax); LITTLE_ENDIAN(buf + 10, nextfree); /* write out the header */ TRACE_OUT(("Header of %s @%d", namelist, *offset)); if (Write(buf, 12, 1) != 1 || Write(namelist, sizeof(char), namelen) != namelen) return (ERR); for (i = 0; i < boolmax; i++) if (tp->Booleans[i] == TRUE) buf[i] = TRUE; else buf[i] = FALSE; if (Write(buf, sizeof(char), boolmax) != boolmax) return (ERR); if (even_boundary(namelen + boolmax)) return (ERR); TRACE_OUT(("Numerics begin at %04x", *offset)); /* the numerics */ convert_shorts(buf, tp->Numbers, nummax); if (Write(buf, 2, nummax) != nummax) return (ERR); TRACE_OUT(("String offsets begin at %04x", *offset)); /* the string offsets */ convert_shorts(buf, offsets, strmax); if (Write(buf, 2, strmax) != strmax) return (ERR); TRACE_OUT(("String table begins at %04x", *offset)); /* the strings */ for (i = 0; i < strmax; i++) if (VALID_STRING(tp->Strings[i])) if (!WRITE_STRING(tp->Strings[i])) return (ERR); #if NCURSES_XNAMES if (extended_object(tp)) { unsigned extcnt = NUM_EXT_NAMES(tp); if (even_boundary(nextfree)) return (ERR); nextfree = compute_offsets(tp->Strings + STRCOUNT, tp->ext_Strings, offsets); TRACE_OUT(("after extended string capabilities, nextfree=%d", nextfree)); if (tp->ext_Strings >= SIZEOF(offsets)) return (ERR); nextfree += compute_offsets(tp->ext_Names, extcnt, offsets + tp->ext_Strings); TRACE_OUT(("after extended capnames, nextfree=%d", nextfree)); strmax = tp->ext_Strings + extcnt; /* * Write the extended header */ LITTLE_ENDIAN(buf + 0, tp->ext_Booleans); LITTLE_ENDIAN(buf + 2, tp->ext_Numbers); LITTLE_ENDIAN(buf + 4, tp->ext_Strings); LITTLE_ENDIAN(buf + 6, strmax); LITTLE_ENDIAN(buf + 8, nextfree); TRACE_OUT(("WRITE extended-header @%d", *offset)); if (Write(buf, 10, 1) != 1) return (ERR); TRACE_OUT(("WRITE %d booleans @%d", tp->ext_Booleans, *offset)); if (tp->ext_Booleans && Write(tp->Booleans + BOOLCOUNT, sizeof(char), tp->ext_Booleans) != tp->ext_Booleans) return (ERR); if (even_boundary(tp->ext_Booleans)) return (ERR); TRACE_OUT(("WRITE %d numbers @%d", tp->ext_Numbers, *offset)); if (tp->ext_Numbers) { convert_shorts(buf, tp->Numbers + NUMCOUNT, tp->ext_Numbers); if (Write(buf, 2, tp->ext_Numbers) != tp->ext_Numbers) return (ERR); } /* * Convert the offsets for the ext_Strings and ext_Names tables, * in that order. */ convert_shorts(buf, offsets, strmax); TRACE_OUT(("WRITE offsets @%d", *offset)); if (Write(buf, 2, strmax) != strmax) return (ERR); /* * Write the string table after the offset tables so we do not * have to do anything about alignment. */ for (i = 0; i < tp->ext_Strings; i++) { if (VALID_STRING(tp->Strings[i + STRCOUNT])) { TRACE_OUT(("WRITE ext_Strings[%d]=%s", (int) i, _nc_visbuf(tp->Strings[i + STRCOUNT]))); if (!WRITE_STRING(tp->Strings[i + STRCOUNT])) return (ERR); } } /* * Write the extended names */ for (i = 0; i < extcnt; i++) { TRACE_OUT(("WRITE ext_Names[%d]=%s", (int) i, tp->ext_Names[i])); if (!WRITE_STRING(tp->ext_Names[i])) return (ERR); } } #endif /* NCURSES_XNAMES */ total_written++; return (OK); }
/* Output startup string. */ bool send_init_strings(int fd GCC_UNUSED, TTY * old_settings) { int i; bool need_flush = FALSE; (void) old_settings; #ifdef TAB3 if (old_settings != 0 && old_settings->c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) { old_settings->c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET); SET_TTY(fd, old_settings); } #endif if (use_reset || use_init) { if (VALID_STRING(init_prog)) { IGNORE_RC(system(init_prog)); } need_flush |= sent_string((use_reset && (reset_1string != 0)) ? reset_1string : init_1string); need_flush |= sent_string((use_reset && (reset_2string != 0)) ? reset_2string : init_2string); #if defined(set_lr_margin) if (VALID_STRING(set_lr_margin)) { need_flush |= sent_string(TPARM_2(set_lr_margin, 0, columns - 1)); } else #endif #if defined(set_left_margin_parm) && defined(set_right_margin_parm) if (VALID_STRING(set_left_margin_parm) && VALID_STRING(set_right_margin_parm)) { need_flush |= sent_string(TPARM_1(set_left_margin_parm, 0)); need_flush |= sent_string(TPARM_1(set_right_margin_parm, columns - 1)); } else #endif if (VALID_STRING(clear_margins) && VALID_STRING(set_left_margin) && VALID_STRING(set_right_margin)) { need_flush |= sent_string(clear_margins); need_flush |= to_left_margin(); need_flush |= sent_string(set_left_margin); if (VALID_STRING(parm_right_cursor)) { need_flush |= sent_string(TPARM_1(parm_right_cursor, columns - 1)); } else { for (i = 0; i < columns - 1; i++) { out_char(' '); need_flush = TRUE; } } need_flush |= sent_string(set_right_margin); need_flush |= to_left_margin(); } need_flush |= reset_tabstops(columns); need_flush |= cat_file((use_reset && reset_file) ? reset_file : init_file); need_flush |= sent_string((use_reset && (reset_3string != 0)) ? reset_3string : init_3string); } return need_flush; }
tputs(const char *string, int affcnt, int (*outc) (int)) { bool always_delay; bool normal_delay; int number; #if BSD_TPUTS int trailpad; #endif /* BSD_TPUTS */ #ifdef TRACE char addrbuf[32]; if (_nc_tracing & TRACE_TPUTS) { if (outc == _nc_outch) (void) strcpy(addrbuf, "_nc_outch"); else (void) sprintf(addrbuf, "%p", outc); if (_nc_tputs_trace) { _tracef("tputs(%s = %s, %d, %s) called", _nc_tputs_trace, _nc_visbuf(string), affcnt, addrbuf); } else { _tracef("tputs(%s, %d, %s) called", _nc_visbuf(string), affcnt, addrbuf); } _nc_tputs_trace = (char *) NULL; } #endif /* TRACE */ if (!VALID_STRING(string)) return ERR; if (cur_term == 0) { always_delay = FALSE; normal_delay = TRUE; } else { always_delay = (string == bell) || (string == flash_screen); normal_delay = !xon_xoff && padding_baud_rate #if NCURSES_NO_PADDING && (SP == 0 || !(SP->_no_padding)) #endif && (_nc_baudrate(ospeed) >= padding_baud_rate); } #if BSD_TPUTS /* * This ugly kluge deals with the fact that some ancient BSD programs * (like nethack) actually do the likes of tputs("50") to get delays. */ trailpad = 0; if (isdigit(UChar(*string))) { while (isdigit(UChar(*string))) { trailpad = trailpad * 10 + (*string - '0'); string++; } trailpad *= 10; if (*string == '.') { string++; if (isdigit(UChar(*string))) { trailpad += (*string - '0'); string++; } while (isdigit(UChar(*string))) string++; } if (*string == '*') { trailpad *= affcnt; string++; } } #endif /* BSD_TPUTS */ my_outch = outc; /* redirect delay_output() */ while (*string) { if (*string != '$') (*outc) (*string); else { string++; if (*string != '<') { (*outc) ('$'); if (*string) (*outc) (*string); } else { bool mandatory; string++; if ((!isdigit(UChar(*string)) && *string != '.') || !strchr(string, '>')) { (*outc) ('$'); (*outc) ('<'); continue; } number = 0; while (isdigit(UChar(*string))) { number = number * 10 + (*string - '0'); string++; } number *= 10; if (*string == '.') { string++; if (isdigit(UChar(*string))) { number += (*string - '0'); string++; } while (isdigit(UChar(*string))) string++; } mandatory = FALSE; while (*string == '*' || *string == '/') { if (*string == '*') { number *= affcnt; string++; } else { /* if (*string == '/') */ mandatory = TRUE; string++; } } if (number > 0 && (always_delay || normal_delay || mandatory)) delay_output(number / 10); } /* endelse (*string == '<') */ } /* endelse (*string == '$') */ if (*string == '\0') break; string++; } #if BSD_TPUTS /* * Emit any BSD-style prefix padding that we've accumulated now. */ if (trailpad > 0 && (always_delay || normal_delay)) delay_output(trailpad / 10); #endif /* BSD_TPUTS */ my_outch = _nc_outch; return OK; }
NET_API_STATUS RxNetShareSetInfo( IN LPTSTR ServerName, IN LPTSTR NetName, IN DWORD Level, IN LPBYTE Buffer, OUT LPDWORD ParmError OPTIONAL ) /*++ Routine Description: Performs the NetShareSetInfo API at a remote down-level server Arguments: ServerName - where to perform the request NetName - name of thing for which to set info Level - level of information - 0, 1, 2, 1004, 1005, 1006, 1009 Buffer - buffer containing info at defined level ParmError - pointer to invalid parameter ordinal Return Value: NET_API_STATUS Success = NERR_Success Failure = ERROR_INVALID_LEVEL ERROR_INVALID_PARAMETER (return code from RxRemoteApi) --*/ { DWORD infolen; // size of structure DWORD parmnum; // we have to cobble down-level parmnum from Level LPDESC pDesc16; // used in call to GetShareInfoDescriptors LPDESC pDesc32; // ditto. Only interested in length of info structure LPDESC pDescSmb; // ditto. Only interested in length of info structure UNREFERENCED_PARAMETER(ParmError); #if DBG // // The ServerName parameter must be a non-NUL(L) string. We know this must // be so since (presumably) the server name was used as the criteria to get // here. Ensure that this is so (in the non-release version) so we trap // stupid mistakes early // NetpAssert(ServerName != NULL); NetpAssert(*ServerName); #endif // // Perform parameter validity checks: // NetName must be non-NULL pointer to non-NULL string // Buffer must be non-NULL pointer to non-NULL pointer // Level must be in range // NB. Assumes that DWORD is unsigned! // if (!VALID_STRING(NetName) || !Buffer) { return ERROR_INVALID_PARAMETER; } // BUGBUG - are there any manifests for these numbers? if (Level < 1 || (Level > 2 && (Level < 1004 || (Level > 1006 && Level != 1009)))) { return ERROR_INVALID_LEVEL; } // // We can set individual info fields using the levels > 1000. We have to // create level and parmnum info for down-level // if (Level > 2) { // // Individual fields are indicated by the old (down-level) parmnum, // augmented by 1000. Split level and parmnum parameters // parmnum = Level - PARMNUM_BASE_INFOLEVEL; Level = 2; pDesc16 = REM16_share_info_2_setinfo; pDesc32 = REM32_share_info_2_setinfo; pDescSmb = REMSmb_share_info_2_setinfo; switch (parmnum) { case 4: // remark case 9: // password infolen = STRSIZE( (LPTSTR)Buffer ); break; case 5: // permissions case 6: // max uses infolen = sizeof(WORD); break; } } else { // // let GetShareInfoDescriptors give us the size of the buffer // that NetShareSetInfo thinks its getting. We have no other way of // determining this (have we?). Levels 0 - 2 set the entire structure // GetShareInfoDescriptors(Level, &pDesc16, &pDesc32, &pDescSmb, &infolen); parmnum = PARMNUM_ALL; } return RxRemoteApi(API_WShareSetInfo, ServerName, // where it will run REMSmb_NetShareSetInfo_P, // parameter descriptor pDesc16, // Data descriptor/16-bit pDesc32, // Data descriptor/32-bit pDescSmb, // Data descriptor/SMB NULL, // Aux descriptor/16-bit NULL, // Aux descriptor/32-bit NULL, // Aux descriptor/SMB FALSE, // this call needs user to be logged on NetName, // pointer to thing to set info on Level, // level of info Buffer, // pointer to buffer sourced by caller infolen, // size of our buffer // // in this case, the field index and parm num are the // same value // MAKE_PARMNUM_PAIR(parmnum, parmnum) // what we're setting ); }
NET_API_STATUS RxNetShareGetInfo( IN LPTSTR ServerName, IN LPTSTR NetName, IN DWORD Level, OUT LPBYTE* Buffer ) /*++ Routine Description: Performs the NetShareGetInfo API at a remote down-level server. The returned information will be in 32-bit LanMan format. Returns single information structure in a buffer sourced in this routine. Caller must use NetApiBufferFree when finished with buffer Arguments: ServerName - where to perform the request NetName - name of thing to get information about Level - level of information requested - 0, 1, 2 are valid Buffer - pointer to pointer to returned buffer Return Value: NET_API_STATUS Success = NERR_Success Failure = ERROR_INVALID_LEVEL ERROR_INVALID_PARAMETER (return code from NetApiBufferAllocate) (return code from RxRemoteApi) --*/ { NET_API_STATUS rc; LPDESC pDesc16; // pointer to 16-bit info descriptor for RxRemoteApi LPDESC pDesc32; // pointer to 32-bit info descriptor for RxRemoteApi LPDESC pDescSmb; // pointer to SMB info descriptor for RxRemoteApi LPBYTE ourbuf; // buffer we allocate, fill, and give to the caller DWORD total_avail; // 32-bit total available if supplied buffer too small DWORD infolen; // 32-bit place to store size of required buffer #if DBG // // The ServerName parameter must be a non-NUL(L) string. We know this must // be so since (presumably) the server name was used as the criteria to get // here. Ensure that this is so (in the non-release version) so we trap // stupid mistakes early // NetpAssert(ServerName != NULL); NetpAssert(*ServerName); #endif // // Preset Buffer and check it is valid pointer // *Buffer = NULL; // // Perform parameter validity checks: // Level must be in range 0 <= Level <= 2 // NetName must be non-NULL pointer to non-NULL string // Buffer must be non-NULL pointer // NB. Assumes DWORD is unsigned quantity // if (Level > 2) { return ERROR_INVALID_LEVEL; } if (!VALID_STRING(NetName) || !Buffer) { return ERROR_INVALID_PARAMETER; } // // Work out the descriptor and buffer size requirements based on the // requested level // GetShareInfoDescriptors(Level, &pDesc16, &pDesc32, &pDescSmb, &infolen); // // allocate a buffer size required to fit in 1 structure at info level // requested. If the allocation fails then return the error // We have to allocate space for the strings too, don't forget // ourbuf = NULL; rc = RxRemoteApi(API_WShareGetInfo, ServerName, // where it will happen REMSmb_NetShareGetInfo_P, // parameter descriptor pDesc16, // Data descriptor/16-bit pDesc32, // Data descriptor/32-bit pDescSmb, // Data descriptor/SMB NULL, // Aux descriptor/16-bit NULL, // Aux descriptor/32-bit NULL, // Aux descriptor/SMB ALLOCATE_RESPONSE, // allocate a buffer for us NetName, // pointer to thing to get info on Level, // level of info &ourbuf, // pointer to buffer sourced by us infolen, // size of our sourced buffer &total_avail // pointer to total available ); // // If the remote NetShareGetInfo call succeeded then give the returned // buffer to the caller // if (rc == NERR_Success) { if (Level == 2) { ConvertMaxUsesField((LPSHARE_INFO_2)ourbuf, 1); } *Buffer = ourbuf; } else if (ourbuf) { // // if we didn't record a success then free the buffer we previously allocated // (void) NetApiBufferFree(ourbuf); } return rc; }
NET_API_STATUS RxNetShareDel( IN LPTSTR ServerName, IN LPTSTR NetName, IN DWORD Reserved ) /*++ Routine Description: Performs the NetShareDel API at a remote down-level server Arguments: ServerName - where to perform the request NetName - to remove Reserved - MBZ Return Value: NET_API_STATUS Success = NERR_Success Failure = ERROR_INVALID_PARAMETER --*/ { #if DBG // // The ServerName parameter must be a non-NUL(L) string. We know this must // be so since (presumably) the server name was used as the criteria to get // here. Ensure that this is so (in the non-release version) so we trap // stupid mistakes early // NetpAssert(ServerName != NULL); NetpAssert(*ServerName); #endif // // if the NetName parameter is a NULL pointer or string OR the Reserved // parameter is NOT 0 then return an error // if (!VALID_STRING(NetName) || Reserved) { return ERROR_INVALID_PARAMETER; } // // Just call the RpcXlate routine to perform it and return the result // return RxRemoteApi(API_WShareDel, ServerName, // where it will run REMSmb_NetShareDel_P, // parameter descriptor NULL, // Data descriptor/16-bit NULL, // Data descriptor/32-bit NULL, // Data descriptor/SMB NULL, // Aux descriptor/16-bit NULL, // Aux descriptor/32-bit NULL, // Aux descriptor/SMB FALSE, // this call needs user to be logged on NetName, // parm 1 0 // parm 2 (RESERVED - MBZ) ); }