/* @(#)scdc.c 17.1.1.1 (ESO-DMD) 01/25/02 17:36:26 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++ SC interface module SCDC +++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION Module SCDC.C .AUTHOR K. Banse ESO - Garching .KEYWORDS standard interfaces, descriptors .ENVIRONMENT VMS and UNIX .COMMENTS holds SCDDEL, SCDCOP, SCDGETC, SCDFND, SCDINF, ZSCDINF, YSCDINF .VERSION [1.00] 920211: pulled out from scd.c 010911 last modif ----------------------------------------------------------------------------*/ #include #include #define DISK_REC 512 /* size of disk record */ /* */ int SCDDEL(imno,descr) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE delete a descriptor .ALGORITHM the descriptor directory is scanned for the specified name and if found, that name is marked as deleted If descriptor = ' ', reinitialize descriptor area. .RETURNS return status ( 0 = o.k. ) -----------------------------------------------------------------------*/ int imno; /* IN : no. of data frame */ char *descr; /* IN : descriptor name */ { int status, bytelem, noelem, dblock, dindx, dunit, dsclen; char dtype[4]; char realdescr[52], help[72]; struct FCB_STRUCT *fcbp; struct FCT_STRUCT *fctpntr; if ( (imno < 0) || (imno >= FCT.MAXENT) ) { status = ERR_INPINV; goto end_of_it; } fctpntr = FCT.ENTRIES + imno; fcbp = fctpntr->FZP; /* if descriptor name is '*', reinitialize descriptor area */ if (*descr == '*') status = MID_INITDS(fcbp,fctpntr->IOCHAN); /* do the rest via MID_INITDS */ else { /* otherwise delete single descriptor */ dsclen = DSCNAM_COPY(realdescr,descr); /* build uppercase name */ dtype[0] = ' '; if (fcbp->DSCFLAG == 'Z') { status = MID_ZDSCDIR(imno,'F',realdescr,dsclen,dtype, &bytelem,&noelem,&dunit,&dblock,&dindx); if (status == ERR_NORMAL) status = MID_ZDSCDIR(imno,'D',realdescr,dsclen,dtype, &bytelem,&noelem,&dunit,&dblock,&dindx); } else if (fcbp->DSCFLAG == 'Y') { status = MID_YDSCDIR(imno,'F',realdescr,dtype, &bytelem,&noelem,&dunit,&dblock,&dindx,help); if (status == ERR_NORMAL) status = MID_YDSCDIR(imno,'D',realdescr,dtype, &bytelem,&noelem,&dunit,&dblock,&dindx,help); } else { status = MID_DSCDIR(imno,'F',descr,dtype, &bytelem,&noelem,&dunit,&dblock,&dindx); if (status == ERR_NORMAL) status = MID_DSCDIR(imno,'D',descr,dtype, &bytelem,&noelem,&dunit,&dblock,&dindx); if (status != ERR_NORMAL) goto end_of_it; dtype[0] = 'H'; /* also look for Help descr. */ status = MID_DSCDIR(imno,'F',descr,dtype, &bytelem,&noelem,&dunit,&dblock,&dindx); if (status == ERR_NORMAL) status = MID_DSCDIR(imno,'D',descr,dtype, &bytelem,&noelem,&dunit,&dblock,&dindx); else status = ERR_NORMAL; /* that's not an error */ } } fctpntr->KAUX[2] = 1; /* set descriptor-modified flag */ end_of_it: /* test for info/warnings again */ if (status != ERR_NORMAL) MID_E2(4,imno,descr,status,1); return (status); } /* */ int SCDCOP(from,to,mask,dsc) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Copy descriptors from one frame to another .ALGORITHM Depending on 'mask' the relevant descriptors are read from the source frame + written to the destination frame. .REMARKS mask for copying: = 1 , copy all descriptors = 2 , copy only standard desc. = 3 , copy all but standard descriptors = 4 , copy descriptor specified by DSClist = 5 , copy all but extended list of standard descriptors .RETURNS return status ( 0 = o.k. ) --------------------------------------------------*/ int from; /* IN: no. of source frame */ int to; /* IN: no. of destination frame */ int mask; /* IN: copy_mask */ char *dsc; /* IN: name of descr. to copy (if mask = 4) */ { struct FCT_STRUCT *fctpntri, *fctpntro; struct FCB_STRUCT *fcbp; fctpntri = FCT.ENTRIES + from; if (fctpntri->LINK[0] >= 2) /* use father frame */ { from = fctpntri->LINK[1]; fctpntri = FCT.ENTRIES + from; } fctpntro = FCT.ENTRIES + to; if (fctpntro->LINK[0] >= 2) /* use father frame */ { to = fctpntro->LINK[1]; fctpntro = FCT.ENTRIES + to; } if (from != to) { if (fctpntro->PROT == 2) return ERR_FILPRO; /* destination is write protected */ fcbp = fctpntri->FZP; if (fcbp->DSCFLAG == 'Z') return ZSCDCOP(from,to,mask,dsc); else if (fcbp->DSCFLAG == 'Y') return YSCDCOP(from,to,mask,dsc); else return oldSCDCOP(from,to,mask,dsc); } return ERR_NORMAL; /* nothing to be done ... */ } /* */ int SCDGETC(imno,descr,felem,maxvals,actvals,values) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE get data from character descriptor and terminate with Null (no trailing blanks) .ALGORITHM use SCDRDC .RETURNS return status ( 0 = o.k. ) --------------------------------------------------*/ int imno /* IN : no. of data frame */; char *descr /* IN : descriptor name */; int felem /* IN : position of 1st element to be accessed */; int maxvals /* IN : max. no. of characters to be returned */; int *actvals /* OUT: actual no. of characters returned */; char *values /* OUT: array for descriptor data */; { int status, mynull, myuni; register int nr; register char mychar; mynull = -1; status = SCDRDC(imno,descr,1,felem,maxvals,actvals,values,&myuni,&mynull); if (status == ERR_NORMAL) { /* get rid of trailing blanks/nulls */ maxvals = (*actvals) - 1; for (nr=maxvals; nr>=0; nr--) { mychar = values[nr]; if ((mychar != ' ') && (mychar != '\0')) { *actvals = ++nr; values[nr] = '\0'; /* add null terminator */ return (status); } } } values[0] = '\0'; *actvals = 0; return (status); } /* */ int SCDFND(imno,descr,type,noelem,bytelem) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE provide info about descriptor 'descr' .ALGORITHM use MID_DSCDIR to find descr. + related info .RETURNS return status ( 0 = o.k. ) --------------------------------------------------*/ int imno /* IN: no. of data frame */; char *descr /* IN: descriptor name */; char *type /* OUT: type of descr - I, R, C, D or ' ' on output */; int *noelem /* OUT: no. of elements */; int *bytelem /* OUT: no. of bytes per element */; { int dblock, dindx, snoel, sbytel; int dsclen, dunit, status, e_c, e_l; char realdescr[52]; struct FCB_STRUCT *fcbp; struct FCT_STRUCT *fctpntr; /* disable error abort */ e_c = ERRO_CONT; e_l = ERRO_LOG; ERRO_CONT = 1; ERRO_LOG = 0; /* check imno + type */ if ( (imno < 0) || (imno >= FCT.MAXENT) ) { status = ERR_INPINV; goto end_of_it; } fctpntr = FCT.ENTRIES + imno; if (fctpntr->LINK[0] >= 2) /* use father frame */ { imno = fctpntr->LINK[1]; fctpntr = FCT.ENTRIES + imno; } dsclen = DSCNAM_COPY(realdescr,descr); /* build uppercase name */ *type = ' '; fcbp = fctpntr->FZP; if (fcbp->DSCFLAG == 'Y') { char help[72]; status = MID_YDSCDIR(imno,'F',realdescr,type,&sbytel,&snoel,&dunit, &dblock,&dindx,help); } else if (fcbp->DSCFLAG == 'Z') status = MID_ZDSCDIR(imno,'F',realdescr,dsclen,type,&sbytel,&snoel, &dunit,&dblock,&dindx); else status = MID_DSCDIR(imno,'F',descr,type,&sbytel,&snoel,&dunit, &dblock,&dindx); if (status != ERR_DSCNPR) { *noelem = snoel; *bytelem = sbytel; } ERRO_CONT = e_c; ERRO_LOG = e_l; /* reset error flags */ return ERR_NORMAL; end_of_it: ERRO_CONT = e_c; ERRO_LOG = e_l; /* reset error flags */ MID_E2(7,imno,"SCDFND: ",status,1); return status; } /* */ int SCDINF(imno,npos,fno,buf,lbuf,numbuf) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE provide info about descriptor at position 'npos' .ALGORITHM go through the descriptor directory and provide the desired info .RETURNS return status ( 0 = o.k. ) --------------------------------------------------*/ int imno /* IN : no. of data frame */; int npos /* IN : position of descriptor, beginning with 1 use 0 for the descr. directory itself */; int fno /* IN : specify desired info, 1 = NAME, 2 = TYPE, 3 = SIZE 4 = NAME,TYPE separated by a comma in `buf' and SIZE in `numbuf' 5 = NAME,TYPE separated by a comma in `buf' and SIZE,BYTELEM in `numbuf' 98 = return total no. of descriptors (except Help-d.) 99 = return total no. of descriptors */; char *buf /* IN : buffer for character descriptor info */; int lbuf /* IN : max. length of buffer above */; int *numbuf /* IN : return buffer for numerical data */; { int status, chanl, ext, flag; int dirfirst, dirused, dirsize, dirlen, diroff, totext; int nullo; int snpos; register int nr; static int mapdscdir = -1; char *dscpntr; register char *cpt; static char *dscdir; struct FCT_STRUCT *fctpntr; struct FCB_STRUCT *fcbp; if ( (imno < 0) || (imno >= FCT.MAXENT) ) { status= ERR_INPINV; /* wrong argument `npos' */ goto end_of_it; } snpos = npos + 1; /* real index is at NPOS+1 because of directory */ if ( (snpos < 1) || (fno < 0) ) { status= ERR_INPINV; /* wrong argument `npos' */ goto end_of_it; } status = ERR_NORMAL; fctpntr = FCT.ENTRIES + imno; if (fctpntr->LINK[0] >= 2) /* use father frame */ { imno = fctpntr->LINK[1]; fctpntr = FCT.ENTRIES + imno; } chanl = fctpntr->IOCHAN; fcbp = fctpntr->FZP; if (fcbp->DSCFLAG == 'Y') /* new descriptor format? */ return YSCDINF(chanl,imno,snpos,fno,buf,lbuf,numbuf); else if (fcbp->DSCFLAG == 'Z') /* new descriptor format? */ return ZSCDINF(chanl,imno,snpos,fno,buf,lbuf,numbuf); dirused = fcbp->DFILLED; dirsize = fcbp->DSIZE; totext = dirsize/fcbp->DIREXT; /* total extensions for directory */ dscpntr = (char *) &DSCDIR_ENTRY.NAME[0]; ext = 1; npos = 0; diroff = 0; flag = 0; pos_loop: dirfirst = diroff + 1; dirlen = dirused - diroff; if (fcbp->DIREXT < dirlen) dirlen = fcbp->DIREXT; /* read max. 1500 chars. */ if (mapdscdir < 0) /* allocate working buffer */ { /* for descr. directory */ dscdir = malloc((unsigned int) dirlen); mapdscdir = 1; } if (fno > 90) { nullo = -1; (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nullo); cpt = dscdir; for (nr=0; nrDIRENTRY) /* take chunks of 30 ch. */ { if (*cpt != ' ') { if (fno == 99) npos ++; else { if (*(cpt+15) != 'H') npos ++; } } cpt += fcbp->DIRENTRY; } /* maybe we need another segment (next extension) of descr. directory */ if (ext < totext) { ext ++ ; /* prepare reading of next directory segment */ diroff += fcbp->DIREXT; goto pos_loop; /* and loop more... */ } *numbuf = --npos; /* remove descriptor directory itself */ return (ERR_NORMAL); } /* here for all the other functions */ nullo = -1; (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nullo); cpt = dscdir; for (nr=0; nrDIRENTRY) /* take chunks of 30 chars. */ { if ((*cpt != ' ') && (*(cpt+15) != 'H')) { if (++npos == snpos) /* always increment `npos' */ { flag = 1; CGN_COPYALL(dscpntr,cpt,fcbp->DIRENTRY); goto descr_found; } } cpt += fcbp->DIRENTRY; } /* we need another segment (next extension) of descr. directory */ if (ext < totext) { ext ++ ; /* prepare reading of next directory segment */ diroff += fcbp->DIREXT; goto pos_loop; /* and loop more... */ } descr_found: if (snpos == 1) /* process DIRECTORY.MIDAS */ DSCDIR_ENTRY.NOELEM = (unsigned short int) dirused; /* s.i => uns. s.i */ switch(fno) { case 1: MID_NAMINFO(flag,DSC_PNTR->NAME,buf,lbuf); break; case 2: MID_TYPINFO(flag,DSC_PNTR->TYPE,DSC_PNTR->BYTELEM,buf,lbuf); break; case 3: *numbuf = DSC_PNTR->NOELEM; break; case 4: MID_NAMINFO(flag,DSC_PNTR->NAME,buf,lbuf); if (lbuf > 15) /* old descr. length = 15 */ { buf[15] = ','; lbuf -= 16; MID_TYPINFO(flag,DSC_PNTR->TYPE,DSC_PNTR->BYTELEM,buf+16,lbuf); } break; default: /* case 5 */ MID_NAMINFO(flag,DSC_PNTR->NAME,buf,lbuf); if (lbuf > 15) { buf[15] = ','; lbuf -= 16; MID_TYPINFO(flag,DSC_PNTR->TYPE,DSC_PNTR->BYTELEM,buf+16,lbuf); } *numbuf++ = DSC_PNTR->NOELEM; *numbuf = DSC_PNTR->BYTELEM; } return status; end_of_it: MID_E2(7,imno,"SCDINF: ",status,1); return status; } /* */ int XSCDINF(chanl,imno,snpos,fno,buf,lbuf,numbuf) int chanl; int imno; int snpos; int fno; char *buf; int lbuf; int *numbuf; { struct FCT_STRUCT *fctpntr; struct FCB_STRUCT *fcbp; fctpntr = FCT.ENTRIES + imno; if (fctpntr->LINK[0] >= 2) /* use father frame */ { imno = fctpntr->LINK[1]; fctpntr = FCT.ENTRIES + imno; } chanl = fctpntr->IOCHAN; fcbp = fctpntr->FZP; if (fcbp->DSCFLAG == 'Y') /* new descriptor format */ return YSCDINF(chanl,imno,snpos,fno,buf,lbuf,numbuf); else /* old descriptor format? */ return ZSCDINF(chanl,imno,snpos,fno,buf,lbuf,numbuf); } /* */ int ZSCDINF(chanl,imno,snpos,fno,buf,lbuf,numbuf) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE provide info about descriptor at position 'npos' .ALGORITHM go through the descriptor directory and provide the desired info .RETURNS return always 0 (checks already done in SCDINF) --------------------------------------------------*/ int chanl; /* IN: I/O chanl of frame */ int imno /* IN: no. of data frame */; int snpos /* IN: incremented position of descriptor */; int fno /* IN: specify desired info, 1 = NAME, 2 = TYPE, 3 = SIZE 4 = NAME,TYPE separated by a comma in `buf' 5 = NAME,TYPE separated by a comma in `buf' and SIZE,BYTELEM in `numbuf' 99 = return total no. of descriptors */; char *buf /* IN: buffer for character descriptor info */; int lbuf /* IN: max. length of buffer above */; int *numbuf /* IN: return buffer for numerical data */; { int flag, ext; int dirfirst, dirused, dirsize, dirlen, diroff, totext; int nullo; int mm, dirbytes, npos; register int nr; char *dscpntr; register char *cpt; struct FCT_STRUCT *fctpntr; struct FCB_STRUCT *fcbp; static int mapdscdir = -1; static char *dscdir; fctpntr = FCT.ENTRIES + imno; fcbp = fctpntr->FZP; dirused = fcbp->DFILLED; dirsize = fcbp->DSIZE; totext = dirsize/fcbp->DIREXT; /* total no. of extensions for directory */ dscpntr = (char *) &ZDSCDIR_ENTRY; ext = 1; npos = 0; diroff = 0; flag = 0; pos_loop: dirfirst = diroff + 1; dirlen = dirused - diroff; if (fcbp->DIREXT < dirlen) dirlen = fcbp->DIREXT; /* read max. 1500 chars. */ if (mapdscdir < 0) /* allocate working buffer */ { /* for descr. directory */ dscdir = malloc((unsigned int)fcbp->DIREXT); /* = 1500 */ mapdscdir = 1; } if (fno > 90) { nullo = -1; (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nullo); cpt = dscdir; nr = 0; while (nr < dirlen) { if (*cpt == '3') mm = 3; else if (*cpt == '2') mm = 2; else mm = 1; dirbytes = mm * fcbp->DIRENTRY; if (*(cpt+1) != '_') npos ++; /* test if just fill_in block */ cpt += dirbytes; nr += dirbytes; } /* maybe we need another segment (next extension) of descr. directory */ if (ext < totext) { ext ++ ; /* prepare reading of next directory segment */ diroff += fcbp->DIREXT; if (diroff < dirused) goto pos_loop; /* and loop more... */ } *numbuf = --npos; /* remove descriptor directory itself */ return (ERR_NORMAL); } /* here for all the other functions */ nullo = -1; (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nullo); cpt = dscdir; nr = 0; while (nr < dirlen) { if (*cpt == '3') mm = 3; else if (*cpt == '2') mm = 2; else mm = 1; dirbytes = mm * fcbp->DIRENTRY; if (*(cpt+1) != '_') /* test if just fill_in block */ { if (++npos == snpos) /* always increment `npos' */ { CGN_COPYALL(dscpntr,cpt,dirbytes); flag = 1; goto descr_found; } } cpt += dirbytes; nr += dirbytes; } /* we need another segment (next extension) of descr. directory */ if (ext < totext) { ext ++ ; /* prepare reading of next directory segment */ diroff += fcbp->DIREXT; goto pos_loop; /* and loop more... */ } descr_found: switch(fno) { case 1: if (flag == 0) /* npos too large */ CGN_FILL(buf,' ',lbuf); else { mm = (int) strlen(ZDSC_PNTR->NAME); if (mm > lbuf) (void) strncpy(buf,ZDSC_PNTR->NAME,lbuf); else (void) strcpy(buf,ZDSC_PNTR->NAME); } break; case 2: (void) MID_TYPINFO(flag,ZDSC_PNTR->TYPE,ZDSC_PNTR->BYTELEM,buf,lbuf); break; case 3: if (flag == 0) /* npos too large */ *numbuf = 0; else { if (snpos == 1) *numbuf = dirused; else *numbuf = ZDSC_PNTR->NOELEM; } break; case 4: if (flag == 0) /* npos too large */ CGN_FILL(buf,' ',lbuf); else { mm = (int) strlen(ZDSC_PNTR->NAME); if (mm > lbuf) (void) strncpy(buf,ZDSC_PNTR->NAME,lbuf); else { (void) strcpy(buf,ZDSC_PNTR->NAME); lbuf -= mm; if (lbuf > 1) { buf[mm] = ','; lbuf --; (void) MID_TYPINFO(flag,ZDSC_PNTR->TYPE,ZDSC_PNTR->BYTELEM, buf+mm+1,lbuf); } } } break; default: /* case 5 */ if (flag == 0) /* npos too large */ CGN_FILL(buf,' ',lbuf); else { mm = (int) strlen(ZDSC_PNTR->NAME); if (mm > lbuf) (void) strncpy(buf,ZDSC_PNTR->NAME,lbuf); else { (void) strcpy(buf,ZDSC_PNTR->NAME); lbuf -= mm; if (lbuf > 1) { buf[mm] = ','; lbuf --; (void) MID_TYPINFO(flag,ZDSC_PNTR->TYPE,ZDSC_PNTR->BYTELEM, buf+mm+1,lbuf); } if (snpos == 1) *numbuf++ = dirused; else *numbuf++ = ZDSC_PNTR->NOELEM; *numbuf = ZDSC_PNTR->BYTELEM; } } } return ERR_NORMAL; } /* */ int YSCDINF(chanl,imno,snpos,fno,buf,lbuf,numbuf) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE provide info about descriptor at position 'npos' .ALGORITHM go through the descriptor directory and provide the desired info .RETURNS return always 0 (checks already done in SCDINF) --------------------------------------------------*/ int chanl; /* IN: I/O chanl of frame */ int imno /* IN: no. of data frame */; int snpos /* IN: incremented position of descriptor */; int fno /* IN: specify desired info, 1 = NAME, 2 = TYPE, 3 = SIZE 4 = NAME,TYPE separated by a comma in `buf' 5 = NAME,TYPE separated by a comma in `buf' and SIZE,BYTELEM in `numbuf' 99 = return total no. of descriptors */; char *buf /* IN: buffer for character descriptor info */; int lbuf /* IN: max. length of buffer above */; int *numbuf /* IN: return buffer for numerical data */; { int flag, ext; int dirfirst, dirused, dirsize, dirlen, diroff, totext; int nullo; int mm, npos; register int nr, direntry; char *dscpntr; register char *cpt; struct FCT_STRUCT *fctpntr; struct FCB_STRUCT *fcbp; static int mapdscdir = -1; static char *dscdir; fctpntr = FCT.ENTRIES + imno; fcbp = fctpntr->FZP; dirused = fcbp->DFILLED; dirsize = fcbp->DSIZE; totext = dirsize/fcbp->DIREXT; /* total no. of extensions for directory */ dscpntr = (char *) &YDSCDIR_ENTRY; direntry = fcbp->DIRENTRY; ext = 1; npos = 0; diroff = 0; flag = 0; pos_loop: dirfirst = diroff + 1; dirlen = dirused - diroff; if (fcbp->DIREXT < dirlen) dirlen = fcbp->DIREXT; /* read max. 2500 chars. */ if (mapdscdir < 0) /* allocate working buffer */ { /* for descr. directory */ dscdir = (char *)malloc((unsigned int)fcbp->DIREXT); /* = 2500 */ mapdscdir = 1; } if (fno > 90) { nullo = -1; (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nullo); cpt = dscdir; nr = 0; while (nr < dirlen) { if (*cpt != '\0') npos ++; /* test if entry is used */ cpt += direntry; nr += direntry; } /* maybe we need another segment (next extension) of descr. directory */ if (ext < totext) { ext ++ ; /* prepare reading of next directory segment */ diroff += fcbp->DIREXT; if (diroff < dirused) goto pos_loop; /* and loop more... */ } *numbuf = --npos; /* remove descriptor directory itself */ return (ERR_NORMAL); } /* here for all the other functions */ nullo = -1; (void) MID_RDSCRC(chanl,fcbp->PTRLDB,0,dirfirst,dirlen,dscdir,&nullo); cpt = dscdir; nr = 0; while (nr < dirlen) { if (*cpt != '\0') /* test if entry is used */ { if (++npos == snpos) /* always increment `npos' */ { (void) memcpy(dscpntr,cpt,(size_t)fcbp->DIRENTRY); flag = 1; goto descr_found; } } cpt += direntry; nr += direntry; } /* we need another segment (next extension) of descr. directory */ if (ext < totext) { ext ++ ; /* prepare reading of next directory segment */ diroff += fcbp->DIREXT; if (diroff < dirused) goto pos_loop; /* and loop more... */ } descr_found: switch(fno) { case 1: if (flag == 0) /* npos too large */ CGN_FILL(buf,' ',lbuf); else { mm = YDSC_PNTR->NAMELEN; if (mm > lbuf) mm = lbuf; (void) memcpy(buf,YDSC_PNTR->NAMESTR,(size_t)mm); } break; case 2: (void) MID_TYPINFO(flag,YDSC_PNTR->TYPE,YDSC_PNTR->BYTELEM,buf,lbuf); break; case 3: if (flag == 0) /* npos too large */ *numbuf = 0; else { if (snpos == 1) *numbuf = dirused; else *numbuf = YDSC_PNTR->NOELEM; } break; case 4: if (flag == 0) /* npos too large */ CGN_FILL(buf,' ',lbuf); else { mm = YDSC_PNTR->NAMELEN; if (mm >= lbuf) (void) memcpy(buf,YDSC_PNTR->NAMESTR,(size_t)lbuf); else { (void) memcpy(buf,YDSC_PNTR->NAMESTR,(size_t)(mm+1)); lbuf -= mm; if (lbuf > 1) { buf[mm] = ','; lbuf --; (void) MID_TYPINFO(flag,YDSC_PNTR->TYPE,YDSC_PNTR->BYTELEM, buf+mm+1,lbuf); } } } break; default: /* case 5 */ if (flag == 0) /* npos too large */ CGN_FILL(buf,' ',lbuf); else { mm = YDSC_PNTR->NAMELEN; if (mm >= lbuf) (void) memcpy(buf,YDSC_PNTR->NAMESTR,(size_t)lbuf); else { (void) memcpy(buf,YDSC_PNTR->NAMESTR,(size_t)(mm+1)); lbuf -= mm; if (lbuf > 1) { buf[mm] = ','; lbuf --; (void) MID_TYPINFO(flag,YDSC_PNTR->TYPE,YDSC_PNTR->BYTELEM, buf+mm+1,lbuf); } if (snpos == 1) *numbuf++ = dirused; else *numbuf++ = YDSC_PNTR->NOELEM; *numbuf = YDSC_PNTR->BYTELEM; } } } return (ERR_NORMAL); }