static void readList (char *line) { // recursively expand; loops are detected if (*line == '@') { // line+1 is a list file name FILE *f = hlr_fopenRead (line+1); int linebuflen; char *fline = NULL; if (strstr (string (fileNames),line+1)) die ("loop in @file including at file %s",line+1); stringCat (fileNames,line+1); stringCat (fileNames,"\001"); // a char not contained in any file name while (getLine (f,&fline,&linebuflen)) { stripNlGetLength (fline); readList (fline); } hlr_free (fline); fclose (f); } else { Seqspec seqspec; if (!seqspec_isCommentLine (line) && (seqspec = seqspec_parseLine (line)) != NULL) { array (seqspecs,arrayMax (seqspecs),Seqspec) = seqspec_clone (seqspec); seqCnt++; } } }
string AES128CTR(string in, string key, string nonce){ string cipher=newString(NULL, in.len); string keystream; string counter=newString(NULL,8); int i,j,n; n=numBlocks(in,16); if (nonce.len!=8){ nonce=newString(NULL,8); } j=0; for(i=0; i<n; i++){ keystream=AES128EncodeBlock(stringCat(nonce, counter), key); do{ if(j<in.len){ cipher.c[j]=keystream.c[j%16] ^ in.c[j]; j++; } else break; }while(j%16); littleEndianIncrement(&counter); } return cipher; }
string AES128DecodeCBC(string in, string key, string IV){ if(in.len%16){ return NULLSTRING; } string out = NULLSTRING; string *blocks = blockString(in, 16); int num = numBlocks(in, 16); for(int i=num-1; i>=0; i--){ blocks[i] = AES128DecodeBlock(blocks[i],key); if(i==0){ out = stringCat(stringXOR(blocks[i], IV), out); } else{ out = stringCat(stringXOR(blocks[i-1], blocks[i]),out); } } return out; }
int main() { char string1 [] = "hello"; char string2 [] = "world"; printf ("This is the concatenation of string1 and string2: "); stringCat(string1, string2); int comparison = stringCmp(string1, string2); printf ("This is the comparison of string1 and string2: %d\n", comparison); }
string AES128DecodeECB(string in, string key){ if(in.len%16){ return NULLSTRING; } string out = NULLSTRING; for(int i=0; i<in.len; i+=16){ out = stringCat(out, AES128DecodeBlock(newString(&in.c[i],16),key)); } return out; }
string AES128EncodeECB(string in, string key){ if(key.len!=16) return NULLSTRING; if(!validatePKCS7Padding(in)){ in = PKCS7PadString(in, 16); } string out = NULLSTRING; for(int i=0; i<in.len; i+=16){ out = stringCat(out, AES128EncodeBlock(newString(&in.c[i],16),key)); } return out; }
int seqspec_split2continous (Seqspec this1) { /** If 'this1' sequence segment is of the form 'db:seq_n begin:b end:e' it is transformed into 'db:seq begin:b1 end:e1' where b1=b+n*100000, e1=e+n*100000 which means the GCG type split is removed @param[in] this1 - the Seqspec object @param[out] this1 - the Seqspec object possibly modified @return 1 if 'this1' changed, else 0 */ static char *seqname = NULL; static Stringa dbseqname = NULL; int nameLen; char *cp; int offset; int segnum; stringCreateClear (dbseqname,40); strReplace (&seqname,this1->seqname); nameLen = strlen (seqname); if (nameLen < 3) return 0; if ((cp = strrchr(seqname, '_')) == NULL) return 0; if (*(cp+1) == '\0' || strlen (cp+1) > 2) return 0; segnum = atoi (cp+1); *cp = 0; offset = segnum * FRAGMENT_LENGTH; this1->begin += offset; if (this1->end != 0) this1->end += offset; stringCpy (dbseqname,this1->dbname); stringCat (dbseqname,":"); stringCat (dbseqname,seqname); seqspec_IDset (this1,string (dbseqname)); return 1; }
string AES128EncodeCBC(string in, string key, string IV){ string out = NULLSTRING; if(!validatePKCS7Padding(in)){ in = PKCS7PadString(in, 16); } string *blocks = blockString(in, 16); int num = numBlocks(in, 16); for(int i=0; i<num; i++){ if(i==0){ blocks[0] = stringXOR(blocks[0], IV); }else{ blocks[i] = stringXOR(blocks[i], newString(&out.c[(i-1)*16],16)); } out = stringCat(out, AES128EncodeBlock(blocks[i], key)); } return out; }
static void como_execute(ComoFrame *frame, ComoFrame *callingframe) { size_t i; for(i = 0; i < O_AVAL(frame->code)->size; i++) { ComoOpCode *opcode = ((ComoOpCode *)(O_PTVAL(O_AVAL(frame->code)->table[i]))); switch(opcode->op_code) { default: { como_error_noreturn("Invalid OpCode got %d", opcode->op_code); } case POSTFIX_INC: { Object *value = NULL; value = mapSearchEx(frame->cf_symtab, O_SVAL(opcode->operand)->value); if(value == NULL) { como_error_noreturn("undefined variable '%s'", O_SVAL(opcode->operand)->value); } else { if(O_TYPE(value) != IS_LONG) { como_error_noreturn("unsupported value for POSTFIX_INC"); } else { long oldvalue = O_LVAL(value); O_LVAL(value) = oldvalue + 1; push(frame, newLong(oldvalue)); } } break; } case POSTFIX_DEC: { Object *value = NULL; value = mapSearchEx(frame->cf_symtab, O_SVAL(opcode->operand)->value); if(value == NULL) { como_error_noreturn("undefined variable '%s'", O_SVAL(opcode->operand)->value); } else { if(O_TYPE(value) != IS_LONG) { como_error_noreturn("unsupported value for POSTFIX_DEC"); } else { long oldvalue = O_LVAL(value); O_LVAL(value) = oldvalue - 1; push(frame, newLong(oldvalue)); } } break; } case IS_LESS_THAN: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(objectValueIsLessThan(left, right)) { push(frame, newLong(1L)); } else { push(frame, newLong(0L)); } break; } case IADD: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(O_TYPE(left) == IS_LONG && O_TYPE(right) == IS_LONG) { long value = O_LVAL(left) + O_LVAL(right); push(frame, newLong(value)); } else { char *left_str = objectToString(left); char *right_str = objectToString(right); Object *s1 = newString(left_str); Object *s2 = newString(right_str); Object *value = stringCat(s1, s2); push(frame, value); objectDestroy(s1); objectDestroy(s2); free(left_str); free(right_str); } break; } case IMINUS: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(O_TYPE(left) != IS_LONG && O_TYPE(right) != IS_LONG) { como_error_noreturn("unsupported value for IMINUS"); } else { push(frame, newLong(O_LVAL(left) - O_LVAL(right))); } break; } case IS_LESS_THAN_OR_EQUAL: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(objectValueCompare(left, right) || objectValueIsLessThan(left, right)) { push(frame, newLong(1L)); } else { push(frame, newLong(0L)); } break; } case JZ: { Object *cond = pop(frame); if(O_TYPE(cond) == IS_LONG && O_LVAL(cond) == 0) { i = (size_t)O_LVAL(opcode->operand); continue; } break; } case JMP: { i = O_LVAL(opcode->operand); continue; } case LABEL: { break; } case HALT: { break; } case IS_NOT_EQUAL: { Object *right = pop(frame); Object *left = pop(frame); if(!objectValueCompare(left, right)) { push(frame, newLong(1L)); } else { push(frame, newLong(0L)); } break; } case LOAD_CONST: { como_debug("LOAD_CONST"); push(frame, opcode->operand); break; } case STORE_NAME: { Object *value = pop(frame); mapInsertEx(frame->cf_symtab, O_SVAL(opcode->operand)->value, value); break; } /* This is where recursion was broken, don't do *ex */ case LOAD_NAME: { Object *value = NULL; value = mapSearch(frame->cf_symtab, O_SVAL(opcode->operand)->value); if(value) { goto load_name_leave; } else { value = mapSearch(global_frame->cf_symtab, O_SVAL(opcode->operand)->value); } if(value == NULL) { como_error_noreturn("undefined variable '%s'", O_SVAL(opcode->operand)->value); } load_name_leave: push(frame, value); break; } case CALL_FUNCTION: { Object *fn = pop(frame); Object *argcount = pop(frame); long i = O_LVAL(argcount); ComoFrame *fnframe; if(O_TYPE(fn) != IS_POINTER) { como_error_noreturn("name '%s' is not callable", O_SVAL(opcode->operand)->value); } fnframe = (ComoFrame *)O_PTVAL(fn); if(O_LVAL(argcount) != (long)(O_AVAL(fnframe->namedparameters)->size)) { como_error_noreturn("callable '%s' expects %ld arguments, but %ld were given", O_SVAL(opcode->operand)->value, (long)(O_AVAL(fnframe->namedparameters)->size), O_LVAL(argcount)); } //como_debug("calling '%s'", O_SVAL(opcode->operand)->value); // DOING THIS ACTUALLY DEFINES THE NAME AT RUNTIME // which could not be equal to that actual function body // declared // name = my_function // name() // that call will have "name" for value __FUNCTION__ // even though the real function is my_function // must define it at COMPILE time // mapInsertEx(fnframe->cf_symtab, "__FUNCTION__", // newString(O_SVAL(opcode->operand)->value)); while(i--) { como_debug("getting %ldth argument for function call '%s'", i, O_SVAL(opcode->operand)->value); Object *argname = O_AVAL(fnframe->namedparameters)->table[i]; Object *argvalue = pop(frame); mapInsert(fnframe->cf_symtab, O_SVAL(argname)->value, argvalue); char *argvaluestr = objectToString(argvalue); como_debug("%ldth argument: '%s' has value: %s", i, O_SVAL(argname)->value, argvaluestr); free(argvaluestr); } //ComoFrame *prev = frame; //fnframe->next = prev; como_execute(fnframe, NULL); push(frame, pop(fnframe)); //fnframe->next = NULL; break; } case IS_EQUAL: { Object *right = pop(frame); Object *left = pop(frame); push(frame, newLong((long)objectValueCompare(left, right))); break; } case ITIMES: { Object *right = pop(frame); Object *left = pop(frame); assert(right); assert(left); if(O_TYPE(right) != IS_LONG && O_TYPE(left) != IS_LONG) { como_error_noreturn("invalid operands for ITIMES"); } como_debug("ITIMES: %d, %d", O_TYPE(left), O_TYPE(right)); long value = O_LVAL(left) * O_LVAL(right); push(frame, newLong(value)); break; } case IRETURN: { /* If there wasn't a return statement found in func body* * The compiler will insert a 1 as the operand if * the AST had an expression for the return statement, * otherwise, it will be 0 * The actual value to be returned is popped from the stack */ if(! (O_LVAL(opcode->operand))) { push(frame, newLong(0L)); } return; } case IPRINT: { Object *value = pop(frame); size_t len = 0; char *sval = objectToStringLength(value, &len); fprintf(stdout, "%s\n", sval); fflush(stdout); free(sval); break; } } } }
int main (int argc, char *argv[]) { Array intervals; Interval *currInterval; SubInterval *currSubInterval; int h,i,j; Array seqs; Seq *currSeq,testSeq; int index; Stringa buffer; Array geneTranscriptEntries; Texta geneTranscriptIds; Array alterations; Alteration *currAlteration,*nextAlteration; char *proteinSequenceBeforeIndel; char *proteinSequenceAfterIndel; int numDisabledTranscripts; Stringa disabledTranscripts; int seqLength,refLength,altLength; char *sequenceBeforeIndel = NULL; int overlapMode; int numOverlaps; int sizeIndel,indelOffset; int overlap; Array coordinates; VcfEntry *currVcfEntry; VcfGenotype *currVcfGenotype; int position; Texta alternateAlleles; int flag1,flag2; if (argc != 3) { usage ("%s <annotation.interval> <annotation.fa>",argv[0]); } intervalFind_addIntervalsToSearchSpace (argv[1],0); geneTranscriptEntries = util_getGeneTranscriptEntries (intervalFind_getAllIntervals ()); seq_init (); fasta_initFromFile (argv[2]); seqs = fasta_readAllSequences (0); fasta_deInit (); arraySort (seqs,(ARRAYORDERF)util_sortSequencesByName); buffer = stringCreate (100); disabledTranscripts = stringCreate (100); alterations = arrayCreate (100,Alteration); vcf_init ("-"); stringPrintf (buffer,"##INFO=<ID=VA,Number=.,Type=String,Description=\"Variant Annotation, %s\">",argv[1]); vcf_addComment (string (buffer)); puts (vcf_writeMetaData ()); puts (vcf_writeColumnHeaders ()); while (currVcfEntry = vcf_nextEntry ()) { if (vcf_isInvalidEntry (currVcfEntry)) { continue; } flag1 = 0; flag2 = 0; position = currVcfEntry->position - 1; // make zero-based alternateAlleles = vcf_getAlternateAlleles (currVcfEntry); for (h = 0; h < arrayMax (alternateAlleles); h++) { refLength = strlen (currVcfEntry->referenceAllele); altLength = strlen (textItem (alternateAlleles,h)); sizeIndel = abs (refLength - altLength); indelOffset = MAX (refLength,altLength) - 1; util_clearAlterations (alterations); intervals = intervalFind_getOverlappingIntervals (currVcfEntry->chromosome,position,position + indelOffset); for (i = 0; i < arrayMax (intervals); i++) { currInterval = arru (intervals,i,Interval*); overlapMode = OVERLAP_NONE; numOverlaps = 0; for (j = 0; j < arrayMax (currInterval->subIntervals); j++) { currSubInterval = arrp (currInterval->subIntervals,j,SubInterval); overlap = rangeIntersection (position,position + indelOffset,currSubInterval->start,currSubInterval->end); if (currSubInterval->start <= position && (position + indelOffset) < currSubInterval->end) { overlapMode = OVERLAP_FULLY_CONTAINED; numOverlaps++; } else if (j == 0 && overlap > 0 && position < currSubInterval->start) { overlapMode = OVERLAP_START; numOverlaps++; } else if (j == (arrayMax (currInterval->subIntervals) - 1) && overlap > 0 && (position + indelOffset) >= currSubInterval->end) { overlapMode = OVERLAP_END; numOverlaps++; } else if (overlap > 0 && overlap <= indelOffset) { overlapMode = OVERLAP_SPLICE; numOverlaps++; } } if (overlapMode == OVERLAP_NONE) { continue; } currAlteration = arrayp (alterations,arrayMax (alterations),Alteration); if (numOverlaps > 1) { util_addAlteration (currAlteration,currInterval->name,"multiExonHit",currInterval,position,0); continue; } else if (numOverlaps == 1 && overlapMode == OVERLAP_SPLICE) { util_addAlteration (currAlteration,currInterval->name,"spliceOverlap",currInterval,position,0); continue; } else if (numOverlaps == 1 && overlapMode == OVERLAP_START) { util_addAlteration (currAlteration,currInterval->name,"startOverlap",currInterval,position,0); continue; } else if (numOverlaps == 1 && overlapMode == OVERLAP_END) { util_addAlteration (currAlteration,currInterval->name,"endOverlap",currInterval,position,0); continue; } else if (numOverlaps == 1 && overlapMode == OVERLAP_FULLY_CONTAINED && altLength > refLength) { if ((sizeIndel % 3) == 0) { util_addAlteration (currAlteration,currInterval->name,"insertionNFS",currInterval,position,0); } else { util_addAlteration (currAlteration,currInterval->name,"insertionFS",currInterval,position,0); } } else if (numOverlaps == 1 && overlapMode == OVERLAP_FULLY_CONTAINED && altLength < refLength) { if ((sizeIndel % 3) == 0) { util_addAlteration (currAlteration,currInterval->name,"deletionNFS",currInterval,position,0); } else { util_addAlteration (currAlteration,currInterval->name,"deletionFS",currInterval,position,0); } } else if (numOverlaps == 1 && overlapMode == OVERLAP_FULLY_CONTAINED && altLength == refLength) { util_addAlteration (currAlteration,currInterval->name,"substitution",currInterval,position,0); } else { die ("Unexpected type: %d %s %s %s", currVcfEntry->position,currVcfEntry->chromosome, currVcfEntry->referenceAllele,currVcfEntry->alternateAllele); } if ((sizeIndel % 3) != 0 && altLength != refLength) { continue; } // Only run the remaining block of code if the indel is fully contained (insertion or deletion) AND does not cause a frameshift OR // if it is a substitution that is fully contained in the coding sequence stringPrintf (buffer,"%s|%s|%c|",currInterval->name,currInterval->chromosome,currInterval->strand); for (j = 0; j < arrayMax (currInterval->subIntervals); j++) { currSubInterval = arrp (currInterval->subIntervals,j,SubInterval); stringAppendf (buffer,"%d|%d%s",currSubInterval->start,currSubInterval->end,j < arrayMax (currInterval->subIntervals) - 1 ? "|" : ""); } testSeq.name = hlr_strdup (string (buffer)); if (!arrayFind (seqs,&testSeq,&index,(ARRAYORDERF)util_sortSequencesByName)) { die ("Expected to find %s in seqs",string (buffer)); } hlr_free (testSeq.name); currSeq = arrp (seqs,index,Seq); strReplace (&sequenceBeforeIndel,currSeq->sequence); seqLength = strlen (sequenceBeforeIndel); coordinates = util_getCoordinates (currInterval); // arraySort (coordinates,(ARRAYORDERF)util_sortCoordinatesByChromosomeAndTranscriptPosition); Array is already sorted by definition j = 0; stringClear (buffer); while (j < seqLength) { if (util_getGenomicCoordinate (coordinates,j,currVcfEntry->chromosome) == position) { if (altLength > refLength) { stringCat (buffer,textItem (alternateAlleles,h)); j++; continue; } else if (altLength < refLength) { stringCatChar (buffer,sequenceBeforeIndel[j]); j = j + refLength - altLength + 1; continue; } else { stringCat (buffer,textItem (alternateAlleles,h)); j = j + altLength; continue; } } stringCatChar (buffer,sequenceBeforeIndel[j]); j++; } util_destroyCoordinates (coordinates); proteinSequenceBeforeIndel = hlr_strdup (util_translate (currInterval,sequenceBeforeIndel)); proteinSequenceAfterIndel = hlr_strdup (util_translate (currInterval,string (buffer))); addSubstitution (currAlteration,proteinSequenceBeforeIndel,proteinSequenceAfterIndel,indelOffset); hlr_free (proteinSequenceBeforeIndel); hlr_free (proteinSequenceAfterIndel); } if (arrayMax (alterations) == 0) { continue; } arraySort (alterations,(ARRAYORDERF)util_sortAlterationsByGeneIdAndType); stringClear (buffer); i = 0; while (i < arrayMax (alterations)) { currAlteration = arrp (alterations,i,Alteration); stringAppendf (buffer,"%s%d:%s:%s:%c:%s",stringLen (buffer) == 0 ? "" : ",",h + 1,currAlteration->geneName,currAlteration->geneId,currAlteration->strand,currAlteration->type); stringClear (disabledTranscripts); if (currAlteration->substitution[0] != '\0') { stringAppendf (disabledTranscripts,"%s:%s:%d_%d_%s",currAlteration->transcriptName,currAlteration->transcriptId,currAlteration->transcriptLength,currAlteration->relativePosition,currAlteration->substitution); } else if (strEqual (currAlteration->type,"multiExonHit") || strEqual (currAlteration->type,"spliceOverlap") || strEqual (currAlteration->type,"startOverlap") || strEqual (currAlteration->type,"endOverlap")) { stringAppendf (disabledTranscripts,"%s:%s:%d",currAlteration->transcriptName,currAlteration->transcriptId,currAlteration->transcriptLength); } else { stringAppendf (disabledTranscripts,"%s:%s:%d_%d",currAlteration->transcriptName,currAlteration->transcriptId,currAlteration->transcriptLength,currAlteration->relativePosition); } numDisabledTranscripts = 1; j = i + 1; while (j < arrayMax (alterations)) { nextAlteration = arrp (alterations,j,Alteration); if (strEqual (currAlteration->geneId,nextAlteration->geneId) && strEqual (currAlteration->type,nextAlteration->type)) { if (nextAlteration->substitution[0] != '\0') { stringAppendf (disabledTranscripts,":%s:%s:%d_%d_%s",nextAlteration->transcriptName,nextAlteration->transcriptId,nextAlteration->transcriptLength,nextAlteration->relativePosition,nextAlteration->substitution); } else if (strEqual (nextAlteration->type,"multiExonHit") || strEqual (nextAlteration->type,"spliceOverlap") || strEqual (nextAlteration->type,"startOverlap") || strEqual (nextAlteration->type,"endOverlap")) { stringAppendf (disabledTranscripts,":%s:%s:%d",nextAlteration->transcriptName,nextAlteration->transcriptId,nextAlteration->transcriptLength); } else { stringAppendf (disabledTranscripts,":%s:%s:%d_%d",nextAlteration->transcriptName,nextAlteration->transcriptId,nextAlteration->transcriptLength,nextAlteration->relativePosition); } numDisabledTranscripts++; } else { break; } j++; } i = j; geneTranscriptIds = util_getTranscriptIdsForGeneId (geneTranscriptEntries,currAlteration->geneId); stringAppendf (buffer,":%d/%d:%s",numDisabledTranscripts,arrayMax (geneTranscriptIds),string (disabledTranscripts)); } if (flag1 == 0) { printf ("%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s;VA=", currVcfEntry->chromosome,currVcfEntry->position,currVcfEntry->id, currVcfEntry->referenceAllele,currVcfEntry->alternateAllele, currVcfEntry->quality,currVcfEntry->filter,currVcfEntry->info); flag1 = 1; } printf ("%s%s",flag2 == 1 ? "," : "",string (buffer)); flag2 = 1; } if (flag1 == 1) { for (i = 0; i < arrayMax (currVcfEntry->genotypes); i++) { currVcfGenotype = arrp (currVcfEntry->genotypes,i,VcfGenotype); if (i == 0) { printf ("\t%s\t",currVcfEntry->genotypeFormat); } printf ("%s%s%s%s",currVcfGenotype->genotype, currVcfGenotype->details[0] != '\0' ? ":" : "", currVcfGenotype->details[0] != '\0' ? currVcfGenotype->details : "", i < arrayMax (currVcfEntry->genotypes) - 1 ? "\t" : ""); } puts (""); } } vcf_deInit (); return 0; }
/* * opendir * * Returns a pointer to a DIR structure appropriately filled in to begin * searching a directory. */ DIR * opendir (const char_t *szPath) { DIR *nd; char_t szFullPath[CL_MAX_DIR]; errno = 0; if (!szPath) { errno = EFAULT; return NULL; } if (szPath[0] == '\0') { errno = ENOTDIR; return NULL; } /* Attempt to determine if the given path really is a directory. */ struct Struct_Stat rcs; if ( Cmd_Stat(szPath,&rcs) == -1) { /* call GetLastError for more error info */ errno = ENOENT; return NULL; } if (!(rcs.st_mode & _S_IFDIR)) { /* Error, entry exists but not a directory. */ errno = ENOTDIR; return NULL; } /* Make an absolute pathname. */ fileFullName (szFullPath, szPath, CL_MAX_DIR); /* Allocate enough space to store DIR structure and the complete * directory path given. */ //nd = (DIR *) malloc (sizeof (DIR) + stringLength (szFullPath) + stringLength (DIRENT_SLASH) + // stringLength (DIRENT_SEARCH_SUFFIX)+1); nd = new DIR; if (!nd) { /* Error, out of memory. */ errno = ENOMEM; return NULL; } /* Create the search expression. */ stringCopy (nd->dd_name, szFullPath); /* Add on a slash if the path does not end with one. */ if (nd->dd_name[0] != '\0' && nd->dd_name[stringLength (nd->dd_name) - 1] != '/' && nd->dd_name[stringLength (nd->dd_name) - 1] != '\\') { stringCat (nd->dd_name, DIRENT_SLASH); } /* Add on the search pattern */ stringCat (nd->dd_name, DIRENT_SEARCH_SUFFIX); /* Initialize handle to -1 so that a premature closedir doesn't try * to call _findclose on it. */ nd->dd_handle = -1; /* Initialize the status. */ nd->dd_stat = 0; /* Initialize the dirent structure. ino and reclen are invalid under * Win32, and name simply points at the appropriate part of the * findfirst_t structure. */ //nd->dd_dir.d_ino = 0; //nd->dd_dir.d_reclen = 0; nd->dd_dir.d_namlen = 0; nd->dd_dir.d_name = nd->dd_dta.name; return nd; }
/* * readdir * * Return a pointer to a dirent structure filled with the information on the * next entry in the directory. */ struct dirent * readdir (DIR * dirp) { errno = 0; /* Check for valid DIR struct. */ if (!dirp) { errno = EFAULT; return NULL; } if (dirp->dd_dir.d_name != dirp->dd_dta.name) { /* The structure does not seem to be set up correctly. */ errno = EINVAL; return NULL; } if (dirp->dd_stat < 0) { /* We have already returned all files in the directory * (or the structure has an invalid dd_stat). */ return NULL; } else if (dirp->dd_stat == 0) { /* We haven't started the search yet. */ /* Start the search */ dirp->dd_handle = CmdFindFirst (dirp->dd_name, &(dirp->dd_dta)); if (dirp->dd_handle == -1) { /* Whoops! Seems there are no files in that * directory. */ dirp->dd_stat = -1; } else { dirp->dd_stat = 1; } } else { /* Get the next search entry. */ if (CmdFindNext (dirp->dd_handle, &(dirp->dd_dta))) { /* We are off the end or otherwise error. */ _findclose (dirp->dd_handle); dirp->dd_handle = -1; dirp->dd_stat = -1; } else { /* Update the status to indicate the correct * number. */ dirp->dd_stat++; } } if (dirp->dd_stat > 0) { /* Successfully got an entry. Everything about the file is * already appropriately filled in except the length of the * file name. */ dirp->dd_dir.d_namlen = stringLength (dirp->dd_dir.d_name); if ( dirp->dd_dir.d_name[0] == '.' && (dirp->dd_dir.d_name[1] == 0 || (dirp->dd_dir.d_name[1] == '.' && dirp->dd_dir.d_name[2] == 0))) return readdir(dirp); struct _stat buf; char_t buffer[CL_MAX_DIR]; int bl = stringLength(dirp->dd_name)-stringLength(DIRENT_SEARCH_SUFFIX); stringNCopy(buffer,dirp->dd_name,bl); buffer[bl]=0; stringCat(buffer, dirp->dd_dir.d_name); if ( Cmd_Stat(buffer,&buf) == -1 ) return readdir(dirp); return &dirp->dd_dir; } return NULL; }