This is afpcmd.c in view mode; [Download] [Up]
/* * $Author: cck $ $Date: 88/05/13 09:28:13 $ * $Header: afpcmd.c,v 1.11 88/05/13 09:28:13 cck Rel $ * $Revision: 1.11 $ */ /* * afpcmd.c - Packing and unpacking commands * * AppleTalk package for UNIX (4.2 BSD). * * Copyright (c) 1986, 1987 by The Trustees of Columbia University in the * City of New York. * * WARNING: if your machine is not a vax, sun, ibm pc/rt or pyramid * you must define BYTESWAPPED if you machine is byteswapped * * Edit History: * * Thu Oct 30 Schilit Created * */ #include <sys/types.h> #include <sys/time.h> #include <netinet/in.h> /* for ntohs, etc. */ #include <netat/appletalk.h> #include <netat/afp.h> #include <netat/afpcmd.h> /* following would be really simple if we could use #if, but vms */ /* c doesn't like and hopefully someday... */ #ifndef BYTESWAPPED # ifdef vax /* This should be defined if you are byte swapped. */ # define BYTESWAPPED # endif #endif /* What bogusity */ #ifndef LOOSE_BYTESWAPPED # ifdef vax /* This should only be defined if you are byte swapped and you can be sure */ /* (byte *) would be the same as a (word *) or (dword *) */ # define LOOSE_BYTESWAPPED # endif #endif #ifndef BYTESWAPPED # ifdef ns16000 # define BYTESWAPPED # endif #endif #ifndef BYTESWAPPED # ifdef ns32000 # define BYTESWAPPED # endif #endif /* add this in case sequent doesn't define nsxxxxx */ #ifndef BYTESWAPPED # ifdef sequent # define BYTESWAPPED # endif #endif /* machines that aren't byteswapped include: ibm032, pyr, sun, hpux, etc */ #define NULL 0 export void InitPackTime(); private void ItoETime(); private void EtoITime(); char *PackNames[] = { "Word", /* P_WORD */ "Byte", /* P_BYTE */ "Double Word", /* P_DWRD */ "Bytes", /* P_BYTS */ "Pascal String", /* P_PSTR */ "BitMap", /* P_BMAP */ "Offset String", /* P_OSTR */ "Path String", /* P_PATH */ "Offset to Pointer", /* P_OPTR */ "Offset Path", /* P_OPTH */ "Even boundary", /* P_EVEN */ "Zero", /* P_ZERO */ "Time" /* P_TIME */ }; int ntohPackX(pt, net, nlen, host) PackEntry *pt; byte *net; byte *host; int nlen; { int ntohPackXbitmap(); return(ntohPackXbitmap(pt, net, nlen, host, (word)0)); } int ntohPackXbitmap(pt,net,nlen,host, bitmap) PackEntry *pt; byte *net; byte *host; int nlen; word bitmap; { int i; int si = 0; word bmap = bitmap; void upack(); /* need to find bmap */ for (i=0; pt[i].pe_typ != P_END; i++) if (si < nlen) upack(&pt[i],net,&si,host,&bmap); /* unpack each item */ return(si); } typedef struct Var_Object { int vo_typ; /* type of variable object */ byte *vo_offset; /* store offset word (INT) here */ byte *vo_object; /* pointer to the object to store */ } VarObject; typedef struct { int vol_first; /* index at start of var objects */ int vol_count; /* count of var objects */ VarObject vol_vos[10]; /* array of variable objects */ } VarObjList; /* * Convert Packet from Host to Net, returns size of net packet. * */ int htonPackX(pe, host, net) PackEntry *pe; byte *host; byte *net; { return(htonPackXbitmap(pe, host, net, 0)); } int htonPackXbitmap(pe,host,net, bitmap) PackEntry *pe; byte *host; byte *net; word bitmap; { VarObjList vol; int i; word bmap = bitmap; int nidx = 0; void pack(); vol.vol_first = 0; /* position 0 for first var object */ vol.vol_count = 0; /* no var objects */ for (i=0; pe[i].pe_typ != P_END; i++) pack(&pe[i],host,net,&nidx,&bmap,&vol); /* scan variable length object list and pack them now */ for (i = 0; i < vol.vol_count; i++) { byte *d; VarObject *vo; OPTRType *optr,**optrr; word wrd; vo = &vol.vol_vos[i]; /* handle on a var object */ /* set offset from start (in remember spot) */ wrd = htons(nidx-vol.vol_first); bcopy(&wrd, vo->vo_offset, sizeof(word)); d = &net[nidx]; /* destination */ /* assume object is PSTR */ switch (vo->vo_typ) { case P_OSTR: cpyc2pstr(d,vo->vo_object); /* copy the pascal string */ nidx += (*d)+1; break; case P_OPTR: /* is a variable length object */ optrr = (OPTRType **) (vo->vo_object); optr = *optrr; bcopy(optr->optr_loc,d,optr->optr_len); /* copy the bytes */ nidx += optr->optr_len; /* increment length */ break; } } return(nidx); /* return length */ } void pack(pe,src,dest,di,bmap,vol) PackEntry *pe; byte *src,*dest; int *di; VarObjList *vol; word *bmap; { byte *s,*d; int siz; word wrd; dword dwrd; if (pe->pe_bit != 0) { /* check if bitmap item */ if ((*bmap & pe->pe_bit) == 0) /* see if a requested bitmap item */ return; /* no, forget it */ } d = &dest[*di]; /* destination is net */ s = &src[pe->pe_off]; /* source is host */ siz = pe->pe_siz; switch (pe->pe_typ) { /* according to the data type */ case P_BMAP: /* bitmap (2 bytes) */ bcopy(s, bmap, sizeof(word)); /* copy bitmap */ vol->vol_first = *di; /* offset */ break; /* BITMAP does NOT get included */ #ifdef BYTESWAPPED case P_WORD: # ifdef LOOSE_BYTESWAPPED /* we should be able to get away with this */ *((word *)d) = htons(*(word *)s); # else bcopy(s, &wrd, sizeof(word)); /* copy in case not byte aligned */ wrd = htons(wrd); /* convert to netorder */ bcopy(&wrd, d, sizeof(word)); /* and copy into dest */ # endif *di += 2; break; case P_DWRD: /* long (4 bytes) */ # ifdef LOOSE_BYTESWAPPED *((dword *)d) = htonl(*(dword *)s); # else bcopy(s, &dwrd, sizeof(dword)); /* copy in case not byte aligned */ dwrd = htonl(dwrd); /* convert to netorder */ bcopy(&dwrd, d, sizeof(dword)); /* and copy into dest */ # endif *di += 4; break; #else case P_WORD: /* int (2 bytes) */ case P_DWRD: #endif case P_BYTE: case P_BYTS: bcopy(s, d, siz); /* copy the word */ *di += siz; break; case P_TIME: /* do external to internal time conversion */ /* assumes time_t input, sdword output */ bcopy(s,&dwrd,sizeof(dwrd)); /* copy it */ *di += 4; /* advance */ ItoETime(dwrd, d); /* convert to internal time */ break; case P_PSTR: /* c to pascal string */ cpyc2pstr(d,s); *di += (*d)+1; break; case P_OPTR: case P_OSTR: /* offset string */ { VarObject *vo; vo = &vol->vol_vos[vol->vol_count++]; /* handle on object entry */ vo->vo_typ = pe->pe_typ; /* save type */ vo->vo_object = s; /* the object to pack */ vo->vo_offset = d; /* location to store offset */ *di += 2; /* increment by offset size */ } break; case P_PATH: bcopy(s,d,(int) (*s)+1); /* pascal string with imbedded nulls */ *di += (*s)+1; break; case P_EVEN: if ((*di % 2) != 0) { *d = 0; /* zero the current byte */ (*di)++; } break; case P_ZERO: bzero(d, siz); *di += siz; break; } return; } /* * * Unpack net to host. Source is net, dest is host. * */ void upack(pe,src,si,dest,bmap) PackEntry *pe; int *si; byte *src,*dest; word *bmap; { word sos; byte *d,*s; word wrd; dword dwrd; int siz; if (pe->pe_bit != 0) /* check bitmap active */ if ((*bmap & pe->pe_bit) == 0) /* then if not a bitmap item */ return; /* forget it */ d = &dest[pe->pe_off]; /* remember host destination */ s = &src[*si]; /* net source */ siz = pe->pe_siz; switch (pe->pe_typ) { /* according to the data type */ case P_BMAP: /* bitmap (2 bytes) */ bcopy(d, bmap, sizeof(word)); /* copy bitmap */ break; #ifdef BYTESWAPPED case P_WORD: /* word (2 bytes) */ # ifdef LOOSE_BYTESWAPPED *((word *)d) = ntohs(*(word *)s); # else bcopy(s, &wrd, sizeof(word)); /* copy in case unaligned */ wrd = ntohs(wrd); /* convert to net order */ bcopy(&wrd, d, sizeof(word)); /* and copy it back */ # endif *si += 2; break; case P_DWRD: /* double word (4 bytes) */ # ifdef LOOSE_BYTESWAPPED *((dword *)d) = ntohl(*(dword *)s); # else bcopy(s, &dwrd, sizeof(dword)); /* copy in case unaligned */ dwrd = ntohl(dwrd); /* convert to net order */ bcopy(&dwrd, d, sizeof(dword)); /* and copy it back */ # endif *si += 4; break; #else case P_WORD: /* word (2 bytes) */ case P_DWRD: /* double word (4 bytes) */ #endif case P_BYTE: /* byte (1 byte) */ case P_BYTS: /* byte string */ bcopy(s,d,siz); /* copy bytes */ *si += siz; break; case P_TIME: /* do external to internal time conversion */ /* assumes sdword input, time_t output */ bcopy(s,&dwrd,sizeof(dwrd)); /* copy it */ *si += 4; /* advance */ EtoITime(dwrd, d); /* convert to internal time */ break; case P_PSTR: /* c to pascal string */ cpyp2cstr(d,s); *si += (*s)+1; break; case P_OSTR: /* offset string */ sos = ntohs(*(word *)s); /* pick up offset from base */ *si += 2; cpyp2cstr(d,&src[sos]); /* copy string */ break; case P_OPTH: sos = ntohs(*(word *)s); /* pick up offset from base */ *si += 2; bcopy(&src[sos],d,(int)src[sos]+1); /* copy string */ break; case P_PATH: bcopy(s,d,(int) (*s)+1); /* pascal string with imbedded nulls */ *si += (*s)+1; break; case P_OPTR: sos = ntohs(*(word *)s); /* pick up offset from base */ *si += 2; *((char **)d) = (char *)&src[sos]; break; case P_EVEN: if ((*si % 2) != 0) /* even boundary? */ (*si)++; /* no, move ahead */ break; case P_ZERO: /* supposed to be zero? */ *si += siz; /* then, just skip */ *d = 0; /* zero dest */ break; } } /* * void PackDWord(dword s, byte *d) * * Pack a double word into destination. * */ void PackDWord(s,d) dword s; byte *d; { #ifdef LOOSE_BYTESWAPPED *((dword *)d) = htonl(s); #else # ifdef BYTESWAPPED s = htonl(s); # endif bcopy(&s, d, sizeof(dword)); #endif } void PackWord(s,d) word s; byte *d; { #ifdef LOOSE_BYTESWAPPED *((word *)d) = htons(s); #else # ifdef BYTESWAPPED s = htons(s); # endif bcopy(&s, d, sizeof(word)); #endif } /* * * Unpack double word (4 bytes) from src into dest. * The src pointer is updated. * */ void UnpackDWord(src,dest) byte **src; dword *dest; { #ifdef BYTESWAPPED # ifdef LOOSE_BYTESWAPPED *dest = ntohl(*(dword *)(*src)); # else dword dwrd; bcopy(*src, &dwrd, sizeof(dword)); dwrd = ntohl(dwrd); bcopy(&dwrd, dest, sizeof(dword)); # endif #else bcopy(*src, dest, sizeof(dword)); #endif *src += 4; /* update source pointer */ } /* * * Unpack word (2 bytes) from src into dest. The src pointer is updated. * */ void UnpackWord(src,dest) byte **src; word *dest; { #ifdef BYTESWAPPED # ifdef LOOSE_BYTESWAPPED *dest = ntohs(*(word *)(*src)); # else word wrd; bcopy(*src, &wrd, sizeof(word)); wrd = ntohs(wrd); bcopy(&wrd, dest, sizeof(word)); # endif #else bcopy(*src, dest, sizeof(word)); #endif *src += 2; /* update source pointer */ } /* * void ItoETime(time_t it, dword *et) * void EtoITime(dowrd et, time_t *it) * * Convert between Internal Unix time and External AFP time. * * All date and time quantities used by AFP are Greenwich Mean Time (GMT) * values. They are 32 bit signed integers corresponding to the number of * seconds measured from 12:00AM January 1, 2000 (the start of the next * century corresponds to datetime=0). * * BSD time base is 12:00AM January 1, 1970 * AFP time base is 12:00AM January 1, 2000 * * Actually, it seems that the Mac sends MacTime - could it be * that our copy of AppleShare does the wrong thing? Version 1.00 was * bad. Fixed in 1.10 and (hopefully) beyond. * * Another problem exists with DST which is not handled here. * I mean, things will be within 2 hours isn't that good enough :-) * * WARNING: if this code breaks, it will be on or near Jan 1, 2000 * or Jan 18, 2038. Of course, it's doubtful that this code * will last that long :-) * */ private int mactime_not_inited = 1; private long mymactime; private long maczerotime; /* difference btwn unix and mac in seconds */ /* mac starts at jan 1, 1904 for appleshare 1.0 */ #define AS1DOT0_MACZEROTIME 0 /* zero time - see comments above */ #define AS1DOT0_MACTIME (66*365+17)*24*60*60L /* difference btween midnight jan 1, 1970 and midnight jan 1, 2000 */ /* for all others */ #define MACTIME (((30*365+7)*(-24)*3600L)) #define MACZEROTIME 0x80000000 /* zero time - from AppleShare 1.1 on */ /* Does time zone adjustment */ /* call with flag set for appleshare 10 style */ export void InitPackTime(flag) int flag; { struct timeval tp; struct timezone tzp; mactime_not_inited = 0; gettimeofday(&tp, &tzp); if (flag) { mymactime = AS1DOT0_MACTIME; maczerotime = AS1DOT0_MACZEROTIME; } else { mymactime = MACTIME; maczerotime = MACZEROTIME; } mymactime -= ((long)tzp.tz_minuteswest*60); } private void ItoETime(ost,atpt) time_t ost; sdword *atpt; /* signed double word */ { sdword temp; if (mactime_not_inited) InitPackTime(0); /* assume past version 1.0 */ temp = htonl((ost) ? ((sdword)ost + mymactime) : maczerotime); bcopy(&temp, atpt, sizeof(temp)); } private void EtoITime(atpt,ost) sdword atpt; /* signed double word */ time_t *ost; { time_t temp; if (mactime_not_inited) InitPackTime(0); /* assume past version 1.0 */ atpt = ntohl(atpt); temp = (atpt == maczerotime) ? 0 : ((time_t)atpt - mymactime); bcopy(&temp, ost, sizeof(time_t)); /* copy out */ }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.