/* * $Author: djh $ $Date: 1996/06/19 04:26:25 $ * $Header: /mac/src/cap60/applications/aufs/RCS/afpdir.c,v 2.8 1996/06/19 04:26:25 djh Rel djh $ * $Revision: 2.8 $ * */ /* * afpdir.c - Appletalk Filing Protocol Directory Level Routines * * AppleTalk package for UNIX (4.2 BSD). * * Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University in the * City of New York. * * Edit History: * * March 1987 Schilit Created. * December 1990 djh tidy up for AFP 2.0 * */ /* * Non OS dependant support routines for: * * FPGetDirParms() * FPSetDirParms() * FPOpenDir() * FPCloseDir() * FPEnumerate() * FPCreateDir() * FPGetFileDirInfo() * */ #include #include #ifndef _TYPES /* assume included by param.h */ # include #endif #include #include #include #include "afpntoh.h" #include "afps.h" /* common server header */ #ifdef DEBUG_AFP_CMD #include #include extern FILE *dbg; #endif /* DEBUG_AFP_CMD */ private int EnumPack(); /* * OSErr FPGetDirParms(byte *p,byte *r,int *rl) * * This call is used to retrieve parameters for a particular directory. * */ OSErr FPGetFileDirParms(p,l,r,rl) byte *p,*r; int l; int *rl; { GetFileDirParmsPkt gfdp; FileDirParm fdp; IDirP idir,ipdir; char file[MAXUFLEN]; int ivol,err; ntohPackX(PsGetFileDirParms,p,l,(byte *) &gfdp); err = EtoIfile(file,&idir,&ipdir,&ivol,gfdp.gdp_dirid, gfdp.gdp_volid,gfdp.gdp_ptype,gfdp.gdp_path); #ifdef DEBUG_AFP_CMD if (dbg != NULL) { void dbg_print_bmap(); void dbg_print_path(); fprintf(dbg, "\tVolID: %04x\n", gfdp.gdp_volid); fprintf(dbg, "\tDirID: %08x\n", gfdp.gdp_dirid); fprintf(dbg, "\tFBMap: %04x\t", gfdp.gdp_fbitmap); dbg_print_bmap(gfdp.gdp_fbitmap, 0); fprintf(dbg, "\tDBMap: %04x\t", gfdp.gdp_dbitmap); dbg_print_bmap(gfdp.gdp_dbitmap, 1); fprintf(dbg, "\tPType: %d\t(%s Names)\n", gfdp.gdp_ptype, (gfdp.gdp_ptype == 1) ? "Short" : "Long"); dbg_print_path(gfdp.gdp_path); if (err == noErr) fprintf(dbg, "\tUPath: \"%s/%s\"\n", pathstr(ipdir), file); else fprintf(dbg, "\tUPath: \n", err); fflush(dbg); } #endif /* DEBUG_AFP_CMD */ if (err != noErr) { if (DBFIL || DBDIR) printf("FPGetFileDirParms: EtoIfile returns %d\n",err); #ifdef SHORT_NAMES if (gfdp.gdp_dirid > 1000) return(aeObjectNotFound); #endif SHORT_NAMES return(err); } fdp.fdp_pdirid = ItoEdirid(ipdir,ivol); fdp.fdp_dbitmap = gfdp.gdp_dbitmap; fdp.fdp_fbitmap = gfdp.gdp_fbitmap; fdp.fdp_zero = 0; err = OSFileDirInfo(ipdir,idir,file,&fdp,ivol); /* fill in information */ if (err != noErr) { if (DBFIL || DBDIR) printf("FPGetFileDirParms: OSFileDirInfo returns %d on %s/%s\n", err,pathstr(ipdir),file); return(err); } if (FDP_ISDIR(fdp.fdp_flg)) { *rl = htonPackX(DirParmPackR,(byte *)&fdp,r); *rl += htonPackX(DirPackR,(byte *)&fdp,r+(*rl)); } if (!FDP_ISDIR(fdp.fdp_flg)) { *rl = htonPackX(DirParmPackR,(byte *)&fdp,r); *rl += htonPackX(FilePackR,(byte *)&fdp,r+(*rl)); } /* * check for bogus bitmaps & truncate response * (DON'T return aeBitMapErr) * */ if ((!FDP_ISDIR(fdp.fdp_flg) && gfdp.gdp_dbitmap && !gfdp.gdp_fbitmap) || (FDP_ISDIR(fdp.fdp_flg) && !gfdp.gdp_dbitmap && gfdp.gdp_fbitmap)) *rl =6; #ifdef DEBUG_AFP_CMD if (dbg != NULL) { void dbg_print_parm(); void dbg_print_bmap(); fprintf(dbg, " Return Parameters:\n"); fprintf(dbg, "\tFBMap: %04x\t", fdp.fdp_fbitmap); dbg_print_bmap(fdp.fdp_fbitmap, 0); fprintf(dbg, "\tDBMap: %04x\t", fdp.fdp_dbitmap); dbg_print_bmap(fdp.fdp_dbitmap, 1); fprintf(dbg, "\tFDFlg: %02x\t(%s)\n", fdp.fdp_flg, FDP_ISDIR(fdp.fdp_flg) ? "Directory" : "File"); if (*rl == 6) fprintf(dbg, "\t\n"); else dbg_print_parm(FDP_ISDIR(fdp.fdp_flg) ? fdp.fdp_dbitmap:fdp.fdp_fbitmap, r+6, (*rl)-6, FDP_ISDIR(fdp.fdp_flg) ? 1 : (idir) ? 1 : 0); fflush(dbg); } #endif /* DEBUG_AFP_CMD */ return(noErr); } /* * OSErr FPEnumerate(...) * * This call is used to enumerate the contents of a directory. The * reply is composed of a number of file and/or directory parameter * structures. * */ OSErr FPEnumerate(p,l,r,rl) byte *p,*r; int l; int *rl; { FileDirParm fdp; EnumeratePkt enup; EnumerateReplyPkt enpr; IDirP idir,ipdir; char file[MAXUFLEN]; byte *cntptr; int ivol,stidx,idx,maxidx; word cnt; int reqcnt,maxreply,len,elen,err; extern int sqs; /* maximum send qs */ ntohPackX(PsEnumerate,p,l,(byte *) &enup); err = EtoIfile(file,&idir,&ipdir,&ivol,enup.enu_dirid, enup.enu_volid,enup.enu_ptype,enup.enu_path); #ifdef DEBUG_AFP_CMD if (dbg != NULL) { void dbg_print_bmap(); void dbg_print_path(); fprintf(dbg, "\tVolID: %04x\n", enup.enu_volid); fprintf(dbg, "\tDirID: %08x\n", enup.enu_dirid); fprintf(dbg, "\tFBMap: %04x\t", enup.enu_fbitmap); dbg_print_bmap(enup.enu_fbitmap, 0); fprintf(dbg, "\tDBMap: %04x\t", enup.enu_dbitmap); dbg_print_bmap(enup.enu_dbitmap, 1); fprintf(dbg, "\tRqCnt: %04x\n", enup.enu_reqcnt); fprintf(dbg, "\tStart: %04x\n", enup.enu_stidx); fprintf(dbg, "\tMaxRp: %04x\n", enup.enu_maxreply); fprintf(dbg, "\tPType: %d\t(%s Names)\n", enup.enu_ptype, (enup.enu_ptype == 1) ? "Short" : "Long"); dbg_print_path(enup.enu_path); if (err == noErr) fprintf(dbg, "\tUPath: \"%s/%s\"\n", pathstr(ipdir), file); else fprintf(dbg, "\tUPath: \n", err); fflush(dbg); } #endif /* DEBUG_AFP_CMD */ if (err != noErr) return(err); if (idir == NILDIR) return(aeDirNotFound); /* set the bitmaps for return message and packing */ fdp.fdp_fbitmap = enpr.enur_fbitmap = enup.enu_fbitmap; fdp.fdp_dbitmap = enpr.enur_dbitmap = enup.enu_dbitmap; /* set the parent dirid to the enumerated directory */ fdp.fdp_pdirid = ItoEdirid(idir,ivol); /* fetch the max size of a reply packet, start index, request count */ maxreply = enup.enu_maxreply; maxreply = min(sqs, maxreply); stidx = enup.enu_stidx; reqcnt = enup.enu_reqcnt; maxidx = OSEnumInit(idir); /* init, and fetch count of entries */ if (maxidx < 0) /* error? */ return(maxidx); /* return error */ if (stidx > maxidx) { /* start index gt count of entries? */ OSEnumDone(idir); return(aeObjectNotFound); /* yes... object not found then */ } cntptr = &r[ENUR_ACTCNT_OFF]; /* address of packed actcnt word */ len = htonPackX(EnumPackR,(byte *)&enpr,r); /* starting with the file/directory at stidx, load upto reqcnt * entries into the reply buffer. The size of the reply buffer must * not exceed maxreply bytes. Do not include a file/directory if * the associated bitmap is zero. */ for (idx=stidx,cnt=0; idx <= maxidx && cnt < (word)reqcnt; idx++) { elen = EnumPack(idir,&fdp,ivol,idx,&r[len]); if (elen > 0) { /* something packed for this entry? */ if (len+elen > maxreply) /* yes... check if overflow */ break; /* yes.. break out */ cnt++; /* else include entry in count */ len += elen; /* include entry in len */ if (len > maxreply-30) /* if close to the limit */ break; /* then break out now */ } } OSEnumDone(idir); /* finished with enumerate */ if (cnt == 0) /* filter tossed all */ return(aeObjectNotFound); PackWord(cnt,cntptr); /* pack the actual count */ *rl = len; /* length of packet for reply */ if (DBDIR) printf("OSEnum: maxreply=%d, ourreply=%d, reqcnt=%d, ourcnt=%d\n", maxreply,len,reqcnt,cnt); #ifdef DEBUG_AFP_CMD if (dbg != NULL) { int i = cnt; byte *q = r + 6; void dbg_print_bmap(); void dbg_print_parm(); fprintf(dbg, " Return Parameters:\n"); fprintf(dbg, "\tFBtMap: %04x\t", enpr.enur_fbitmap); dbg_print_bmap(enpr.enur_fbitmap, 0); fprintf(dbg, "\tDBtMap: %04x\t", enpr.enur_dbitmap); dbg_print_bmap(enpr.enur_dbitmap, 1); fprintf(dbg, "\tActCnt: %d\n", cnt); while (i-- > 0) { fprintf(dbg, "\t----------\n"); fprintf(dbg, "\tStrcLn: %d\n", (int)*q); fprintf(dbg, "\tEnType: %02x\t(%s)\n", *(q+1), (*(q+1) & 0x80) ? "Directory" : "File"); dbg_print_parm((*(q+1) & 0x80) ? enpr.enur_dbitmap : enpr.enur_fbitmap, q+2, (*q)-2, (*(q+1) & 0x80) ? 1 : 0); q += *q; } fflush(dbg); } #endif /* DEBUG_AFP_CMD */ return(noErr); /* all ok */ } /* * int EnumPack(IDirP ipdir, FileDirParm *fdp, int ivol, * int idx, byte *r); * * Pack a single enumeration entry as specified by the enumeration * idx and the enumeration direcotry ipdir. * * Fetch file/directory information for the entry as specified by * the parent directory (ipdir), the volume (ivol), and the name * from enumeration index (idx). * * If the file bitmap passed in fdp is zero and the entry is a file * then return 0. If the directory bitmap passed in fdp is zero and * the entry is a directory then return 0. * * In the normal case pack a length byte, directory flag byte, and * the file/directory information as specified by the fdp bitmaps * int r and return the length of of this entry. * */ private int EnumPack(ipdir,fdp,ivol,idx,r) IDirP ipdir; FileDirParm *fdp; int ivol,idx; byte *r; { char *fn; int len; int err; fn = (char *) OSEnumGet(ipdir,idx); /* get the file name */ /* and the info for this entry (nildir - no info on whether */ /* directory or not) */ err = OSFileDirInfo(ipdir,NILDIR,fn,fdp,ivol); if (err == aeAccessDenied) /* if no access */ return(0); /* then forget the entry */ if (FDP_ISDIR(fdp->fdp_flg)) { /* if a directory */ if (fdp->fdp_dbitmap == 0) /* and dir bitmap is zero */ return(0); /* then skip the entry */ len = htonPackX(DirPackR,(byte *) fdp,r+2); /* else pack */ } else { /* else, if a file */ if (fdp->fdp_fbitmap == 0) /* and file bitmap is zero */ return(0); /* then skip the entry */ len = htonPackX(FilePackR,(byte *) fdp,r+2); /* else pack */ } len += 2; /* include size, flg into sum */ if ((len % 2) != 0) /* if odd number of bytes */ r[len++] = 0; /* then even out the length */ r[0] = (byte) len; /* store length of structure */ r[1] = fdp->fdp_flg; /* directory flag */ return(len); /* return length of this item */ } /*ARGSUSED*/ OSErr FPSetDirParms(p,l,r,rl) byte *p,*r; int l; int *rl; { SetDirParmsPkt sdp; FileDirParm fdp; IDirP ipdir,idir; int ivol,len,err; char file[MAXUFLEN]; len = ntohPackX(PsSetDirParms,p,l,(byte *) &sdp); ntohPackXbitmap(ProtoDirAttr,p+len,l-len, (byte *) &fdp,sdp.sdp_bitmap); err = EtoIfile(file,&idir,&ipdir,&ivol,sdp.sdp_dirid, sdp.sdp_volid,sdp.sdp_ptype,sdp.sdp_path); #ifdef DEBUG_AFP_CMD if (dbg != NULL) { char *pathstr(); void dbg_print_bmap(); void dbg_print_parm(); void dbg_print_path(); fprintf(dbg, "\tVolID: %04x\n", sdp.sdp_volid); fprintf(dbg, "\tDirID: %08x\n", sdp.sdp_dirid); fprintf(dbg, "\tFBMap: %04x\t", sdp.sdp_bitmap); dbg_print_bmap(sdp.sdp_bitmap, 1); fprintf(dbg, "\tPType: %d\t(%s Names)\n", sdp.sdp_ptype, (sdp.sdp_ptype == 1) ? "Short" : "Long"); dbg_print_path(sdp.sdp_path); if (err == noErr) fprintf(dbg, "\tUPath: \"%s/%s\"\n", pathstr(ipdir), file); else fprintf(dbg, "\tUPath: \n", err); dbg_print_parm(sdp.sdp_bitmap, p+len, l-len, 1); fflush(dbg); } #endif /* DEBUG_AFP_CMD */ if (err != noErr) return(err); fdp.fdp_dbitmap = sdp.sdp_bitmap; /* using this bitmap */ if (DBDIR) printf("FPSetDirParms: path=%s, file=%s, bm=%d\n", pathstr(ipdir),file,sdp.sdp_bitmap); err = OSSetDirParms(ipdir,file,&fdp); /* set dirparms */ if (err == noErr) VolModified(ivol); return(err); } #ifdef SHORT_NAMES OSErr FPOpenDir(p,l,r,rl) byte *p, *r; int l; int *rl; { OpenDirPkt ODPkt; IDirP idir,ipdir; char file[MAXUFLEN]; int ivol,err; ntohPackX(PsOpenDir,p,l,(byte*)&ODPkt); err = EtoIfile(file,&idir,&ipdir,&ivol,ODPkt.odr_dirid, ODPkt.odr_volid, ODPkt.odr_ptype,ODPkt.odr_path); #ifdef DEBUG_AFP_CMD if (dbg != NULL) { void dbg_print_path(); fprintf(dbg, "\tVolID: %04x\n", ODPkt.odr_volid); fprintf(dbg, "\tDirID: %08x\n", ODPkt.odr_dirid); fprintf(dbg, "\tPType: %d\t(%s Names)\n", ODPkt.odr_ptype, (ODPkt.odr_ptype == 1) ? "Short" : "Long"); dbg_print_path(ODPkt.odr_path); if (err == noErr) fprintf(dbg, "\tUPath: \"%s/%s\"\n", pathstr(ipdir), file); else fprintf(dbg, "\tUPath: \n", err); fflush(dbg); } #endif /* DEBUG_AFP_CMD */ if ((err != noErr) && (DBDIR)) printf("error returned from EtoIfile\n"); PackDWord(ItoEdirid(idir,ivol),r); *rl = 4; return(noErr); } #else SHORT_NAMES OSErr FPOpenDir() { return(aeParamErr); } #endif SHORT_NAMES OSErr FPCloseDir() { return(aeParamErr); } OSErr FPCreateDir(p,l,r,rl) byte *p,*r; int l; int *rl; { CreateDirPkt crd; IDirP idir,ipdir; int ivol,err; char file[MAXUFLEN]; ntohPackX(PsCreateDir,p,l,(byte *) &crd); err = EtoIfile(file,&idir,&ipdir,&ivol,crd.crd_dirid, crd.crd_volid,crd.crd_ptype,crd.crd_path); #ifdef DEBUG_AFP_CMD if (dbg != NULL) { void dbg_print_path(); fprintf(dbg, "\tVolID: %04x\n", crd.crd_volid); fprintf(dbg, "\tDirID: %08x\n", crd.crd_dirid); fprintf(dbg, "\tPType: %d\t(%s Names)\n", crd.crd_ptype, (crd.crd_ptype == 1) ? "Short" : "Long"); dbg_print_path(crd.crd_path); if (err == noErr) fprintf(dbg, "\tUPath: \"%s/%s\"\n", pathstr(ipdir), file); else fprintf(dbg, "\tUPath: \n", err); fflush(dbg); } #endif /* DEBUG_AFP_CMD */ if (err != noErr) return(err); if (DBFIL) printf("FPCreateDir: create path=%s name=%s\n",pathstr(ipdir),file); if ((err = OSCreateDir(ipdir,file, &idir)) == noErr) { if (DBFIL) printf("FPCreateDir: create path=%s name=%s edirID=%d\n", pathstr(ipdir),file,idir->edirid); PackDWord(ItoEdirid(idir,ivol),r); *rl = 4; } if (err == noErr) /* if success */ VolModified(ivol); /* then volume modified */ return(err); } /* * Preliminary version - just does files * */ /*ARGSUSED*/ OSErr FPSetFileDirParms(p,l,r,rl) byte *p, *r; int l; int *rl; { SetFileDirParmsPkt scp; FileDirParm fdp; IDirP idir,ipdir; char file[MAXUFLEN]; int ivol,len,err; len = ntohPackX(PsSetFileDirParms,p,l,(byte *) &scp); ntohPackXbitmap(ProtoFileDirAttr,p+len,l-len,(byte *) &fdp,scp.scp_bitmap); err = EtoIfile(file,&idir,&ipdir,&ivol,scp.scp_dirid, scp.scp_volid,scp.scp_ptype,scp.scp_path); #ifdef DEBUG_AFP_CMD if (dbg != NULL) { void dbg_print_bmap(); void dbg_print_parm(); void dbg_print_path(); fprintf(dbg, "\tVolID: %04x\n", scp.scp_volid); fprintf(dbg, "\tDirID: %08x\n", scp.scp_dirid); fprintf(dbg, "\tBtMap: %04x\t", scp.scp_bitmap); dbg_print_bmap(scp.scp_bitmap, 0); fprintf(dbg, "\tPType: %d\t(%s Names)\n", scp.scp_ptype, (scp.scp_ptype == 1) ? "Short" : "Long"); dbg_print_path(scp.scp_path); if (err == noErr) fprintf(dbg, "\tUPath: \"%s/%s\"\n", pathstr(ipdir), file); else fprintf(dbg, "\tUPath: \n", err); dbg_print_parm(scp.scp_bitmap, p+len, l-len, (idir) ? 1 : 0); fflush(dbg); } #endif /* DEBUG_AFP_CMD */ if (err != noErr) return(err); fdp.fdp_dbitmap = fdp.fdp_fbitmap = scp.scp_bitmap; if (DBFIL) printf("FPSetFileDirParms: setting bm=%d for %s %s\n", scp.scp_bitmap,pathstr(ipdir),file); return(OSSetFileDirParms(ipdir,idir,file,&fdp)); } #ifdef DEBUG_AFP_CMD /* * describe FPGetFileDirParms/FPGetFileInfo bitmaps * */ void dbg_print_bmap(bmap, typ) u_short bmap; int typ; { int i, j; if (dbg != NULL) { fprintf(dbg, "("); for (i = 0, j = 0; i < 16; i++) { if (bmap & (0x0001 << i)) { bmap &= ~(0x0001 << i); switch (i) { case 0: fprintf(dbg, "Attributes"); j++; break; case 1: fprintf(dbg, "Parent DID"); j++; break; case 2: fprintf(dbg, "Creat Date"); j++; break; case 3: fprintf(dbg, "Modif Date"); j++; break; case 4: fprintf(dbg, "Bakup Date"); j++; break; case 5: fprintf(dbg, "Findr Info"); j++; break; case 6: fprintf(dbg, "Long Name"); j++; break; case 7: fprintf(dbg, "Short Name"); j++; break; case 8: if (typ) fprintf(dbg, "Direct ID"); else fprintf(dbg, "File Numbr"); j++; break; case 9: if (typ) fprintf(dbg, "OffSpr Cnt"); else fprintf(dbg, "DFork Len"); j++; break; case 10: if (typ) fprintf(dbg, "Owner ID"); else fprintf(dbg, "RFork Len"); j++; break; case 11: if (typ) fprintf(dbg, "Group ID"); j++; break; case 12: if (typ) { fprintf(dbg, "Acs Rights"); j++; } break; case 13: fprintf(dbg, "ProDos Inf"); j++; break; default: fprintf(dbg, "Unknwn Bit"); j++; break; } if (bmap) fprintf(dbg, ", "); if (bmap && (j % 4) == 0) fprintf(dbg, "\n\t\t\t"); } } fprintf(dbg, ")\n"); } return; } /* * dump parameters described by bitmap * */ #define get2(s) (u_short)(((s)[0]<<8)|((s)[1])) #define get4(s) (u_int)(((s)[0]<<24)|((s)[1]<<16)|((s)[2]<<8)|((s)[3])) void dbg_print_parm(bmap, r, rl, typ) u_short bmap; byte *r; int rl, typ; { int i, j; byte *p, *q; short offset; void dbg_print_attr(); void dbg_print_date(); void dbg_print_accs(); void dbg_print_fndr(); p = r; /* parameters */ if (dbg != NULL) { for (i = 0; i < 16 && rl > 0; i++) { if (bmap & (0x0001 << i)) { switch (i) { case 0: fprintf(dbg, "\tAttributes: "); dbg_print_attr(get2(r), typ); rl -= 2; r += 2; break; case 1: fprintf(dbg, "\tParent DID: %08x\n", get4(r)); rl -= 4; r += 4; break; case 2: fprintf(dbg, "\tCreat Date: "); dbg_print_date(get4(r)); rl -= 4; r += 4; break; case 3: fprintf(dbg, "\tModif Date: "); dbg_print_date(get4(r)); rl -= 4; r += 4; break; case 4: fprintf(dbg, "\tBakup Date: "); dbg_print_date(get4(r)); rl -= 4; r += 4; break; case 5: fprintf(dbg, "\tFindr Info:\n"); dbg_print_fndr(r, typ); rl -= 32; r += 32; break; case 6: fprintf(dbg, "\t Long Name: \""); offset = get2(r); q = p + offset; for (j = 0; j < (int)*q; j++) fprintf(dbg, "%c", *(q+j+1)); fprintf(dbg, "\"\n"); rl -= 2; r += 2; break; case 7: fprintf(dbg, "\tShort Name: "); offset = get2(r); q = p + offset; for (j = 0; j < (int)*q; j++) fprintf(dbg, "%c", *(q+j+1)); fprintf(dbg, "\"\n"); rl -= 2; r += 2; break; case 8: if (typ) fprintf(dbg, "\t Direct ID: %08x\n", get4(r)); else fprintf(dbg, "\tFile Numbr: %08x\n", get4(r)); rl -= 4; r += 4; break; case 9: if (typ) { fprintf(dbg, "\tOffSpr Cnt: %d\n", get2(r)); rl -= 2; r += 2; } else { fprintf(dbg, "\t DFork Len: %d\n", get4(r)); rl -= 4; r += 4; } break; case 10: if (typ) fprintf(dbg, "\t Owner ID: %08x\n", get4(r)); else fprintf(dbg, "\t RFork Len: %d\n", get4(r)); rl -= 4; r += 4; break; case 11: if (typ) { fprintf(dbg, "\t Group ID: %08x\n", get4(r)); rl -= 4; r += 4; } break; case 12: if (typ) { fprintf(dbg, "\tAcs Rights: "); dbg_print_accs(r); rl -= 4; r += 4; } break; case 13: fprintf(dbg, "\tProDos Inf:\n"); rl -= 6; r += 6; break; default: fprintf(dbg, "\t\n", i); break; } } } } return; } /* * Print the 16-bit File/Dir attributes * */ void dbg_print_attr(attr, typ) u_int attr; int typ; { int i, j; if (dbg != NULL) { fprintf(dbg, "%04x (", attr); for (i = 0, j = 0; i < 16; i++) { if (attr & (0x0001 << i)) { attr &= ~(0x0001 << i); switch (i) { case 0: fprintf(dbg, "Invisible"); j++; break; case 1: if (typ) fprintf(dbg, "IsExpFolder"); else fprintf(dbg, "MultiUser"); j++; break; case 2: fprintf(dbg, "System"); j++; break; case 3: if (typ) fprintf(dbg, "Mounted"); else fprintf(dbg, "DAlrdyOpen"); j++; break; case 4: if (typ) fprintf(dbg, "InExpFolder"); else fprintf(dbg, "RAlrdyOpen"); j++; break; case 5: if (typ) fprintf(dbg, "", i); else fprintf(dbg, "RDOnly/WrtInhib"); j++; break; case 6: fprintf(dbg, "BackupNeeded"); j++; break; case 7: fprintf(dbg, "RenameInhib"); j++; break; case 8: fprintf(dbg, "DeleteInhib"); j++; break; case 9: if (typ) fprintf(dbg, ""); else fprintf(dbg, "CopyProtect"); j++; break; case 15: fprintf(dbg, "Set/Clear"); j++; break; default: fprintf(dbg, "", i); j++; break; } if (attr) fprintf(dbg, ", "); if (attr && (j % 4) == 0) fprintf(dbg, "\n\t\t\t"); } } fprintf(dbg, ")\n"); } return; } /* * print Finder Information * */ void dbg_print_fndr(f, typ) byte *f; int typ; { void dbg_print_type(); /* * File Finder Info * */ if (typ == 0) { dbg_print_type("\t FilTyp:", f); f += 4; dbg_print_type("\t Creatr:", f); f += 4; fprintf(dbg, "\t FdrFlg: %04x\n", get2(f)); f += 2; fprintf(dbg, "\t Locatn: %04x %04x\n", get2(f), get2(f+2)); f += 4; fprintf(dbg, "\t Window: %04x\n", get2(f)); f += 2; fprintf(dbg, "\t IconID: %04x\n", get2(f)); f += 2; f += 8; /* unused */ fprintf(dbg, "\t CommID: %04x\n", get2(f)); f += 2; fprintf(dbg, "\t HomeID: %08x\n", get4(f)); return; } /* * Directory Finder Info * */ if (typ == 1) { fprintf(dbg, "\t DiRect: %04x %04x %04x %04x\n", get2(f), get2(f+2), get2(f+4), get2(f+6)); f += 8; fprintf(dbg, "\t FdrFlg: %04x\n", get2(f)); f += 2; fprintf(dbg, "\t Locatn: %04x %04x\n", get2(f), get2(f+2)); f += 4; fprintf(dbg, "\t FdView: %04x\n", get2(f)); f += 2; fprintf(dbg, "\t Scroll: %04x %04x\n", get2(f), get2(f+2)); f += 4; fprintf(dbg, "\t DChain: %08x\n", get4(f)); f += 4; fprintf(dbg, "\t Script: %02x\n", *f); fprintf(dbg, "\t XFlags: %02x\n", *(f+1)); f += 2; fprintf(dbg, "\t CommID: %04x\n", get2(f)); f += 2; fprintf(dbg, "\t HomeID: %08x\n", get4(f)); return; } return; } /* * print 4 byte access rights * */ void dbg_print_accs(accs) byte *accs; { if (dbg != NULL) { if (accs[0] & 0x80) fprintf(dbg, "OWNER, "); if (accs[0] & 0x10) fprintf(dbg, "BLANK ACCESS, "); fprintf(dbg, "UARights %02x, World %02x, Group %02x, Owner %02x\n", accs[0] & 0x07, accs[1], accs[2], accs[3]); } return; } /* * print the AFP date * */ void dbg_print_date(date) time_t date; { char *ctime(); time_t offset; struct timeval tp; struct timezone tzp; if (dbg != NULL) { if (date == 0x80000000) { fprintf(dbg, "\n"); return; } #ifdef SOLARIS tzset(); offset = timezone; #else /* SOLARIS */ gettimeofday(&tp, &tzp); offset = (time_t)(tzp.tz_minuteswest*60); #endif /* SOLARIS */ date = date - (((30*365+7)*(-24)*3600L)) + offset; fprintf(dbg, "%s", ctime(&date)); } return; } /* * print a path name (pascal string) * */ void dbg_print_path(path) char *path; { int i; if (dbg != NULL) { fprintf(dbg, "\tMFile: \""); for (i = 0; i < *path; i++) if (isprint(*(path+i+1))) fprintf(dbg, "%c", *(path+i+1)); else fprintf(dbg, "<0x%02x>", *(path+i+1)); fprintf(dbg, "\"\n"); } } #endif /* DEBUG_AFP_CMD */