#include "headers.h" Rune smbruneconvert(Rune r, ulong flags) { if (r >= 'a' && r <= 'z' && (flags & SMB_STRING_UPCASE)) r = toupper(r); else if (r == '/' && (flags & SMB_STRING_REVPATH)) r = '\\'; else if (r == '\\' && (flags & SMB_STRING_PATH)) r = '/'; else if (r == 0xa0 && (flags & SMB_STRING_REVPATH) && smbglobals.convertspace) r = ' '; else if (r == ' ' && (flags & SMB_STRING_PATH) && smbglobals.convertspace) r = 0xa0; return r; } int smbucs2len(char *string) { return (string ? utflen(string) : 0) * 2 + 2; } int smbstrlen(char *string) { return (string ? strlen(string) : 0) + 1; } int smbstringlen(SmbPeerInfo *i, char *string) { if (smbglobals.unicode && (i == nil || (i->capabilities & CAP_UNICODE) != 0)) return smbucs2len(string); return smbstrlen(string); } char * smbstrinline(uchar **bdatap, uchar *edata) { char *p; uchar *np; np = memchr(*bdatap, 0, edata - *bdatap); if (np == nil) return nil; p = (char *)*bdatap; *bdatap = np + 1; return p; } char * smbstrdup(uchar **bdatap, uchar *edata) { char *p; uchar *np; np = memchr(*bdatap, 0, edata - *bdatap); if (np == nil) return nil; p = smbestrdup((char *)(*bdatap)); *bdatap = np + 1; return p; } char * smbstringdup(SmbHeader *h, uchar *base, uchar **bdatap, uchar *edata) { char *p; if (h && h->flags2 & SMB_FLAGS2_UNICODE) { uchar *bdata = *bdatap; uchar *savebdata; Rune r; int l; char *q; l = 0; if ((bdata - base) & 1) bdata++; savebdata = bdata; do { if (bdata + 2 > edata) return nil; r = smbnhgets(bdata); bdata += 2; l += runelen(r); } while (r != 0); p = smbemalloc(l); bdata = savebdata; q = p; do { r = smbnhgets(bdata); bdata += 2; q += runetochar(q, &r); } while (r != 0); *bdatap = bdata; return p; } return smbstrdup(bdatap, edata); } int smbstrnput(uchar *buf, ushort n, ushort maxlen, char *string, ushort size, int upcase) { uchar *p = buf + n; int l; l = strlen(string); if (l + 1 > size) l = size - 1; if (n + l + 1 > maxlen) return 0; if (upcase) { int x; for (x = 0; x < l; x++) p[x] = toupper(string[x]); } else memcpy(p, string, l); p += l; while (l++ < size) *p++ = 0; return size; } int smbstrput(ulong flags, uchar *buf, ushort n, ushort maxlen, char *string) { uchar *p = buf + n; int l; l = string ? strlen(string) : 0; if (n + l + ((flags & SMB_STRING_UNTERMINATED) == 0 ? 1 : 0) > maxlen) return 0; memcpy(p, string, l); if (flags & (SMB_STRING_UPCASE | SMB_STRING_PATH | SMB_STRING_REVPATH)) { uchar *q; for (q = p; q < p + l; q++) if (*q >= 'a' && *q <= 'z' && (flags & SMB_STRING_UPCASE)) *q = toupper(*q); else if (*q == '/' && (flags & SMB_STRING_REVPATH)) *q = '\\'; else if (*q == '\\' && (flags & SMB_STRING_PATH)) *q = '/'; } p += l; if ((flags & SMB_STRING_UNTERMINATED) == 0) *p++ = 0; return p - (buf + n); } int smbucs2put(ulong flags, uchar *buf, ushort n, ushort maxlen, char *string) { uchar *p = buf + n; int l; int align; align = (flags & SMB_STRING_UNALIGNED) == 0 && (n & 1) != 0; l = string ? utflen(string) * 2 : 0; if (n + l + ((flags & SMB_STRING_UNTERMINATED) ? 0 : 2) + align > maxlen) return 0; if (align) *p++ = 0; while (string && *string) { Rune r; int i; i = chartorune(&r, string); if (flags & SMB_STRING_CONVERT_MASK) r = smbruneconvert(r, flags); smbhnputs(p, r); p += 2; string += i; } if ((flags & SMB_STRING_UNTERMINATED) == 0) { smbhnputs(p, 0); p += 2; } assert(p <= buf + maxlen); return p - (buf + n); } int smbstringput(SmbPeerInfo *p, ulong flags, uchar *buf, ushort n, ushort maxlen, char *string) { if (flags & SMB_STRING_UNICODE) return smbucs2put(flags, buf, n, maxlen, string); if (flags & SMB_STRING_ASCII) return smbstrput(flags, buf, n, maxlen, string); if (p && (p->capabilities & CAP_UNICODE) != 0) return smbucs2put(flags, buf, n, maxlen, string); return smbstrput(flags, buf, n, maxlen, string); } void smbstringprint(char **p, char *fmt, ...) { va_list arg; if (*p) { free(*p); *p = nil; } va_start(arg, fmt); *p = vsmprint(fmt, arg); va_end(arg); }