#include #include #include "ncp.h" Session * Attach(int fd) { Session *s; int err, len; ushort msg; if ((s = malloc(sizeof(Session))) == nil) sysfatal("No memory for another Session connection"); memset(s, 0, sizeof(Session)); s->txsig = 0x446d6454; // not using signatures, signature s->task = 1; s->mtu = BASEMTU; if ((s->buf = malloc(s->mtu)) == nil) sysfatal("No memory for another Session connection"); s->p = s->buf; memset(s->buf, 0, s->mtu); pb32(s, s->txsig); pb32(s, 23); // fixed packet len pb32(s, NCPVER); pb32(s, 0); // reply length pb16(s, Mattach); p8(s, s->seq); p8(s, 0xff); // connection number (MSBs) p8(s, 0); // task number (ignored) p8(s, 0); // reserved (ignored) p8(s, 0); // request code (ignored) if (Debug) fprint(2, "\n%N", s->buf); len = s->p - s->buf; if (write(fd, s->buf, len) != len){ werrstr("write to media failed"); free(s->buf); free(s); return nil; } s->p = s->buf; memset(s->buf, 0, s->mtu); if (read(fd, s->buf, s->mtu) == -1){ werrstr("read of media failed"); free(s->buf); free(s); return nil; } if (Debug) fprint(2, "%N", s->buf); s->rxsig = gb32(s); gb32(s); // length if ((msg = gb16(s)) != Mreply){ werrstr("read of media failed, 0x%4x", msg); free(s->buf); free(s); return nil; } s->seq = g8(s); s->conn = g8(s); g8(s); // task number s->conn |= (g8(s) << 8); if ((err = g8(s)) != 0){ werrstr("%s", nwerrstr(err)); free(s->buf); free(s); return nil; } if ((err = g8(s)) != 0){ if (err & (1 << 6)) fprint(2, "broadcast message waiting"); else{ if (err & (1 << 0)) werrstr("bad service connection"); if (err & (1 << 2)) werrstr("no connections avaliable"); if (err & (1 << 4)) werrstr("server is down"); free(s->buf); free(s); return nil; } } s->seq = (s->seq +1) % 256; s->fd = fd; return s; } int Detach(Session *s) { int len; s->p = s->buf; memset(s->buf, 0, s->mtu); pb32(s, s->txsig); // signature pb32(s, 0x49); // fixed packet len pb32(s, NCPVER); // packet version pb32(s, 0); // max reply length pb16(s, Mdetach); // packet type p8(s, s->seq); // sequence number p8(s, s->conn & 0xff); // server's connection # MSB p8(s, s->task); // client's transaction nesting p8(s, (s->conn >> 8) & 0xff); // server's connection # LSB if (Debug) fprint(2, "%N", s->buf); len = s->p - s->buf; if (write(s->fd, s->buf, len) != len){ werrstr("write to media failed"); free(s); return -1; } /* * ignore reply */ free(s->buf); free(s); return 0; } /******************* * Login/logout */ int Logout(Session *s) { ncphdr(s, 0x1900, Tsimple); return ncpcall(s); } int LoginObject(Session *s, char *name, int type, char *pass) { ncphdr(s, 0x1714, Tvarlen); pb16(s, type); pstr(s, name); pstr(s, pass); return ncpcall(s); } int KeyedObjectLogin(Session *s, int type, char *name, uchar *key) { ncphdr(s, 0x1718, Tvarlen); pmem(s, key, NWKEYLEN); pb16(s, type); pstr(s, name); return ncpcall(s); } int GetLoginKey(Session *s, int target, uchar *key) { ncphdr(s, 0x1717, Tvarlen); p8(s, target); if (ncpcall(s) == -1) return -1; gmem(s, key, NWKEYLEN); return 0; } int NegotiateBufferSize(Session *s, int *sz) { assert((*sz & ~0xffff) == 0); ncphdr(s, 0x2100, Tsimple); pb16(s, *sz); if (ncpcall(s) == -1) return -1; *sz = gb16(s); return 0; } /******************* * File server config */ int GetFileServerInfo(Session *s, FSInfo *fsi) { ncphdr(s, 0x1711, Tvarlen); if (ncpcall(s) == -1) return -1; gmem(s, fsi->name, OBJNAMLEN); fsi->fsvermaj = g8(s); fsi->fsvermin = g8(s); fsi->maxconn = gb16(s); fsi->numconn = gb16(s); fsi->numvol = gb16(s); fsi->rev = g8(s); fsi->sftlev = g8(s); fsi->ttslev = g8(s); fsi->mostconn = gb16(s); fsi->acctver = g8(s); fsi->vapver = g8(s); fsi->quever = g8(s); fsi->lprver = g8(s); fsi->consver = g8(s); fsi->restrct = g8(s); fsi->bridgeflag = g8(s); fsi->mixedpaths = g8(s); fsi->locallogin = g8(s); fsi->prodmaj = gb16(s); fsi->prodmin = gb16(s); fsi->prodver = gb16(s); fsi->lang = g8(s); fsi->bigfiles = g8(s); return 0; } int GetStationsLoggedInfo(Session *s, long conn, int *id, int *type, char *name, long *logtime) { ncphdr(s, 0x171c, Tvarlen); pl32(s, conn); if (ncpcall(s) == -1) return -1; *id = gb32(s); *type = gb16(s); gmem(s, name, OBJNAMLEN); *logtime = gtbuf(s); return 0; } int GetInternetAddress(Session *s, long conn, uchar *addr, int *type) { ncphdr(s, 0x171a, Tvarlen); pl32(s, conn); if (ncpcall(s) == -1) return -1; gmem(s, addr, IPXADDRLEN); *type = g8(s); return 0; } int GetFileServerDateAndTime(Session *s, long *now) { ncphdr(s, 0x1400, Tsimple); if (ncpcall(s) == -1) return -1; *now = gtbuf(s); return 0; } /******************* * Volumes */ int GetVolumeName(Session *s, int vol, char *name) { ncphdr(s, 0x1606, Tvarlen); p8(s, vol); if (ncpcall(s) == -1) return -1; gstr(s, name, VOLNAMLEN); return 0; } int GetVolumeNumber(Session *s, char *name, int *vol) { ncphdr(s, 0x1605, Tvarlen); pstr(s, name); if (ncpcall(s) == -1) return -1; *vol = g8(s); return 0; } int GetVolumeAndPurgeInfo(Session *s, int vol, VInfo *vi) { ncphdr(s, 0x162c, Tvarlen); p8(s, vol); if (ncpcall(s) == -1) return -1; vi->total = gl32(s); vi->free = gl32(s); vi->purgable = gl32(s); vi->notpurged = gl32(s); vi->dir_total = gl32(s); vi->dir_avail = gl32(s); gb32(s); // reserved vi->sectperblock = g8(s); gstr(s, vi->name, VOLNAMLEN); return 0; } /******************* * Bindery access */ int GetBinderyObjectName(Session *s, ulong id, char *name, int *type) { ncphdr(s, 0x1736, Tvarlen); pb32(s, id); if (ncpcall(s) == -1) return -1; gb32(s); // ID, but we already know that *type = gb16(s); gmem(s, name, OBJNAMLEN); return 0; } int GetBinderyObjectId(Session *s, char *name, int type, ulong *id) { ncphdr(s, 0x1735, Tvarlen); pb16(s, type); pstr(s, name); if (ncpcall(s) == -1) return -1; *id = gb32(s); return 0; } int ScanBinderyObject(Session *s, char *iname, int itype, int *id, char *oname, int *otype, int *hasprops, int *flags, int *rights) { ncphdr(s, 0x1737, Tvarlen); pb32(s, *id); pb16(s, itype); pstr(s, iname); if (ncpcall(s) == -1) return -1; *id = gb32(s); *otype = gb16(s); gmem(s, oname, OBJNAMLEN); *flags = g8(s); *rights = g8(s); *hasprops = g8(s); return 0; } ScanProperty(Session *s, char *obj, int type, char *prop, long *seq, char *name, int *flags, int *secure, int *hasval, int *ismore) { ncphdr(s, 0x173c, Tvarlen); pb16(s, type); pstr(s, obj); pb32(s, *seq); pstr(s, prop); if (ncpcall(s) == -1) return -1; gmem(s, name, PROPNAMLEN); *flags = g8(s); *secure = g8(s); *seq = gb32(s); *hasval = g8(s); *ismore = g8(s); return(0); } ReadPropertyValue(Session *s, char *object, int type, char *property, int seg, void *value, int *ismore, int *flags) { ncphdr(s, 0x173d, Tvarlen); pb16(s, type); pstr(s, object); p8(s, seg); pstr(s, property); if (ncpcall(s) == -1) return -1; gmem(s, value, PROPLEN); *flags = g8(s); *ismore = g8(s); return(0); } /******************* * Directory manipulation */ int DeteleFileOrDir(Session *s, int ns, int sa, char *path) { ncphdr(s, 0x5708, Tsubfun); p8(s, ns); p8(s, 0); // reserved pl16(s, sa); phps(s, path); return ncpcall(s); } int RenameOrMoveFileOrDir(Session *s, int ns, int flags, int sa, char *src, char *dst) { ncphdr(s, 0x5704, Tsubfun); p8(s, ns); p8(s, flags); pl16(s, sa); pphs2(s, src, dst); return ncpcall(s); } int ModifyFileOrDirInfo(Session *s, int ns, int sa, int mask, Mfi *mfi, char *path) { ncphdr(s, 0x5707, Tsubfun); p8(s, ns); p8(s, 0); // reserved pl16(s, sa); pl32(s, mask); pl32(s, mfi->attr); pdatetime(s, mfi->created); pb32(s, mfi->creator); pdatetime(s, mfi->modified); pb32(s, mfi->modifier); pdatetime(s, mfi->archived); pb32(s, mfi->archiver); pdate(s, mfi->accessed); pl16(s, mfi->grant); pl16(s, mfi->revoke); pl32(s, mfi->quota); phps(s, path); return ncpcall(s); } /******************* * File I/O */ int OpenCreateFileOrSubdir(Session *s, int ns, int mode, int sa, long mask, int rights, long attr, char *name, int *action, Fh fh,FInfo *i) { ncphdr(s, 0x5701, Tsubfun); p8(s, ns); p8(s, mode); pl16(s, sa); pl32(s, mask); pl32(s, attr); pl16(s, rights); // inherited rights mask phps(s, name); if (ncpcall(s) ==-1) return -1; gfhand32(s, fh); *action = g8(s); g8(s); // reserved ginfo(s, i); return(0); } /* * DANGER: netware versions before 5.0 require all transfers * to be block aligned, where a block is that size negoiated * at connection time with NegotiateBufferSize(); */ int ReadFromAFile(Session *s, Fh fh, void *b, long *len, long off) { ncphdr(s, 0x4800, Tsimple); p8(s, 0); // reserved pmem(s, fh, sizeof(Fh)); pb32(s, off); pb16(s, *len); if (ncpcall(s) == -1){ *len = -1; return -1; } *len = gb16(s); /* * netware strangeness - if the request * starts on an odd byte boundry then data will * be prefixed by a single byte of garbage. */ if (off & 1L) g8(s); gmem(s, b, *len); return 0; } /* * DANGER: netware versions before 5.0 require all transfers * to be block aligned, where a block is that size negoiated * at connection time with NegotiateBufferSize(); */ int WriteToAFile(Session *s, Fh fh, void *b, int len, long off) { ncphdr(s, 0x4900, Tsimple); p8(s, 0); // reserved pmem(s, fh, sizeof(Fh)); pb32(s, off); pb16(s, len); pmem(s, b, len); return ncpcall(s); } int CommitFile(Session *s, Fh fh) { ncphdr(s, 0x3b00, Tsimple); p8(s, 0); // reserved pmem(s, fh, sizeof(Fh)); return ncpcall(s); } int CloseFile(Session *s, Fh fh) { ncphdr(s, 0x4200, Tsimple); p8(s, 0); // reserved pmem(s, fh, sizeof(Fh)); return ncpcall(s); } /******************* * Directory scanning */ int InitializeSearch(Session *s, int ns, char *path, Srch srch) { ncphdr(s, 0x5702, Tsubfun); p8(s, ns); p8(s, 0); // reserved phps(s, path); if (ncpcall(s) == -1) return -1; gmem(s, srch, sizeof(Srch)); return(0); } int SearchFileOrSubdirectory(Session *s, Srch srch, int ns, int ds, int sa, char *path, int mask,FInfo *i) { ncphdr(s, 0x5703, Tsubfun); p8(s, ns); p8(s, ds); pl16(s, sa); pl32(s, mask); pmem(s, srch, sizeof(Srch)); pstr(s, path); if (ncpcall(s) == -1) return -1; gmem(s, srch, sizeof(Srch)); g8(s); // reserved ginfo(s, i); return(0); } int SearchFileOrSubdirectorySet(Session *s, Srch srch, int sns, int dns, int sa, char *path, long mask,FInfo *i, int *nent, int *more) { int n; ncphdr(s, 0x5714, Tsubfun); p8(s, sns); p8(s, dns); pl16(s, sa); pl32(s, mask); pl16(s, *nent); pmem(s, srch, sizeof(Srch)); pstr(s, path); if (ncpcall(s) == -1) return -1; gmem(s, srch, sizeof(Srch)); *more = g8(s); *nent = gl16(s); for (n = 0; n < *nent; n++, i++) ginfo(s, i); return(0); } int ObtainFileOrDirInfo(Session *s, int sns, int dns, long mask, char *path,FInfo *i) { ncphdr(s, 0x5706, Tsubfun); p8(s, sns); p8(s, dns); pl16(s, 0); pl32(s, mask); phps(s, path); if (ncpcall(s) == -1) return -1; ginfo(s, i); return 0; }