void GPUERT::deviceHandler(){ m_devId = m_gfxMgr->createDeviceContext(m_devId); calculateMaxNodes(m_devId); initResources(); m_constantsBagging.cb_baggingActivated = false; TimerPtr timerKernel = TimerPtr(new boost::timer); TimerPtr timer = TimerPtr(new boost::timer); TimerPtr timerTotal = TimerPtr(new boost::timer); m_internalNodes = 0, m_leafNodes = 0; int treesLeft = m_numTrees; int treesToLaunch = m_maxTreesPerIteration; int lastLaunch = 0; int checkSum = m_maxTreesPerIteration; int newNodes = m_maxTreesPerIteration; std::vector<int> checkVars(4,0); m_buildTime = 0; m_baggingTime = 0; m_classificationTime = 0; m_depth = 0; timerTotal->restart(); int numIter = ceil(float(m_numTrees)/float(m_maxTreesPerIteration)); for(unsigned int j=0; j<numIter; ++j){ checkSum = treesToLaunch; newNodes = treesToLaunch; m_constants.cb_nodeBufferStart = 0; m_constants.cb_nodeIdFlip = 0; initResourceBatch(lastLaunch == treesToLaunch); lastLaunch = treesToLaunch; treesLeft -= treesToLaunch; timer->restart(); for(unsigned int i=0; i<m_MaxDepth; ++i){ if(i > m_depth) m_depth = i; assert(newNodes < m_maxNodesPerIteration); int nodeLimit = 10000; int innerNodes = newNodes; int numInnerIter = ceil(float(innerNodes)/float(nodeLimit)); int launchCount = 0; m_constants.cb_availableNodes = newNodes; m_constants.cb_numFeatures = 0; timerKernel->restart(); for(unsigned int k=0; k<m_numFeatures; ++k){ innerNodes = newNodes; numInnerIter = ceil(float(innerNodes)/float(nodeLimit)); launchCount = 0; // Best split kernel m_gfxMgr->setGPUBuffer(m_devId,m_setBufferIdsExFindSplit,m_setResourceTypesExFindSplit); m_gfxMgr->setGPUProgram(m_devId,m_gpuFunctionIds["RFP_ExFindSplit"]); innerNodes = newNodes; launchCount = 0; m_constants.cb_currentDepth = 0; for(unsigned int l=0; l<numInnerIter; ++l){ launchCount = innerNodes > nodeLimit ? nodeLimit : innerNodes; m_gfxMgr->copyToGPU(m_devId,m_bufferIds["RFB_constants"],&ConstantUpdate(&m_constants,KID_ExtremeFindSplit),sizeof(m_constants)); m_gfxMgr->launchComputation(m_devId,launchCount*thread_group_size,1,1); m_constants.cb_currentDepth += launchCount; innerNodes -= launchCount; if(innerNodes <= 0) break; } ++m_constants.cb_numFeatures; } if(m_kernelSpecificTimings){ m_gfxMgr->syncDevice(m_devId); m_kernelTimes[L"RFP_ExFindSplit"] += timerKernel->elapsed(); } innerNodes = newNodes; launchCount = 0; m_constants.cb_currentDepth = 0; m_gfxMgr->setGPUBuffer(m_devId,m_setBufferIdsExMakeSplit,m_setResourceTypesExMakeSplit); m_gfxMgr->setGPUProgram(m_devId,m_gpuFunctionIds["RFP_ExMakeSplit"]); // Split data timerKernel->restart(); for(unsigned int k=0; k<numInnerIter; ++k){ launchCount = innerNodes > nodeLimit ? nodeLimit : innerNodes; m_gfxMgr->copyToGPU(m_devId,m_bufferIds["RFB_constants"],&ConstantUpdate(&m_constants,KID_ExtremeMakeSplit),sizeof(m_constants)); m_gfxMgr->launchComputation(m_devId,launchCount*thread_group_size,1,1); m_constants.cb_currentDepth += launchCount; innerNodes -= launchCount; if(innerNodes <= 0) break; } if(m_kernelSpecificTimings){ m_gfxMgr->syncDevice(m_devId); m_kernelTimes[L"RFP_ExMakeSplit"] += timerKernel->elapsed(); } // Swap buffer to avoid unecessary copying int tmpBuffId = m_bufferIds["RFB_nodeIndices"]; m_bufferIds["RFB_nodeIndices"] = m_bufferIds["RFB_nodeIndicesMirror"]; m_bufferIds["RFB_nodeIndicesMirror"] = tmpBuffId; setBufferSettings(); m_constants.cb_currentDepth = i; // Evaluate splits timerKernel->restart(); m_gfxMgr->setGPUBuffer(m_devId,m_setBufferIdsExCreateNodes,m_setResourceTypesExCreateNodes); m_gfxMgr->copyToGPU(m_devId,m_bufferIds["RFB_constants"],&ConstantUpdate(&m_constants,KID_ExtremeCreateNodes),sizeof(m_constants)); m_gfxMgr->setGPUProgram(m_devId,m_gpuFunctionIds["RFP_ExCreateNodes"]); m_gfxMgr->launchComputation(m_devId,newNodes,1,1); // Get continuation variables m_gfxMgr->copyFromGPU(m_devId,m_bufferIds["RFB_checkVariables"],&checkVars[0],checkVars.size()*sizeof(int)); if(m_kernelSpecificTimings){ m_gfxMgr->syncDevice(m_devId); m_kernelTimes[L"RFP_ExCreateNd"] += timerKernel->elapsed(); } m_constants.cb_nodeBufferStart = checkSum; checkSum = checkVars[2]; m_leafNodes += checkVars[3]; newNodes = checkSum; m_internalNodes += checkSum; checkVars[1] = 0; checkVars[2] = 0; checkVars[3] = 0; m_gfxMgr->copyToGPU(m_devId,m_bufferIds["RFB_checkVariables"],&checkVars[0],checkVars.size()*sizeof(int)); m_constants.cb_nodeIdFlip = (m_constants.cb_nodeIdFlip == 0) ? 1 : 0; if(newNodes <= 0) break; } m_buildTime += timer->elapsed(); // Vote on test instances timer->restart(); runClassificationProcess(treesToLaunch); m_classificationTime += timer->elapsed(); if(m_saveModel) getResultsFromGPU(); m_data->m_gui->setProgressBar(IDC_PROGRESSBAR_PROGRESS,100,(float(m_numTrees-treesLeft)/float(m_numTrees))*100); if(treesLeft != 0 && treesLeft < m_maxTreesPerIteration){ treesToLaunch = treesLeft; m_maxTreesPerIteration = treesToLaunch; } } getVotesFromGPU(); m_totalTime = timerTotal->elapsed(); m_bar->wait(); }
SEXP fmelt(SEXP DT, SEXP id, SEXP measure, SEXP varfactor, SEXP valfactor, SEXP var_name, SEXP val_name, SEXP na_rm, SEXP drop_levels, SEXP print_out) { int i, j, k, nrow, ncol, protecti=0, lids=-1, lvalues=-1, totlen=0, counter=0, thislen=0; SEXP thiscol, ans, dtnames, ansnames, idcols, valuecols, levels, factorLangSxp; SEXP vars, target, idxkeep = R_NilValue, thisidx = R_NilValue; Rboolean isfactor=FALSE, isidentical=TRUE, narm = FALSE, droplevels=FALSE, verbose=FALSE; SEXPTYPE valtype=NILSXP; size_t size; if (TYPEOF(DT) != VECSXP) error("Input is not of type VECSXP, expected a data.table, data.frame or list"); if (TYPEOF(valfactor) != LGLSXP) error("Argument 'value.factor' should be logical TRUE/FALSE"); if (TYPEOF(varfactor) != LGLSXP) error("Argument 'variable.factor' should be logical TRUE/FALSE"); if (TYPEOF(na_rm) != LGLSXP) error("Argument 'na.rm' should be logical TRUE/FALSE"); if (LOGICAL(na_rm)[0] == TRUE) narm = TRUE; if (TYPEOF(print_out) != LGLSXP) error("Argument 'verbose' should be logical TRUE/FALSE"); if (LOGICAL(print_out)[0] == TRUE) verbose = TRUE; // check for var and val names if (TYPEOF(var_name) != STRSXP || length(var_name) != 1) error("Argument 'variable.name' must be a character vector of length 1"); if (TYPEOF(val_name) != STRSXP || length(val_name) != 1) error("Argument 'value.name' must be a character vector of length 1"); // droplevels future feature request, maybe... should ask on data.table-help // if (!isLogical(drop_levels)) error("Argument 'drop.levels' should be logical TRUE/FALSE"); // if (LOGICAL(drop_levels)[0] == TRUE) droplevels = TRUE; // if (droplevels && !narm) warning("Ignoring argument 'drop.levels'. 'drop.levels' should be set to remove any unused levels as a result of setting 'na.rm=TRUE'. Here there is nothing to do because 'na.rm=FALSE'"); ncol = LENGTH(DT); nrow = length(VECTOR_ELT(DT, 0)); if (ncol <= 0) { warning("ncol(data) is 0. Nothing to do, returning original data.table."); return(DT); } PROTECT(dtnames = getAttrib(DT, R_NamesSymbol)); protecti++; if (isNull(dtnames)) error("names(data) is NULL. Please report to data.table-help"); vars = checkVars(DT, id, measure, verbose); PROTECT(idcols = VECTOR_ELT(vars, 0)); protecti++; PROTECT(valuecols = VECTOR_ELT(vars, 1)); protecti++; // <~~~ not protecting vars leads to segfault (on big data) lids = length(idcols); lvalues = length(valuecols); // edgecase where lvalues = 0 and lids > 0 if (lvalues == 0 && lids > 0) { if (verbose) Rprintf("length(measure.var) is 0. Edge case detected. Nothing to melt. Returning data.table with all 'id.vars' which are columns %s\n", CHAR(STRING_ELT(concat(dtnames, idcols), 0))); PROTECT(ansnames = allocVector(STRSXP, lids)); protecti++; PROTECT(ans = allocVector(VECSXP, lids)); protecti++; for (i=0; i<lids; i++) { SET_VECTOR_ELT(ans, i, VECTOR_ELT(DT, INTEGER(idcols)[i]-1)); SET_STRING_ELT(ansnames, i, STRING_ELT(dtnames, INTEGER(idcols)[i]-1)); } setAttrib(ans, R_NamesSymbol, ansnames); UNPROTECT(protecti); return(ans); } if (lvalues == 0 && lids == 0 && verbose) Rprintf("length(measure.var) and length(id.var) are both 0. Edge case detected. Nothing to melt.\n"); // <~~ don't think this will ever happen though with all the checks // set names for 'ans' - the output list PROTECT(ansnames = allocVector(STRSXP, lids+2)); protecti++; for (i=0; i<lids; i++) { SET_STRING_ELT(ansnames, i, STRING_ELT(dtnames, INTEGER(idcols)[i]-1)); } SET_STRING_ELT(ansnames, lids, mkChar(CHAR(STRING_ELT(var_name, 0)))); // mkChar("variable") SET_STRING_ELT(ansnames, lids+1, mkChar(CHAR(STRING_ELT(val_name, 0)))); // mkChar("value") // get "value" column for (i=0; i<lvalues; i++) { thiscol = VECTOR_ELT(DT, INTEGER(valuecols)[i]-1); if (!isfactor && isFactor(thiscol)) isfactor = TRUE; if (TYPEOF(thiscol) > valtype) valtype = TYPEOF(thiscol); } if (isfactor && valtype != VECSXP) valtype = STRSXP; for (i=0; i<lvalues; i++) { thiscol = VECTOR_ELT(DT, INTEGER(valuecols)[i]-1); if (TYPEOF(thiscol) != valtype && isidentical) { if (!(isFactor(thiscol) && valtype == STRSXP)) { isidentical = FALSE; // for Date like column (not implemented for now) warning("All 'measure.vars are NOT of the SAME type. By order of hierarchy, the molten data value column will be of type '%s'. Therefore all measure variables that are not of type '%s' will be coerced to. Check the DETAILS section of ?melt.data.table for more on coercion.\n", type2char(valtype), type2char(valtype)); break; } } } if (valtype == VECSXP && narm) { narm = FALSE; if (verbose) Rprintf("The molten data value type is a list. 'na.rm=TRUE' is therefore ignored.\n"); } if (narm) { PROTECT(idxkeep = allocVector(VECSXP, lvalues)); protecti++; for (i=0; i<lvalues; i++) { SET_VECTOR_ELT(idxkeep, i, which_notNA(VECTOR_ELT(DT, INTEGER(valuecols)[i]-1))); totlen += length(VECTOR_ELT(idxkeep, i)); } } else totlen = nrow * lvalues; PROTECT(ans = allocVector(VECSXP, lids + 2)); protecti++; target = PROTECT(allocVector(valtype, totlen)); for (i=0; i<lvalues; i++) { thiscol = VECTOR_ELT(DT, INTEGER(valuecols)[i]-1); if (isFactor(thiscol)) thiscol = asCharacterFactor(thiscol); if (TYPEOF(thiscol) != valtype && !isFactor(thiscol)) { // thiscol = valtype == STRSXP ? PROTECT(coerce_to_char(thiscol, R_GlobalEnv)) : PROTECT(coerceVector(thiscol, valtype)); // protecti++; // for now, no preserving of class attributes thiscol = PROTECT(coerceVector(thiscol, valtype)); protecti++; } size = SIZEOF(thiscol); if (narm) { thisidx = VECTOR_ELT(idxkeep, i); thislen = length(thisidx); } switch(valtype) { case VECSXP : if (narm) { for (j=0; j<thislen; j++) SET_VECTOR_ELT(target, counter + j, VECTOR_ELT(thiscol, INTEGER(thisidx)[j]-1)); } else { for (j=0; j<nrow; j++) SET_VECTOR_ELT(target, i*nrow + j, VECTOR_ELT(thiscol, j)); } break; case STRSXP : if (narm) { for (j=0; j<thislen; j++) SET_STRING_ELT(target, counter + j, STRING_ELT(thiscol, INTEGER(thisidx)[j]-1)); } else { for (j=0; j<nrow; j++) SET_STRING_ELT(target, i*nrow + j, STRING_ELT(thiscol, j)); } break; case REALSXP : if (narm) { for (j=0; j<thislen; j++) REAL(target)[counter + j] = REAL(thiscol)[INTEGER(thisidx)[j]-1]; } else { memcpy((char *)DATAPTR(target)+i*nrow*size, (char *)DATAPTR(thiscol), nrow*size); } break; case INTSXP : if (narm) { for (j=0; j<thislen; j++) INTEGER(target)[counter + j] = INTEGER(thiscol)[INTEGER(thisidx)[j]-1]; } else { memcpy((char *)DATAPTR(target)+i*nrow*size, (char *)DATAPTR(thiscol), nrow*size); } break; case LGLSXP : if (narm) { for (j=0; j<thislen; j++) LOGICAL(target)[counter + j] = LOGICAL(thiscol)[INTEGER(thisidx)[j]-1]; } else { memcpy((char *)DATAPTR(target)+i*nrow*size, (char *)DATAPTR(thiscol), nrow*size); } break; default : error("Unknown column type '%s' for column '%s' in 'data'", type2char(TYPEOF(thiscol)), CHAR(STRING_ELT(dtnames, INTEGER(valuecols)[i]-1))); } if (narm) counter += thislen; // if (isidentical && valtype != VECSXP) // for now, no preserving of class attributes // setAttrib(target, R_ClassSymbol, getAttrib(VECTOR_ELT(DT, INTEGER(valuecols)[0]-1), R_ClassSymbol)); // for Date like column } // check for factor if (LOGICAL(valfactor)[0] == TRUE && valtype == VECSXP) warning("argument 'value.factor' ignored because 'value' column is a list\n"); if (LOGICAL(valfactor)[0] == TRUE && valtype != VECSXP) { PROTECT(factorLangSxp = allocList(2)); SET_TYPEOF(factorLangSxp, LANGSXP); SETCAR(factorLangSxp, install("factor")); SETCAR(CDR(factorLangSxp), target); SET_VECTOR_ELT(ans, lids+1, eval(factorLangSxp, R_GlobalEnv)); // last column UNPROTECT(1); // factorLangSxp } else SET_VECTOR_ELT(ans, lids+1, target); UNPROTECT(1); // target // get "variable" column counter = 0, i=0; target = PROTECT(allocVector(INTSXP, totlen)); for (j=0; j<lvalues; j++) { if (narm) { thislen = length(VECTOR_ELT(idxkeep, j)); for (k=0; k<thislen; k++) INTEGER(target)[counter + k] = i+1; counter += thislen; if (thislen > 0 || !droplevels) i++; } else { for (k=0; k<nrow; k++) INTEGER(target)[nrow*j + k] = j+1; } } setAttrib(target, R_ClassSymbol, mkString("factor")); if (narm && droplevels) { counter = 0; for (j=0; j<lvalues; j++) { if (length(VECTOR_ELT(idxkeep, j)) > 0) counter++; } } else counter = lvalues; levels = PROTECT(allocVector(STRSXP, counter)); i = 0; for (j=0; j<lvalues; j++) { if (narm && droplevels) { if (length(VECTOR_ELT(idxkeep, j)) > 0) SET_STRING_ELT(levels, i++, STRING_ELT(dtnames, INTEGER(valuecols)[j]-1)); } else SET_STRING_ELT(levels, j, STRING_ELT(dtnames, INTEGER(valuecols)[j]-1)); } setAttrib(target, R_LevelsSymbol, levels); UNPROTECT(1); // levels if (LOGICAL(varfactor)[0] == FALSE) target = asCharacterFactor(target); SET_VECTOR_ELT(ans, lids, target); UNPROTECT(1); // target // generate idcols (left part) for (i=0; i<lids; i++) { counter = 0; thiscol = VECTOR_ELT(DT, INTEGER(idcols)[i]-1); size = SIZEOF(thiscol); target = PROTECT(allocVector(TYPEOF(thiscol), totlen)); switch(TYPEOF(thiscol)) { case REALSXP : if (narm) { for (j=0; j<lvalues; j++) { thisidx = PROTECT(VECTOR_ELT(idxkeep, j)); thislen = length(thisidx); for (k=0; k<thislen; k++) REAL(target)[counter + k] = REAL(thiscol)[INTEGER(thisidx)[k]-1]; counter += thislen; UNPROTECT(1); // thisidx } } else { for (j=0; j<lvalues; j++) memcpy((char *)DATAPTR(target)+j*nrow*size, (char *)DATAPTR(thiscol), nrow*size); } break; case INTSXP : if (narm) { for (j=0; j<lvalues; j++) { thisidx = PROTECT(VECTOR_ELT(idxkeep, j)); thislen = length(thisidx); for (k=0; k<thislen; k++) INTEGER(target)[counter + k] = INTEGER(thiscol)[INTEGER(thisidx)[k]-1]; counter += thislen; UNPROTECT(1); // thisidx } } else { for (j=0; j<lvalues; j++) memcpy((char *)DATAPTR(target)+j*nrow*size, (char *)DATAPTR(thiscol), nrow*size); } break; case LGLSXP : if (narm) { for (j=0; j<lvalues; j++) { thisidx = PROTECT(VECTOR_ELT(idxkeep, j)); thislen = length(thisidx); for (k=0; k<thislen; k++) LOGICAL(target)[counter + k] = LOGICAL(thiscol)[INTEGER(thisidx)[k]-1]; counter += thislen; UNPROTECT(1); // thisidx } } else { for (j=0; j<lvalues; j++) memcpy((char *)DATAPTR(target)+j*nrow*size, (char *)DATAPTR(thiscol), nrow*size); } break; case STRSXP : if (narm) { for (j=0; j<lvalues; j++) { thisidx = PROTECT(VECTOR_ELT(idxkeep, j)); thislen = length(thisidx); for (k=0; k<thislen; k++) SET_STRING_ELT(target, counter + k, STRING_ELT(thiscol, INTEGER(thisidx)[k]-1)); counter += thislen; UNPROTECT(1); // thisidx } } else { // SET_STRING_ELT for j=0 and memcpy for j>0, WHY? // From assign.c's memcrecycle - only one SET_STRING_ELT per RHS item is needed to set generations (overhead) for (k=0; k<nrow; k++) SET_STRING_ELT(target, k, STRING_ELT(thiscol, k)); for (j=1; j<lvalues; j++) memcpy((char *)DATAPTR(target)+j*nrow*size, (char *)DATAPTR(target), nrow*size); } break; case VECSXP : for (j=0; j<lvalues; j++) { for (k=0; k<nrow; k++) { SET_VECTOR_ELT(target, j*nrow + k, VECTOR_ELT(thiscol, k)); } } break; default : error("Unknown column type '%s' for column '%s' in 'data'", type2char(TYPEOF(thiscol)), CHAR(STRING_ELT(dtnames, INTEGER(idcols)[i]-1))); } copyMostAttrib(thiscol, target); // all but names,dim and dimnames. And if so, we want a copy here, not keepattr's SET_ATTRIB. SET_VECTOR_ELT(ans, i, target); UNPROTECT(1); // target } setAttrib(ans, R_NamesSymbol, ansnames); UNPROTECT(protecti); return(ans); }
int main(int argc, char* argv[]) { int sock; //Socket descriptor struct sockaddr_in servAddr; //Echo server address char* lineBuffer; //String to send to server char* tempBuffer; //Temporary Buffer for Storage char recvBuffer[RCVBUFSIZE]; int bytesRcvd, totalBytesRcvd; //Bytes read in single recv & total FILE* in; //MEClient.txt, if passed FILE* out; //MEClient.log, logfile of correspondance struct hostent* he; //Used to get IP information from hostname int usrAuth = -1; char* token; int i, doneSig; if (argc < 2) { //Test for correct number of arguments fprintf(stderr,"Usage: %s <Server Machine Name> [MEClient.txt]\n", argv[0]); exit(1); } if (argc == 3) //If file is passed in in = fopen(argv[2], "r"); //Create a file descriptor for the input file else in = stdin; //Otherwise, use Standard In out = fopen("MEClient.log", "w"); //Open log file if (in == NULL) DieWithError("Error Opening File for Reading"); //Construct the Server Address Structure memset(&servAddr, 0, sizeof(servAddr)); //Zero out structure if((he = gethostbyname(argv[1])) == NULL) DieWithError("Error resolving Server IP"); memcpy(&servAddr.sin_addr, he->h_addr_list[0], he->h_length); //Set address servAddr.sin_family = AF_INET; //Family servAddr.sin_port = htons(1100); //Well-Known Port lineBuffer = (char*) malloc(LINEBUFSIZE); tempBuffer = (char*) malloc(LINEBUFSIZE); token = (char*) malloc(LINEBUFSIZE); while(1) { //Run forever; quit function will eventually end the program fgets(lineBuffer, LINEBUFSIZE, in); //Gets line from MEClient.txt fprintf(out, lineBuffer); //Write command to log file strncpy(tempBuffer, lineBuffer, LINEBUFSIZE); token = strtok(tempBuffer, " "); //Login Command if(strncasecmp(token, "login", 5)==0) { token = strtok(NULL, " "); //Token is user's name //Log in user, and set authorization level if(strncmp(token, "FEMA", 4)==0 || strncmp(token, "Query", 5)==0) { if(usrAuth != -1) puts("ERROR: User already logged in"); else{ //Create a reliable, stream socket using TCP if ((sock = socket(AF_INET, SOCK_STREAM, 0))<0) DieWithError("socket() failed"); //Establish a connection to the ME Server if (connect(sock, (struct sockaddr*)&servAddr, sizeof(servAddr))<0) DieWithError("connect() failed"); //Return 1 for FEMA, 0 for Query usrAuth = ((strncmp(token, "FEMA", 4)==0) ? 1 : 0); if (send(sock, lineBuffer, RCVBUFSIZE, 0)!= RCVBUFSIZE) DieWithError("send() sent a different nuber of bytes than expected"); bytesRcvd = 0; totalBytesRcvd = 0; while (totalBytesRcvd < RCVBUFSIZE) { //Receive up to the buffer size if ((bytesRcvd = recv(sock, recvBuffer, RCVBUFSIZE, 0))<=0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; //Keep tally of total bytes } printf(recvBuffer); //Print server's response fprintf(out, recvBuffer); //Write to log file } } else puts("ERROR: Invalid login name"); } //Add / Update Command else if ((strncasecmp(token, "add", 3)==0 || strncasecmp(token, "update", 6)==0) && usrAuth==1) { strcpy(tempBuffer, lineBuffer); if (checkVars(tempBuffer, 5)) { if (send(sock, lineBuffer, RCVBUFSIZE, 0)!= RCVBUFSIZE) DieWithError("send() sent a different nuber of bytes than expected"); bytesRcvd = 0; totalBytesRcvd = 0; while (totalBytesRcvd < RCVBUFSIZE) { //Receive up to the buffer size if ((bytesRcvd = recv(sock, recvBuffer, RCVBUFSIZE, 0))<=0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; //Keep tally of total bytes } printf(recvBuffer); //Print server's response fprintf(out, recvBuffer); //Write to log file } else puts("ERROR: Wrong number of variables."); } //Remove Command else if (strncasecmp(token, "remove", 6)==0 && usrAuth==1) { if (send(sock, lineBuffer, RCVBUFSIZE, 0)!= RCVBUFSIZE) DieWithError("send() sent a different nuber of bytes than expected"); bytesRcvd = 0; totalBytesRcvd = 0; while (totalBytesRcvd < RCVBUFSIZE) { //Receive up to the buffer size if ((bytesRcvd = recv(sock, recvBuffer, RCVBUFSIZE, 0))<=0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; //Keep tally of total bytes } printf(recvBuffer); //Print server's response fprintf(out, recvBuffer); //Write to log file } //Find / List / Locate Command else if ((strncasecmp(token, "find", 4)==0 || strncasecmp(token, "list", 4)==0 || strncasecmp(token, "locate", 6)==0) && usrAuth!=-1) { strcpy(tempBuffer, lineBuffer); if(strncasecmp(token, "locate", 6)==0 && checkTooMany(tempBuffer, 2)==1) { puts("ERROR: Wrong number of variables."); fprintf(out, "ERROR: Wrong number of variables.\n"); continue; } if (send(sock, lineBuffer, RCVBUFSIZE, 0)!= RCVBUFSIZE) DieWithError("send() sent a different nuber of bytes than expected"); doneSig = 1; while(doneSig) { bytesRcvd = 0; totalBytesRcvd = 0; while (totalBytesRcvd < RCVBUFSIZE) { //Receive up to the buffer size if ((bytesRcvd = recv(sock, recvBuffer, RCVBUFSIZE, 0))<=0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; //Keep tally of total bytes } if(strcasecmp(recvBuffer, "S: Search Complete.") == 0) doneSig = 0; //Done Receiving else { printf(recvBuffer); //Print server's response fprintf(out, recvBuffer); //Write to log file } } } //Quit Command else if (strncasecmp(token, "quit", 4)==0 && usrAuth!=-1) { token = strtok(NULL, " "); //Token is EOF marker (if passed) usrAuth = -1; //Reset authentication level if (send(sock, lineBuffer, RCVBUFSIZE, 0)!= RCVBUFSIZE) DieWithError("send() sent a different nuber of bytes than expected"); for(i=0; i<3; i++) { //Receive and print two messages from the server bytesRcvd = 0; totalBytesRcvd = 0; while (totalBytesRcvd < RCVBUFSIZE) { //Receive up to the buffer size if ((bytesRcvd = recv(sock, recvBuffer, RCVBUFSIZE, 0))<=0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; //Keep tally of total bytes } printf(recvBuffer); fprintf(out, recvBuffer); //Write to log file } if (token != NULL && strncmp(token, "EOF", 3)==0) { for(i=0; i<2; i++) { //Receive and print two messages from the server bytesRcvd = 0; totalBytesRcvd = 0; while (totalBytesRcvd < RCVBUFSIZE) { //Receive up to the buffer size if ((bytesRcvd = recv(sock, recvBuffer, RCVBUFSIZE, 0))<=0) DieWithError("recv() failed or connection closed prematurely"); totalBytesRcvd += bytesRcvd; //Keep tally of total bytes } printf(recvBuffer); fprintf(out, recvBuffer); //Write to log file } close(sock); fclose(in); fclose(out); exit(0); //If EOF string passed, we're done } else close(sock); } else { //User either entered a bad command, or they puts("ERROR: Bad Command");//had the wrong authentication level fprintf(out, "ERROR: Bad Command\n"); } } }