static void VerifyAndCleanup(void) { PRUintn i; PRInt32 nRead, rv; for (i=0; i<TBSIZE; i++) tbuf[i] = 0; rv = PR_Seek(t2,0,PR_SEEK_SET); PR_ASSERT(rv == 0); nRead = PR_Read((PRFileDesc*)t2, tbuf, TBSIZE); PR_ASSERT(nRead == TBSIZE); for (i=0; i<TBSIZE; i++) if (tbuf[i] != (PRUint8)i) { if (debug_mode) printf("data mismatch for index= %d \n", i); else failed_already=1; } PR_Close(t1); PR_Close(t2); PR_Delete("t1.tmp"); PR_Delete("t2.tmp"); if (debug_mode) printf("fileio test passed\n"); }
std::string CommandEventHandler::rm(std::string path) { if (PR_Delete(path.c_str()) == PR_SUCCESS) return std::string("removing file" + path); return agentWarn("error: could not delete " + path); }
// Returns true if the contents of |file| match |contents|. static PRBool CheckFileContents(nsILocalFile *file, const char *contents) { nsCString nativePath; file->GetNativePath(nativePath); // Now read in the file contents and compare to the expected output PRFileInfo info; ASSERT_TRUE_RET(PR_GetFileInfo(nativePath.get(), &info) == PR_SUCCESS, PR_FALSE); char *buf = new char[info.size + 1]; ASSERT_TRUE_RET(buf, PR_FALSE); PRFileDesc *fd = PR_Open(nativePath.get(), PR_RDONLY, 0); ASSERT_TRUE_RET(fd, PR_FALSE); ASSERT_TRUE_RET(PR_Read(fd, buf, info.size) == info.size, PR_FALSE); PR_Close(fd); buf[info.size] = '\0'; // Leave the file in place if the test failed ASSERT_TRUE_RET(!strcmp(buf, contents), PR_FALSE); PR_Delete(nativePath.get()); delete[] buf; return PR_TRUE; }
void db_put_dn(char *data_dn) { int ret; char *db_path = DATABASE; char *db_path_bak = DATABASE_BACK; PRFileInfo64 info; PRFileDesc *prfd; PRInt32 data_sz; char *data_dnp = NULL; if(db_lock == NULL){ db_lock = PR_NewLock(); } PR_Lock(db_lock); /* if db_path is a directory, rename it */ ret = PR_GetFileInfo64(db_path, &info); if (PR_SUCCESS == ret) { if (PR_FILE_DIRECTORY == info.type) { /* directory */ ret = PR_GetFileInfo64(db_path_bak, &info); if (PR_SUCCESS == ret) { if (PR_FILE_DIRECTORY != info.type) { /* not a directory */ PR_Delete(db_path_bak); } } PR_Rename(db_path, db_path_bak); } } /* open a file */ if ((prfd = PR_Open(db_path, PR_RDWR | PR_CREATE_FILE | PR_APPEND, 0600)) == NULL ) { slapi_log_error(SLAPI_LOG_FATAL, DB_PLUGIN_NAME, "db: Could not open file \"%s\" for read/write; %d (%s)\n", db_path, PR_GetError(), slapd_pr_strerror(PR_GetError())); return; } data_dnp = slapi_ch_smprintf("%s\n", data_dn); data_sz = (PRInt32)strlen(data_dnp); ret = PR_Write(prfd, data_dnp, data_sz); if (ret == data_sz) { slapi_log_error(SLAPI_LOG_PLUGIN, DB_PLUGIN_NAME, "db: %s: key stored.\n", data_dn); ret = 0; } else { slapi_log_error(SLAPI_LOG_FATAL, DB_PLUGIN_NAME, "db: Failed to store key \"%s\"; %d (%s)\n", data_dn, PR_GetError(), slapd_pr_strerror(PR_GetError())); ret = 1; } if(ret) { slapi_log_error(SLAPI_LOG_FATAL, DB_PLUGIN_NAME, "db: Error detected in db_put_dn \n"); } slapi_ch_free_string(&data_dnp); PR_Close(prfd); PR_Unlock(db_lock); return; }
/* mkdir -p */ int mkdir_p(char *dir, unsigned int mode) { PRFileInfo info; int rval; char sep = get_sep(dir); rval = PR_GetFileInfo(dir, &info); if (PR_SUCCESS == rval) { if (PR_FILE_DIRECTORY != info.type) /* not a directory */ { PR_Delete(dir); if (PR_SUCCESS != PR_MkDir(dir, mode)) { LDAPDebug(LDAP_DEBUG_ANY, "mkdir_p %s: error %d (%s)\n", dir, PR_GetError(),slapd_pr_strerror(PR_GetError())); return -1; } } return 0; } else { /* does not exist */ char *p, *e; char c[2] = {0, 0}; int len = strlen(dir); rval = 0; e = dir + len - 1; if (*e == sep) { c[1] = *e; *e = '\0'; } c[0] = '/'; p = strrchr(dir, sep); if (NULL != p) { *p = '\0'; rval = mkdir_p(dir, mode); *p = c[0]; } if (c[1]) *e = c[1]; if (0 != rval) return rval; if (PR_SUCCESS != PR_MkDir(dir, mode)) { LDAPDebug(LDAP_DEBUG_ANY, "mkdir_p %s: error %d (%s)\n", dir, PR_GetError(),slapd_pr_strerror(PR_GetError())); return -1; } return 0; } }
int main(int argc, char **argv) { PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "dh"); PRFileDesc* fd; PRErrorCode err; /* parse command line options */ while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug mode */ debug_mode = PR_TRUE; break; case 'h': default: Help(); return 2; } } PL_DestroyOptState(opt); lm = PR_NewLogModule( "testcase" ); (void) PR_MkDir( DIRNAME, 0777); fd = PR_Open( DIRNAME FILENAME, PR_CREATE_FILE|PR_RDWR, 0666); if (fd == 0) { PRErrorCode err = PR_GetError(); fprintf(stderr, "create file fails: %d: %s\n", err, PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); failed_already = PR_TRUE; goto Finished; } PR_Close(fd); if (PR_RmDir( DIRNAME ) == PR_SUCCESS) { fprintf(stderr, "remove directory succeeds\n"); failed_already = PR_TRUE; goto Finished; } err = PR_GetError(); fprintf(stderr, "remove directory fails with: %d: %s\n", err, PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); (void) PR_Delete( DIRNAME FILENAME); (void) PR_RmDir( DIRNAME ); return 0; Finished: if ( debug_mode ) printf("%s\n", ( failed_already ) ? "FAILED" : "PASS" ); return( (failed_already)? 1 : 0 ); } /* --- end main() */
/* * delete the given file/directory and its sub files/directories */ int ldbm_delete_dirs(char *path) { PRDir *dirhandle = NULL; PRDirEntry *direntry = NULL; char fullpath[MAXPATHLEN]; int rval = 0; PRFileInfo info; dirhandle = PR_OpenDir(path); if (! dirhandle) { PR_Delete(path); return 0; } while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT | PR_SKIP_DOT_DOT))) { if (! direntry->name) break; PR_snprintf(fullpath, MAXPATHLEN, "%s/%s", path, direntry->name); rval = PR_GetFileInfo(fullpath, &info); if (PR_SUCCESS == rval) { if (PR_FILE_DIRECTORY == info.type) rval += ldbm_delete_dirs(fullpath); } if (PR_FILE_DIRECTORY != info.type) PR_Delete(fullpath); } PR_CloseDir(dirhandle); /* remove the directory itself too */ rval += PR_RmDir(path); return rval; }
/* * r m _ d a s h _ r * * Remove a file, or a directory recursively. * */ int rm_dash_r(char *path) { PRDir *dir; PRDirEntry *entry; PRFileInfo fileinfo; char filename[FNSIZE]; if (PR_GetFileInfo(path, &fileinfo) != PR_SUCCESS) { /*fprintf(stderr, "Error: Unable to access %s\n", filename);*/ return -1; } if (fileinfo.type == PR_FILE_DIRECTORY) { dir = PR_OpenDir(path); if (!dir) { PR_fprintf(errorFD, "Error: Unable to open directory %s.\n", path); errorCount++; return -1; } /* Recursively delete all entries in the directory */ while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) { sprintf(filename, "%s/%s", path, entry->name); if (rm_dash_r(filename)) return -1; } if (PR_CloseDir(dir) != PR_SUCCESS) { PR_fprintf(errorFD, "Error: Could not close %s.\n", path); errorCount++; return -1; } /* Delete the directory itself */ if (PR_RmDir(path) != PR_SUCCESS) { PR_fprintf(errorFD, "Error: Unable to delete %s\n", path); errorCount++; return -1; } } else { if (PR_Delete(path) != PR_SUCCESS) { PR_fprintf(errorFD, "Error: Unable to delete %s\n", path); errorCount++; return -1; } } return 0; }
int32 CallPRDeleteFileUsingFileURL(char *fileURL) { int32 result = -1; const char *path; char *escapedPath = unescapeURL(fileURL); path = convertFileURLToNSPRCopaceticPath(escapedPath); if (path != NULL) { result = PR_Delete(path); } if (escapedPath != NULL) freeMem(escapedPath); return result; }
//--------------------------------------------- // nsZipArchive::ExtractFile // This extracts the item to the filehandle provided. // If 'aFd' is null, it only tests the extraction. // On extraction error(s) it removes the file. // When needed, it also resolves the symlink. //--------------------------------------------- nsresult nsZipArchive::ExtractFile(nsZipItem *item, const char *outname, PRFileDesc* aFd) { if (!item) return ZIP_ERR_PARAM; if (!mFd) return ZIP_ERR_GENERAL; // Directory extraction is handled in nsJAR::Extract, // so the item to be extracted should never be a directory PR_ASSERT(!item->isDirectory); //-- move to the start of file's data if (SeekToItem(item, mFd) != ZIP_OK) return ZIP_ERR_CORRUPT; nsresult rv; //-- extract the file using the appropriate method switch(item->compression) { case STORED: rv = CopyItemToDisk(item->size, item->crc32, aFd); break; case DEFLATED: rv = InflateItem(item, aFd); break; default: //-- unsupported compression type rv = ZIP_ERR_UNSUPPORTED; } //-- delete the file on errors, or resolve symlink if needed if (aFd) { PR_Close(aFd); if (rv != ZIP_OK) PR_Delete(outname); #if defined(XP_UNIX) || defined(XP_BEOS) else if (item->isSymlink) rv = ResolveSymlink(outname); #endif } return rv; }
Result<Ok, nsresult> MemMapSnapshot::Freeze(AutoMemMap& aMem) { // Delete the shm file after we're done here, whether we succeed or not. The // open file descriptor will keep it alive until all remaining references // are closed, at which point it will be automatically freed. auto cleanup = MakeScopeExit([&]() { PR_Delete(mPath.get()); }); // Make the shm file readonly. This doesn't make a difference in practice, // since we open and share a read-only file descriptor, and then delete the // file. But it doesn't hurt, either. chmod(mPath.get(), 0400); nsCOMPtr<nsIFile> file; MOZ_TRY(NS_NewNativeLocalFile(mPath, /* followLinks = */ false, getter_AddRefs(file))); return aMem.init(file); }
//--------------------------------------------- // ResolveSymlink //--------------------------------------------- static nsresult ResolveSymlink(const char *path) { PRFileDesc * fIn = PR_Open(path, PR_RDONLY, 0000); if (!fIn) return ZIP_ERR_DISK; char buf[PATH_MAX+1]; PRInt32 length = PR_Read(fIn, (void*)buf, PATH_MAX); PR_Close(fIn); if ( (length <= 0) || ((buf[length] = 0, PR_Delete(path)) != 0) || (symlink(buf, path) != 0)) { return ZIP_ERR_DISK; } return ZIP_OK; }
static PRBool MakeConfFile(const char *regfile, const nsCString &greHome, const GREProperty *aProperties, PRUint32 aPropertiesLen) { // If the file exists, don't create it again! if (access(regfile, R_OK) == 0) return PR_FALSE; PRBool ok = PR_TRUE; { // scope "fd" so that we can delete the file if something goes wrong AutoFDClose fd = PR_Open(regfile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE, 0664); if (!fd) return PR_FALSE; static const char kHeader[] = "# Registration file generated by xulrunner. Do not edit.\n\n" "[" GRE_BUILD_ID "]\n" "GRE_PATH="; if (PR_Write(fd, kHeader, sizeof(kHeader) - 1) != sizeof(kHeader) - 1) ok = PR_FALSE; if (PR_Write(fd, greHome.get(), greHome.Length()) != greHome.Length()) ok = PR_FALSE; for (PRUint32 i = 0; i < aPropertiesLen; ++i) { if (PR_fprintf(fd, "\n%s=%s", aProperties[i].property, aProperties[i].value) <= 0) ok = PR_FALSE; } PR_Write(fd, "\n", 1); } if (!ok) PR_Delete(regfile); return ok; }
/** * ZIP_ExtractFile * * extracts named file from an opened archive * * @param hZip handle obtained from ZIP_OpenArchive * @param filename name of file in archive * @param outname filename to extract to */ PR_PUBLIC_API(PRInt32) ZIP_ExtractFile(void* hZip, const char * filename, const char * outname) { /*--- error check args ---*/ if (hZip == 0) return ZIP_ERR_PARAM; nsZipArchive* zip = static_cast<nsZipArchive*>(hZip); if (zip->kMagic != ZIP_MAGIC) return ZIP_ERR_PARAM; /* whatever it is isn't one of ours! */ //-- Find item in archive nsZipItem* item = zip->GetItem(filename); if (!item) return ZIP_ERR_FNF; // Can't extract a directory if (item->isDirectory) return ZIP_ERR_PARAM; // delete any existing file so that we overwrite the file permissions PR_Delete(outname); PRFileDesc* fOut = PR_Open(outname, ZFILE_CREATE, item->mode); if (!fOut) return ZIP_ERR_DISK; #if defined(XP_UNIX) && defined(STANDALONE) // When STANDALONE is defined, PR_Open ignores its 3d argument. mode_t msk = umask(0); umask(msk); chmod(outname, (item->mode | S_IRUSR) & ~msk); #endif // ExtractFile also closes the fOut handle and resolves the symlink if needed return zip->ExtractFile(item, outname, fOut); }
int main(int argc, char **argv) { PRFileDesc *fd; PRInt64 offset, position; PRInt32 nbytes; char buf[MESSAGE_SIZE]; #ifdef _WIN32 HANDLE hFile; LARGE_INTEGER li; #endif /* _WIN32 */ LL_I2L(offset, 1); LL_SHL(offset, offset, 32); #ifdef _WIN32 hFile = CreateFile(TEST_FILE_NAME, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { fprintf(stderr, "CreateFile failed\n"); exit(1); } li.QuadPart = offset; li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN); if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) { fprintf(stderr, "SetFilePointer failed\n"); exit(1); } PR_ASSERT(li.QuadPart == offset); strcpy(buf, MESSAGE); if (WriteFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) { fprintf(stderr, "WriteFile failed\n"); exit(1); } PR_ASSERT(nbytes == sizeof(buf)); if (CloseHandle(hFile) == 0) { fprintf(stderr, "CloseHandle failed\n"); exit(1); } #endif /* _WIN32 */ memset(buf, 0, sizeof(buf)); fd = PR_Open(TEST_FILE_NAME, PR_RDONLY, 0666); if (fd == NULL) { fprintf(stderr, "PR_Open failed\n"); exit(1); } position = PR_Seek64(fd, offset, PR_SEEK_SET); if (!LL_GE_ZERO(position)) { fprintf(stderr, "PR_Seek64 failed\n"); exit(1); } PR_ASSERT(LL_EQ(position, offset)); nbytes = PR_Read(fd, buf, sizeof(buf)); if (nbytes != sizeof(buf)) { fprintf(stderr, "PR_Read failed\n"); exit(1); } if (strcmp(buf, MESSAGE)) { fprintf(stderr, "corrupt data:$%s$\n", buf); exit(1); } if (PR_Close(fd) == PR_FAILURE) { fprintf(stderr, "PR_Close failed\n"); exit(1); } if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) { fprintf(stderr, "PR_Delete failed\n"); exit(1); } printf("PASS\n"); return 0; }
NSFC_MakeTempCopy(const char *infile, char *outfile, NSFCCache cip, PRInt64 *size) { PRFileDesc *infd; PRFileDesc *outfd; char *cp; PRStatus rv = PR_FAILURE; infd = NSFC_PR_Open(infile, PR_RDONLY, 0); if (infd == NULL) { return rv; } /* Create the output directory if necessary */ cp = strrchr(outfile, '/'); if (cp) { *cp = 0; rv = NSFC_MakeDirectory(outfile, cip); *cp = '/'; if (rv == PR_FAILURE) { PR_Close(infd); return rv; } } outfd = NSFC_PR_Open(outfile, PR_CREATE_FILE|PR_TRUNCATE|PR_WRONLY, 0660); if (outfd != NULL) { PRInt32 inlen = -1; PRInt32 outlen; PRInt64 written = 0; char *buffer = (char *)PR_Malloc(COPY_BUFFER_SIZE); if (buffer) { while (1) { inlen = PR_Read(infd, buffer, COPY_BUFFER_SIZE); if (inlen <= 0) { break; } outlen = PR_Write(outfd, buffer, inlen); if (outlen != inlen) { break; } written += outlen; } PR_Free(buffer); } PR_Close(outfd); if (inlen == 0) { rv = PR_SUCCESS; struct stat tempStat; *size = written; /* VB: bug# 360312 * Whenever we make a temporary copy of a file, we need to * set the modification/access time of the copy to be that * of the original. * This is required to avoid the following scenario. * 1. Copy file1 preserving timestamp. * 2. Edit file1 and access it. This would cause the edited verion * to be cached and a temp copy of the edited verion to be * created. * 3. Now replace the edited file1 with the original copy preserving * the timestamp. So file 1 has the timestamp at the beginning * of our test. * 4. We would never end up serving this file since the timestamp * of the temp copy would be ahead of that of file1. * 5. With this fix, we aviod the case since we can now compare * for inequality (LL_NE) rather than which is newer. (LL_CMP). * This is of relevance in raltion to the doc dir being backed up * and restored. */ if (stat(infile, &tempStat) == 0) { struct utimbuf infileTime; infileTime.actime = tempStat.st_atime; infileTime.modtime = tempStat.st_mtime; if (utime(outfile, &infileTime) == -1) { /* VB: This can happen if the file is owned by someone else * This should not happen unless the server user was changed * Should we be failing in this case ? */ int whatDoIdonow = 1; } } else { // stat failed. This should happen if infile got deleted. // So what - we serve the temp file until the filecache // realizes to the contrary. int shouldNotMatter = 0; } } else { rv = PR_FAILURE; PR_Delete(outfile); } } PR_Close(infd); return rv; }
NSFC_OpenTempCopy(NSFCCache cip, NSFCEntryImpl *nep, NSFCStatusInfo *statusInfo) { const char *fname; int releaseWrite = 0; PRStatus rv; PRFileDesc *fd; char tempname[1024]; NSFCSTATUSINFO_INIT(statusInfo); /* copy files for non-cache transmit is not supported */ if (nep == NULL) { PR_ASSERT(0); return NULL; } fname = nep->filename; if (!(nep->flags & NSFCENTRY_HASINFO)) { PR_ASSERT(0); return NULL; } if (nep->flags & NSFCENTRY_ERRORINFO) return NULL; /* Don't repeatedly try to copy a too-large file to a too-small tempDir */ if (nep->flags & NSFCENTRY_CREATETMPFAIL) return NULL; if (_make_tempname(cip, fname, tempname, sizeof(tempname)) == NULL) return NULL; /* Has this file been copied to a temporary file yet? */ if (!(nep->flags & NSFCENTRY_TMPFILE)) { PRFileInfo64 tfinfo; PRFileInfo64 *nepfinfo = NULL; PRBool needCopy = PR_TRUE; nepfinfo = &(nep->finfo.pr); if (NSFC_AcquireEntryWriteLock(cip, nep) != NSFC_OK) goto error; /* See if temp file created while we acquired the lock */ if (nep->flags & NSFCENTRY_TMPFILE) { NSFC_ReleaseEntryWriteLock(cip, nep); goto do_open; } releaseWrite = 1; /* See if the temporary file is present */ if (NSFC_PR_GetFileInfo(tempname, &tfinfo) == PR_SUCCESS) { /* Is the temporary file up to date? */ if ((tfinfo.size == nep->finfo.pr.size) && (tfinfo.creationTime == nep->finfo.pr.creationTime) && (tfinfo.modifyTime == nep->finfo.pr.modifyTime)) { /* Yes, use the copy as is */ needCopy = PR_FALSE; } else { /* No, delete the copy and create a new one */ rv = PR_Delete(tempname); if (rv == PR_FAILURE) { NSFCSTATUSINFO_SET(statusInfo, NSFC_STATUSINFO_DELETETMPFAIL); fd = NULL; goto error; } } } if (needCopy == PR_TRUE) { PRInt64 size = nepfinfo->size; rv = NSFC_MakeTempCopy(fname, tempname, cip, &size); if (rv == PR_FAILURE) { /* Failed to create temporary copy */ NSFCSTATUSINFO_SET(statusInfo, NSFC_STATUSINFO_CREATETMPFAIL); nep->flags |= NSFCENTRY_CREATETMPFAIL; fd = NULL; goto error; } if (size != nepfinfo->size) { NSFCSTATUSINFO_SET(statusInfo, NSFC_STATUSINFO_FILESIZE); NSFC_DeleteEntry(cip, nep, PR_FALSE); fd = NULL; goto error; } } nep->flags |= NSFCENTRY_TMPFILE; NSFC_ReleaseEntryWriteLock(cip, nep); releaseWrite = 0; } do_open: fd = NSFC_PR_Open(tempname, PR_RDONLY, 0); return fd; error: /* We get here only on an error with a NULL fd */ if (releaseWrite) { NSFC_ReleaseEntryWriteLock(cip, nep); } return NULL; }
/*********************************************************************** ** PRIVATE FUNCTION: Thread ** DESCRIPTION: ** Hammer on the file I/O system ** INPUTS: A pointer to the thread's private data ** OUTPUTS: None ** RETURN: None ** SIDE EFFECTS: ** Creates, accesses and deletes a file ** RESTRICTIONS: ** (Currently) must have file create permission in "/usr/tmp". ** MEMORY: NA ** ALGORITHM: ** This function is a root of a thread ** 1) Creates a (hopefully) unique file in /usr/tmp/ ** 2) Writes a zero to a random number of sequential pages ** 3) Closes the file ** 4) Reopens the file ** 5) Seeks to a random page within the file ** 6) Writes a one byte on that page ** 7) Repeat steps [5..6] for each page in the file ** 8) Close and delete the file ** 9) Repeat steps [1..8] until told to stop ** 10) Notify complete and return ***********************************************************************/ static void PR_CALLBACK Thread(void *arg) { PRUint32 index; char filename[30]; const char zero = 0; PRFileDesc *file = NULL; PRStatus rv = PR_SUCCESS; Hammer_t *cd = (Hammer_t*)arg; (void)sprintf(filename, "%ssg%04ld.dat", baseName, cd->id); if (debug_mode) printf("Starting work on %s\n", filename); while (PR_TRUE) { PRUint32 bytes; PRUint32 minor = (Random() % cd->limit) + 1; PRUint32 random = (Random() % cd->limit) + 1; PRUint32 pages = (Random() % cd->limit) + 10; while (minor-- > 0) { cd->problem = sg_okay; if (cd->action != sg_go) goto finished; cd->problem = sg_open; file = PR_Open(filename, PR_RDWR|PR_CREATE_FILE, 0666); if (file == NULL) goto finished; for (index = 0; index < pages; index++) { cd->problem = sg_okay; if (cd->action != sg_go) goto close; cd->problem = sg_seek; bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET); if (bytes != pageSize * index) goto close; cd->problem = sg_write; bytes = PR_Write(file, &zero, sizeof(zero)); if (bytes <= 0) goto close; cd->writes += 1; } cd->problem = sg_close; rv = PR_Close(file); if (rv != PR_SUCCESS) goto purge; cd->problem = sg_okay; if (cd->action != sg_go) goto purge; cd->problem = sg_open; file = PR_Open(filename, PR_RDWR, 0666); for (index = 0; index < pages; index++) { cd->problem = sg_okay; if (cd->action != sg_go) goto close; cd->problem = sg_seek; bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET); if (bytes != pageSize * index) goto close; cd->problem = sg_write; bytes = PR_Write(file, &zero, sizeof(zero)); if (bytes <= 0) goto close; cd->writes += 1; random = (random + 511) % pages; } cd->problem = sg_close; rv = PR_Close(file); if (rv != PR_SUCCESS) goto purge; cd->problem = sg_delete; rv = PR_Delete(filename); if (rv != PR_SUCCESS) goto finished; } } close: (void)PR_Close(file); purge: (void)PR_Delete(filename); finished: PR_Lock(cd->ml); cd->action = sg_done; PR_NotifyCondVar(cd->cv); PR_Unlock(cd->ml); if (debug_mode) printf("Ending work on %s\n", filename); return; } /* Thread */
//---------------------------------------------------------------------------------------- static int CrudeFileCopy(const char* in, const char* out) //---------------------------------------------------------------------------------------- { char buf[1024]; // Used as buffer for the copy loop PRInt32 rbytes, wbytes; // Number of bytes read and written in copy loop struct stat in_stat; // Stores informations from the stat syscall int stat_result = -1, ret; PRFileDesc * pFileDescIn, * pFileDescOut; // Src and dest pointers // Check if the pointers to filenames are valid NS_ASSERTION(in && out, "CrudeFileCopy should be called with pointers to filenames..."); // Check if the pointers are the same, if so, no need to copy A to A if (in == out) return 0; // Check if content of the pointers are the sames, if so, no need to copy A to A if (strcmp(in,out) == 0) return 0; // Retrieve the 'in' file attributes stat_result = stat(in, &in_stat); if(stat_result != 0) { // test if stat failed, it can happen if the file does not exist, is not // readable or is not available ( can happen with NFS mounts ) return -1; // Return an error } // Open the input file for binary read pFileDescIn = PR_Open(in, PR_RDONLY, 0444); if (pFileDescIn == 0) { return -1; // Open failed, return an error } // Open the output file for binary write pFileDescOut = PR_Open(out, PR_WRONLY | PR_CREATE_FILE, 0600); if (pFileDescOut == 0) { // Open failed, need to close input file, then return an error PR_Close(pFileDescOut); // Close the output file return -1; // Open failed, return an error } // Copy the data if (CrudeFileCopy_DoCopy(pFileDescIn, pFileDescOut, buf, sizeof(buf)) != 0) { // Error case PR_Close(pFileDescOut); // Close output file PR_Close(pFileDescIn); // Close input file PR_Delete(out); // Destroy output file return -1; // Return an error } // There is no need for error handling here. This should have worked, but even // if it fails, the data are now copied to destination, thus there is no need // for the function to fail on the input file error PR_Close(pFileDescIn); // It is better to call fsync and test return code before exiting to be sure // data are actually written on disk. Data loss can happen with NFS mounts if (PR_Sync(pFileDescOut) != PR_SUCCESS) { // Test if the fsync function succeeded PR_Close(pFileDescOut); // Close output file PR_Delete(out); // Destroy output file return -1; // Return an error } // Copy is done, close both file if (PR_Close(pFileDescOut) != PR_SUCCESS) // Close output file { // Output file was not closed :( PR_Delete(out); // Destroy output file return -1; // Return an error } ret = chmod(out, in_stat.st_mode & 0777); // Set the new file file mode if (ret != 0) // Test if the chmod function succeeded { PR_Delete(out); // Destroy output file return -1; // Return an error } return 0; // Still here ? ok so it worked :) } // nsFileSpec::CrudeFileCopy
/* * Delete a module from the Data Base */ static SECStatus nssutil_DeleteSecmodDBEntry(const char *appName, const char *filename, const char *dbname, char *args, PRBool rw) { /* SHDB_FIXME implement */ os_stat_type stat_existing; os_open_permissions_type file_mode; FILE *fd = NULL; FILE *fd2 = NULL; char line[MAX_LINE_LENGTH]; char *dbname2 = NULL; char *block = NULL; char *name = NULL; char *lib = NULL; int name_len = 0, lib_len = 0; PRBool skip = PR_FALSE; PRBool found = PR_FALSE; if (dbname == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if (!rw) { PORT_SetError(SEC_ERROR_READ_ONLY); return SECFailure; } dbname2 = PORT_Strdup(dbname); if (dbname2 == NULL) goto loser; dbname2[strlen(dbname)-1]++; /* get the permissions of the existing file, or use the default */ if (!os_stat(dbname, &stat_existing)) { file_mode = stat_existing.st_mode; } else { file_mode = os_open_permissions_default; } /* do we really want to use streams here */ fd = fopen(dbname, "r"); if (fd == NULL) goto loser; fd2 = lfopen(dbname2, lfopen_truncate, file_mode); if (fd2 == NULL) goto loser; name = NSSUTIL_ArgGetParamValue("name",args); if (name) { name_len = PORT_Strlen(name); } lib = NSSUTIL_ArgGetParamValue("library",args); if (lib) { lib_len = PORT_Strlen(lib); } /* * the following loop takes line separated config files and collapses * the lines to a single string, escaping and quoting as necessary. */ /* loop state variables */ block = NULL; skip = PR_FALSE; while (fgets(line, sizeof(line), fd) != NULL) { /* If we are processing a block (we haven't hit a blank line yet */ if (*line != '\n') { /* skip means we are in the middle of a block we are deleting */ if (skip) { continue; } /* if we haven't found the block yet, check to see if this block * matches our requirements */ if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) && (PORT_Strncmp(line+5,name,name_len) == 0)) || (lib && (PORT_Strncasecmp(line,"library=",8) == 0) && (PORT_Strncmp(line+8,lib,lib_len) == 0)))) { /* yup, we don't need to save any more data, */ PORT_Free(block); block=NULL; /* we don't need to collect more of this block */ skip = PR_TRUE; /* we don't need to continue searching for the block */ found =PR_TRUE; continue; } /* not our match, continue to collect data in this block */ block = nssutil_DupCat(block,line); continue; } /* we've collected a block of data that wasn't the module we were * looking for, write it out */ if (block) { fwrite(block, PORT_Strlen(block), 1, fd2); PORT_Free(block); block = NULL; } /* If we didn't just delete the this block, keep the blank line */ if (!skip) { fputs(line,fd2); } /* we are definately not in a deleted block anymore */ skip = PR_FALSE; } fclose(fd); fclose(fd2); if (found) { /* rename dbname2 to dbname */ PR_Delete(dbname); PR_Rename(dbname2,dbname); } else { PR_Delete(dbname2); } PORT_Free(dbname2); PORT_Free(lib); PORT_Free(name); PORT_Free(block); return SECSuccess; loser: if (fd != NULL) { fclose(fd); } if (fd2 != NULL) { fclose(fd2); } if (dbname2) { PR_Delete(dbname2); PORT_Free(dbname2); } PORT_Free(lib); PORT_Free(name); return SECFailure; }
void RunWriter(void* arg) { PR_SetCurrentThreadName("Shutdown Statistics Writer"); MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(arg); // Shutdown will generally complete before we have a chance to // deallocate. This is not a leak. // Setup destinationPath and tmpFilePath nsCString destinationPath(static_cast<char*>(arg)); nsAutoCString tmpFilePath; tmpFilePath.Append(destinationPath); tmpFilePath.AppendLiteral(".tmp"); // Cleanup any file leftover from a previous run Unused << PR_Delete(tmpFilePath.get()); Unused << PR_Delete(destinationPath.get()); while (true) { // // Check whether we have received data from the main thread. // // We perform the check before waiting on `gWriteReady` as we may // have received data while we were busy writing. // // Also note that gWriteData may have been modified several times // since we last checked. That's ok, we are not losing any important // data (since we keep adding data), and we are not leaking memory // (since the main thread deallocates any data that hasn't been // consumed by the writer thread). // UniquePtr<nsCString> data(gWriteData.exchange(nullptr)); if (!data) { // Data is not available yet. // Wait until the main thread provides it. PR_EnterMonitor(gWriteReady); PR_Wait(gWriteReady, PR_INTERVAL_NO_TIMEOUT); PR_ExitMonitor(gWriteReady); continue; } MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(data.get()); // Shutdown may complete before we have a chance to deallocate. // This is not a leak. // // Write to a temporary file // // In case of any error, we simply give up. Since the data is // hardly critical, we don't want to spend too much effort // salvaging it. // UniquePtr<PRFileDesc, PR_CloseDelete> tmpFileDesc(PR_Open(tmpFilePath.get(), PR_WRONLY | PR_TRUNCATE | PR_CREATE_FILE, 00600)); // Shutdown may complete before we have a chance to close the file. // This is not a leak. MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(tmpFileDesc.get()); if (tmpFileDesc == nullptr) { break; } if (PR_Write(tmpFileDesc.get(), data->get(), data->Length()) == -1) { break; } tmpFileDesc.reset(); // // Rename on top of destination file. // // This is not sufficient to guarantee that the destination file // will be written correctly, but, again, we don't care enough // about the data to make more efforts. // if (PR_Rename(tmpFilePath.get(), destinationPath.get()) != PR_SUCCESS) { break; } } }
/************************************************************************* * * P k 1 1 I n s t a l l _ D o I n s t a l l * * jarFile is the path of a JAR in the PKCS #11 module JAR format. * installDir is the directory relative to which files will be * installed. */ Pk11Install_Error Pk11Install_DoInstall(char *jarFile, const char *installDir, const char *tempDir, PRFileDesc *feedback, short force, PRBool noverify) { JAR *jar; char *installer; unsigned long installer_len; int status; Pk11Install_Error ret; PRBool made_temp_file; Pk11Install_Info installInfo; Pk11Install_Platform *platform; char *errMsg; char sysname[SYS_INFO_BUFFER_LENGTH], release[SYS_INFO_BUFFER_LENGTH], arch[SYS_INFO_BUFFER_LENGTH]; char *myPlatform; jar = NULL; ret = PK11_INSTALL_UNSPECIFIED; made_temp_file = PR_FALSE; errMsg = NULL; Pk11Install_Info_init(&installInfo); /* printf("Inside DoInstall, jarFile=%s, installDir=%s, tempDir=%s\n", jarFile, installDir, tempDir); */ /* * Check out jarFile and installDir for validity */ if (PR_Access(installDir, PR_ACCESS_EXISTS) != PR_SUCCESS) { error(PK11_INSTALL_DIR_DOESNT_EXIST, installDir); return PK11_INSTALL_DIR_DOESNT_EXIST; } if (!tempDir) { tempDir = "."; } if (PR_Access(tempDir, PR_ACCESS_EXISTS) != PR_SUCCESS) { error(PK11_INSTALL_DIR_DOESNT_EXIST, tempDir); return PK11_INSTALL_DIR_DOESNT_EXIST; } if (PR_Access(tempDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) { error(PK11_INSTALL_DIR_NOT_WRITEABLE, tempDir); return PK11_INSTALL_DIR_NOT_WRITEABLE; } if ((PR_Access(jarFile, PR_ACCESS_EXISTS) != PR_SUCCESS)) { error(PK11_INSTALL_FILE_DOESNT_EXIST, jarFile); return PK11_INSTALL_FILE_DOESNT_EXIST; } if (PR_Access(jarFile, PR_ACCESS_READ_OK) != PR_SUCCESS) { error(PK11_INSTALL_FILE_NOT_READABLE, jarFile); return PK11_INSTALL_FILE_NOT_READABLE; } /* * Extract the JAR file */ jar = JAR_new(); JAR_set_callback(JAR_CB_SIGNAL, jar, jar_callback); if (noverify) { status = JAR_pass_archive_unverified(jar, jarArchGuess, jarFile, "url"); } else { status = JAR_pass_archive(jar, jarArchGuess, jarFile, "url"); } if ((status < 0) || (jar->valid < 0)) { if (status >= JAR_BASE && status <= JAR_BASE_END) { error(PK11_INSTALL_JAR_ERROR, jarFile, JAR_get_error(status)); } else { error(PK11_INSTALL_JAR_ERROR, jarFile, mySECU_ErrorString(PORT_GetError())); } ret = PK11_INSTALL_JAR_ERROR; goto loser; } /*printf("passed the archive\n");*/ /* * Show the user security information, allow them to abort or continue */ if (Pk11Install_UserVerifyJar(jar, PR_STDOUT, force ? PR_FALSE : PR_TRUE) && !force) { if (feedback) { PR_fprintf(feedback, msgStrings[USER_ABORT]); } ret = PK11_INSTALL_USER_ABORT; goto loser; } /* * Get the name of the installation file */ if (JAR_get_metainfo(jar, NULL, INSTALL_METAINFO_TAG, (void **)&installer, (unsigned long *)&installer_len)) { error(PK11_INSTALL_NO_INSTALLER_SCRIPT); ret = PK11_INSTALL_NO_INSTALLER_SCRIPT; goto loser; } if (feedback) { PR_fprintf(feedback, msgStrings[INSTALLER_SCRIPT_NAME], installer); } /* * Extract the installation file */ if (PR_Access(SCRIPT_TEMP_FILE, PR_ACCESS_EXISTS) == PR_SUCCESS) { if (PR_Delete(SCRIPT_TEMP_FILE) != PR_SUCCESS) { error(PK11_INSTALL_DELETE_TEMP_FILE, SCRIPT_TEMP_FILE); ret = PK11_INSTALL_DELETE_TEMP_FILE; goto loser; } } if (noverify) { status = JAR_extract(jar, installer, SCRIPT_TEMP_FILE); } else { status = JAR_verified_extract(jar, installer, SCRIPT_TEMP_FILE); } if (status) { if (status >= JAR_BASE && status <= JAR_BASE_END) { error(PK11_INSTALL_JAR_EXTRACT, installer, JAR_get_error(status)); } else { error(PK11_INSTALL_JAR_EXTRACT, installer, mySECU_ErrorString(PORT_GetError())); } ret = PK11_INSTALL_JAR_EXTRACT; goto loser; } else { made_temp_file = PR_TRUE; } /* * Parse the installation file into a syntax tree */ Pk11Install_FD = PR_Open(SCRIPT_TEMP_FILE, PR_RDONLY, 0); if (!Pk11Install_FD) { error(PK11_INSTALL_OPEN_SCRIPT_FILE, SCRIPT_TEMP_FILE); ret = PK11_INSTALL_OPEN_SCRIPT_FILE; goto loser; } if (Pk11Install_yyparse()) { error(PK11_INSTALL_SCRIPT_PARSE, installer, Pk11Install_yyerrstr ? Pk11Install_yyerrstr : ""); ret = PK11_INSTALL_SCRIPT_PARSE; goto loser; } #if 0 /* for debugging */ Pk11Install_valueList->Print(0); #endif /* * From the syntax tree, build a semantic structure */ errMsg = Pk11Install_Info_Generate(&installInfo, Pk11Install_valueList); if (errMsg) { error(PK11_INSTALL_SEMANTIC, errMsg); ret = PK11_INSTALL_SEMANTIC; goto loser; } #if 0 installInfo.Print(0); #endif if (feedback) { PR_fprintf(feedback, msgStrings[PARSED_INSTALL_SCRIPT]); } /* * Figure out which platform to use */ { sysname[0] = release[0] = arch[0] = '\0'; if ((PR_GetSystemInfo(PR_SI_SYSNAME, sysname, SYS_INFO_BUFFER_LENGTH) != PR_SUCCESS) || (PR_GetSystemInfo(PR_SI_RELEASE, release, SYS_INFO_BUFFER_LENGTH) != PR_SUCCESS) || (PR_GetSystemInfo(PR_SI_ARCHITECTURE, arch, SYS_INFO_BUFFER_LENGTH) != PR_SUCCESS)) { error(PK11_INSTALL_SYSINFO); ret = PK11_INSTALL_SYSINFO; goto loser; } myPlatform = PR_smprintf("%s:%s:%s", sysname, release, arch); platform = Pk11Install_Info_GetBestPlatform(&installInfo, myPlatform); if (!platform) { error(PK11_INSTALL_NO_PLATFORM, myPlatform); PR_smprintf_free(myPlatform); ret = PK11_INSTALL_NO_PLATFORM; goto loser; } if (feedback) { PR_fprintf(feedback, msgStrings[MY_PLATFORM_IS], myPlatform); PR_fprintf(feedback, msgStrings[USING_PLATFORM], Pk11Install_PlatformName_GetString(&platform->name)); } PR_smprintf_free(myPlatform); } /* Run the install for that platform */ ret = DoInstall(jar, installDir, tempDir, platform, feedback, noverify); if (ret) { goto loser; } ret = PK11_INSTALL_SUCCESS; loser: if (Pk11Install_valueList) { Pk11Install_ValueList_delete(Pk11Install_valueList); PR_Free(Pk11Install_valueList); Pk11Install_valueList = NULL; } if (jar) { JAR_destroy(jar); } if (made_temp_file) { PR_Delete(SCRIPT_TEMP_FILE); } if (errMsg) { PR_smprintf_free(errMsg); } return ret; }
/********************************************************************* * * m a i n */ int main(int argc, char *argv[]) { PRBool readOnly; int retval = 0; outputFD = PR_STDOUT; errorFD = PR_STDERR; progName = argv[0]; if (argc < 2) { Usage(); } excludeDirs = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL); extensions = PL_NewHashTable(10, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL); if (parse_args(argc, argv)) { retval = -1; goto cleanup; } /* Parse the command file if one was given */ if (cmdFile) { if (ProcessCommandFile()) { retval = -1; goto cleanup; } } /* Set up output redirection */ if (outfile) { if (PR_Access(outfile, PR_ACCESS_EXISTS) == PR_SUCCESS) { /* delete the file if it is already present */ PR_fprintf(errorFD, "warning: %s already exists and will be overwritten.\n", outfile); warningCount++; if (PR_Delete(outfile) != PR_SUCCESS) { PR_fprintf(errorFD, "ERROR: unable to delete %s.\n", outfile); errorCount++; exit(ERRX); } } outputFD = PR_Open(outfile, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0777); if (!outputFD) { PR_fprintf(errorFD, "ERROR: Unable to create %s.\n", outfile); errorCount++; exit(ERRX); } errorFD = outputFD; } /* This seems to be a fairly common user error */ if (verify && list_certs > 0) { PR_fprintf(errorFD, "%s: Can't use -l and -v at the same time\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* -J assumes -Z now */ if (javascript && zipfile) { PR_fprintf(errorFD, "%s: Can't use -J and -Z at the same time\n", PROGRAM_NAME); PR_fprintf(errorFD, "%s: -J option will create the jar files for you\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* -X needs -Z */ if (xpi_arc && !zipfile) { PR_fprintf(errorFD, "%s: option XPI (-X) requires option jarfile (-Z)\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } /* Less common mixing of -L with various options */ if (list_certs > 0 && (tell_who || zipfile || javascript || scriptdir || extensionsGiven || exclusionsGiven || install_script)) { PR_fprintf(errorFD, "%s: Can't use -l or -L with that option\n", PROGRAM_NAME); errorCount++; retval = -1; goto cleanup; } if (!cert_dir) cert_dir = get_default_cert_dir(); VerifyCertDir(cert_dir, keyName); if (compression_level < MIN_COMPRESSION_LEVEL || compression_level > MAX_COMPRESSION_LEVEL) { PR_fprintf(errorFD, "Compression level must be between %d and %d.\n", MIN_COMPRESSION_LEVEL, MAX_COMPRESSION_LEVEL); errorCount++; retval = -1; goto cleanup; } if (jartree && !keyName) { PR_fprintf(errorFD, "You must specify a key with which to sign.\n"); errorCount++; retval = -1; goto cleanup; } readOnly = (genkey == NULL); /* only key generation requires write */ if (InitCrypto(cert_dir, readOnly)) { PR_fprintf(errorFD, "ERROR: Cryptographic initialization failed.\n"); errorCount++; retval = -1; goto cleanup; } if (enableOCSP) { SECStatus rv = CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); if (rv != SECSuccess) { PR_fprintf(errorFD, "ERROR: Attempt to enable OCSP Checking failed.\n"); errorCount++; retval = -1; } } if (verify) { if (VerifyJar(verify)) { errorCount++; retval = -1; goto cleanup; } } else if (list_certs) { if (ListCerts(keyName, list_certs)) { errorCount++; retval = -1; goto cleanup; } } else if (list_modules) { JarListModules(); } else if (genkey) { if (GenerateCert(genkey, keySize, token)) { errorCount++; retval = -1; goto cleanup; } } else if (tell_who) { if (JarWho(tell_who)) { errorCount++; retval = -1; goto cleanup; } } else if (javascript && jartree) { /* make sure directory exists */ PRDir *dir; dir = PR_OpenDir(jartree); if (!dir) { PR_fprintf(errorFD, "ERROR: unable to open directory %s.\n", jartree); errorCount++; retval = -1; goto cleanup; } else { PR_CloseDir(dir); } /* undo junk from prior runs of signtool*/ if (RemoveAllArc(jartree)) { PR_fprintf(errorFD, "Error removing archive directories under %s\n", jartree); errorCount++; retval = -1; goto cleanup; } /* traverse all the htm|html files in the directory */ if (InlineJavaScript(jartree, !noRecurse)) { retval = -1; goto cleanup; } /* sign any resultant .arc directories created in above step */ if (SignAllArc(jartree, keyName, javascript, metafile, install_script, optimize, !noRecurse)) { retval = -1; goto cleanup; } if (!leaveArc) { RemoveAllArc(jartree); } if (errorCount > 0 || warningCount > 0) { PR_fprintf(outputFD, "%d error%s, %d warning%s.\n", errorCount, errorCount == 1 ? "" : "s", warningCount, warningCount == 1 ? "" : "s"); } else { PR_fprintf(outputFD, "Directory %s signed successfully.\n", jartree); } } else if (jartree) { SignArchive(jartree, keyName, zipfile, javascript, metafile, install_script, optimize, !noRecurse); } else Usage(); cleanup: if (extensions) { PL_HashTableDestroy(extensions); extensions = NULL; } if (excludeDirs) { PL_HashTableDestroy(excludeDirs); excludeDirs = NULL; } if (outputFD != PR_STDOUT) { PR_Close(outputFD); } rm_dash_r(TMP_OUTPUT); if (retval == 0) { if (NSS_Shutdown() != SECSuccess) { exit(1); } } return retval; }
PRIntn main(PRIntn argc, char *argv[]) { PRFileDesc *fd; PRStatus rv; PRInt32 written; char outBuf[] = "op_excl.c test file"; #define OUT_SIZE sizeof(outBuf) #define NEW_FILENAME "xxxExclNewFile" { /* ** Get command line options */ PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "hd"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug */ debug = 1; msgLevel = PR_LOG_ERROR; break; case 'h': /* help message */ Help(); break; default: break; } } PL_DestroyOptState(opt); } lm = PR_NewLogModule("Test"); /* Initialize logging */ /* ** First, open a file, PR_EXCL, we believe not to exist */ fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 ); if ( NULL == fd ) { if (debug) fprintf( stderr, "Open exclusive. Expected success, got failure\n"); failed_already = 1; goto Finished; } written = PR_Write( fd, outBuf, OUT_SIZE ); if ( OUT_SIZE != written ) { if (debug) fprintf( stderr, "Write after open exclusive failed\n"); failed_already = 1; goto Finished; } rv = PR_Close(fd); if ( PR_FAILURE == rv ) { if (debug) fprintf( stderr, "Close after open exclusive failed\n"); failed_already = 1; goto Finished; } /* ** Second, open the same file, PR_EXCL, expect it to fail */ fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 ); if ( NULL != fd ) { if (debug) fprintf( stderr, "Open exclusive. Expected failure, got success\n"); failed_already = 1; PR_Close(fd); } rv = PR_Delete( NEW_FILENAME ); if ( PR_FAILURE == rv ) { if (debug) fprintf( stderr, "PR_Delete() failed\n"); failed_already = 1; } Finished: if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); return( (failed_already == PR_TRUE )? 1 : 0 ); } /* main() */
void referint_thread_func(void *arg) { PRFileDesc *prfd; char **plugin_argv = (char **)arg; char *logfilename; char thisline[MAX_LINE]; char delimiter[]="\t\n"; char *ptoken; char *tmprdn; char *iter = NULL; Slapi_DN *sdn = NULL; Slapi_DN *tmpsuperior = NULL; int logChanges = 0; int delay; int no_changes; if(plugin_argv == NULL){ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_thread_func not get args \n" ); return; } delay = atoi(plugin_argv[0]); logfilename = plugin_argv[1]; logChanges = atoi(plugin_argv[2]); /* * keep running this thread until plugin is signaled to close */ while(1){ no_changes=1; while(no_changes){ PR_Lock(keeprunning_mutex); if(keeprunning == 0){ PR_Unlock(keeprunning_mutex); break; } PR_Unlock(keeprunning_mutex); referint_lock(); if (( prfd = PR_Open( logfilename, PR_RDONLY, REFERINT_DEFAULT_FILE_MODE )) == NULL ){ referint_unlock(); /* go back to sleep and wait for this file */ PR_Lock(keeprunning_mutex); PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay)); PR_Unlock(keeprunning_mutex); } else { no_changes = 0; } } /* * Check keep running here, because after break out of no * changes loop on shutdown, also need to break out of this * loop before trying to do the changes. The server * will pick them up on next startup as file still exists */ PR_Lock(keeprunning_mutex); if(keeprunning == 0){ PR_Unlock(keeprunning_mutex); break; } PR_Unlock(keeprunning_mutex); while( GetNextLine(thisline, MAX_LINE, prfd) ){ ptoken = ldap_utf8strtok_r(thisline, delimiter, &iter); sdn = slapi_sdn_new_normdn_byref(ptoken); ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter); if(!strcasecmp(ptoken, "NULL")) { tmprdn = NULL; } else { tmprdn = slapi_ch_smprintf("%s", ptoken); } ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter); if (!strcasecmp(ptoken, "NULL")) { tmpsuperior = NULL; } else { tmpsuperior = slapi_sdn_new_normdn_byref(ptoken); } ptoken = ldap_utf8strtok_r (NULL, delimiter, &iter); if (strcasecmp(ptoken, "NULL") != 0) { /* Set the bind DN in the thread data */ if(slapi_td_set_dn(slapi_ch_strdup(ptoken))){ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,"Failed to set thread data\n"); } } update_integrity(plugin_argv, sdn, tmprdn, tmpsuperior, logChanges); slapi_sdn_free(&sdn); slapi_ch_free_string(&tmprdn); slapi_sdn_free(&tmpsuperior); } PR_Close(prfd); /* remove the original file */ if( PR_SUCCESS != PR_Delete(logfilename) ){ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop_close could not delete \"%s\"\n", logfilename ); } /* unlock and let other writers back at the file */ referint_unlock(); /* wait on condition here */ PR_Lock(keeprunning_mutex); PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay)); PR_Unlock(keeprunning_mutex); } /* cleanup resources allocated in start */ if (NULL != keeprunning_mutex) { PR_DestroyLock(keeprunning_mutex); } if (NULL != referint_mutex) { PR_DestroyLock(referint_mutex); } if (NULL != keeprunning_cv) { PR_DestroyCondVar(keeprunning_cv); } }
static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server) { PRStatus drv, rv; char buffer[1024]; PRFileDesc *file = NULL; PRThread * me = PR_GetCurrentThread(); PRInt32 bytes, descbytes, netbytes, filebytes = 0; CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): receiving desciptor\n", me)); bytes = PR_Recv( fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout); if (-1 == bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto exit; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): receive timeout\n", me)); } goto exit; } if (0 == bytes) { rv = PR_FAILURE; TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): unexpected end of file\n", me)); goto exit; } descbytes = PR_ntohl(descriptor->size); TEST_ASSERT(sizeof(*descriptor) == bytes); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", me, descbytes, descriptor->filename)); file = PR_Open( descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666); if (NULL == file) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): open file timeout\n", me)); goto aborted; } } TEST_ASSERT(NULL != file); filebytes = 0; while (filebytes < descbytes) { netbytes = sizeof(buffer); if ((descbytes - filebytes) < netbytes) netbytes = descbytes - filebytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)); bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); if (-1 == bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): receive data timeout\n", me)); goto aborted; } /* * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED) * on NT here. This is equivalent to ECONNRESET on Unix. * -wtc */ TEST_LOG( cltsrv_log_file, TEST_LOG_WARNING, ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } if(0 == bytes) { TEST_LOG( cltsrv_log_file, TEST_LOG_WARNING, ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)); rv = PR_FAILURE; goto aborted; } filebytes += bytes; netbytes = bytes; /* The byte count for PR_Write should be positive */ MY_ASSERT(netbytes > 0); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes)); bytes = PR_Write(file, buffer, netbytes); if (netbytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): write file timeout\n", me)); goto aborted; } } TEST_ASSERT(bytes > 0); } PR_Lock(server->ml); server->operations += 1; server->bytesTransferred += filebytes; PR_Unlock(server->ml); rv = PR_Close(file); if (Aborted(rv)) goto aborted; TEST_ASSERT(PR_SUCCESS == rv); file = NULL; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename)); file = PR_Open(descriptor->filename, PR_RDONLY, 0); if (NULL == file) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread())); goto aborted; } TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } TEST_ASSERT(NULL != file); netbytes = 0; while (netbytes < descbytes) { filebytes = sizeof(buffer); if ((descbytes - netbytes) < filebytes) filebytes = descbytes - netbytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes)); bytes = PR_Read(file, buffer, filebytes); if (filebytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): read file timeout\n", me)); else TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } TEST_ASSERT(bytes > 0); netbytes += bytes; filebytes = bytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes)); bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); if (filebytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): send data timeout\n", me)); goto aborted; } break; } TEST_ASSERT(bytes > 0); } PR_Lock(server->ml); server->bytesTransferred += filebytes; PR_Unlock(server->ml); rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); if (Aborted(rv)) goto aborted; rv = PR_Close(file); if (Aborted(rv)) goto aborted; TEST_ASSERT(PR_SUCCESS == rv); file = NULL; aborted: PR_ClearInterrupt(); if (NULL != file) PR_Close(file); drv = PR_Delete(descriptor->filename); TEST_ASSERT(PR_SUCCESS == drv); exit: TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): Finished\n", me)); PR_DELETE(descriptor); #if defined(WIN95) PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */ #endif return rv; } /* ProcessRequest */
int ldbm_instance_post_delete_instance_entry_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) { char *instance_name; struct ldbminfo *li = (struct ldbminfo *)arg; struct ldbm_instance *inst = NULL; parse_ldbm_instance_entry(entryBefore, &instance_name); inst = ldbm_instance_find_by_name(li, instance_name); if (inst == NULL) { LDAPDebug(LDAP_DEBUG_ANY, "ldbm: instance '%s' does not exist! (2)\n", instance_name, 0, 0); if (returntext) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "No ldbm instance exists with the name '%s' (2)\n", instance_name); } if (returncode) { *returncode = LDAP_UNWILLING_TO_PERFORM; } slapi_ch_free((void **)&instance_name); return SLAPI_DSE_CALLBACK_ERROR; } LDAPDebug(LDAP_DEBUG_ANY, "ldbm: removing '%s'.\n", instance_name, 0, 0); cache_destroy_please(&inst->inst_cache, CACHE_TYPE_ENTRY); if (entryrdn_get_switch()) { /* subtree-rename: on */ cache_destroy_please(&inst->inst_dncache, CACHE_TYPE_DN); } { struct ldbminfo *li = (struct ldbminfo *) inst->inst_be->be_database->plg_private; dblayer_private *priv = (dblayer_private*) li->li_dblayer_private; struct dblayer_private_env *pEnv = priv->dblayer_env; if(pEnv) { PRDir *dirhandle = NULL; char inst_dir[MAXPATHLEN*2]; char *inst_dirp = NULL; if (inst->inst_dir_name == NULL){ dblayer_get_instance_data_dir(inst->inst_be); } inst_dirp = dblayer_get_full_inst_dir(li, inst, inst_dir, MAXPATHLEN*2); if (NULL != inst_dirp) { dirhandle = PR_OpenDir(inst_dirp); /* the db dir instance may have been removed already */ if (dirhandle) { PRDirEntry *direntry = NULL; char *dbp = NULL; char *p = NULL; while (NULL != (direntry = PR_ReadDir(dirhandle, PR_SKIP_DOT|PR_SKIP_DOT_DOT))) { int rc; if (!direntry->name) break; dbp = PR_smprintf("%s/%s", inst_dirp, direntry->name); if (NULL == dbp) { LDAPDebug (LDAP_DEBUG_ANY, "ldbm_instance_post_delete_instance_entry_callback:" " failed to generate db path: %s/%s\n", inst_dirp, direntry->name, 0); break; } p = strstr(dbp, LDBM_FILENAME_SUFFIX); if (NULL != p && strlen(p) == strlen(LDBM_FILENAME_SUFFIX)) { rc = dblayer_db_remove(pEnv, dbp, 0); } else { rc = PR_Delete(dbp); } PR_ASSERT(rc == 0); PR_smprintf_free(dbp); } PR_CloseDir(dirhandle); } /* * When a backend was removed, the db instance directory * was removed as well (See also bz463774). * In case DB_RECOVER_FATAL is set in the DB open after * the removal (e.g., in restore), the logs in the transaction * logs are replayed and compared with the contents of the DB * files. At that time, if the db instance directory does not * exist, libdb returns FATAL error. To prevent the problem, * we have to leave the empty directory. (bz597375) * * PR_RmDir(inst_dirp); */ } /* non-null dirhandle */ if (inst_dirp != inst_dir) { slapi_ch_free_string(&inst_dirp); } } /* non-null pEnv */ } ldbm_instance_unregister_callbacks(inst); slapi_be_free(&inst->inst_be); ldbm_instance_destroy(inst); slapi_ch_free((void **)&instance_name); return SLAPI_DSE_CALLBACK_OK; }
/* * Socket_Misc_Test - test miscellaneous functions * */ static PRInt32 Socket_Misc_Test(void) { PRIntn i, rv = 0, bytes, count, len; PRThread *t; PRThreadScope scope; PRSemaphore *server_sem; Server_Param *sparamp; Client_Param *cparamp; PRMonitor *mon2; PRInt32 datalen; /* * We deliberately pick a buffer size that is not a nice multiple * of 1024. */ #define TRANSMITFILE_BUF_SIZE (4 * 1024 - 11) typedef struct { char data[TRANSMITFILE_BUF_SIZE]; } file_buf; file_buf *buf = NULL; /* * create file(s) to be transmitted */ if ((PR_MkDir(TEST_DIR, 0777)) < 0) { printf("prsocket_test failed to create dir %s\n",TEST_DIR); failed_already=1; return -1; } small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777); if (small_file_fd == NULL) { fprintf(stderr,"prsocket_test failed to create/open file %s\n", SMALL_FILE_NAME); failed_already=1; rv = -1; goto done; } buf = PR_NEW(file_buf); if (buf == NULL) { fprintf(stderr,"prsocket_test failed to allocate buffer\n"); failed_already=1; rv = -1; goto done; } /* * fill in random data */ for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) { buf->data[i] = i; } count = 0; do { len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ? TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count); bytes = PR_Write(small_file_fd, buf->data, len); if (bytes <= 0) { fprintf(stderr, "prsocket_test failed to write to file %s\n", SMALL_FILE_NAME); failed_already=1; rv = -1; goto done; } count += bytes; } while (count < SMALL_FILE_SIZE); #ifdef XP_UNIX /* * map the small file; used in checking for data corruption */ small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ, MAP_PRIVATE, small_file_fd->secret->md.osfd, 0); if (small_file_addr == (void *) -1) { fprintf(stderr,"prsocket_test failed to mmap file %s\n", SMALL_FILE_NAME); failed_already=1; rv = -1; goto done; } #endif /* * header for small file */ small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE); if (small_file_header == NULL) { fprintf(stderr,"prsocket_test failed to malloc header file\n"); failed_already=1; rv = -1; goto done; } memset(small_file_header, (int) PR_IntervalNow(), SMALL_FILE_HEADER_SIZE); /* * setup large file */ large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777); if (large_file_fd == NULL) { fprintf(stderr,"prsocket_test failed to create/open file %s\n", LARGE_FILE_NAME); failed_already=1; rv = -1; goto done; } /* * fill in random data */ for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) { buf->data[i] = i; } count = 0; do { len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ? TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count); bytes = PR_Write(large_file_fd, buf->data, len); if (bytes <= 0) { fprintf(stderr, "prsocket_test failed to write to file %s: (%ld, %ld)\n", LARGE_FILE_NAME, PR_GetError(), PR_GetOSError()); failed_already=1; rv = -1; goto done; } count += bytes; } while (count < LARGE_FILE_SIZE); #ifdef XP_UNIX /* * map the large file; used in checking for data corruption */ large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ, MAP_PRIVATE, large_file_fd->secret->md.osfd, 0); if (large_file_addr == (void *) -1) { fprintf(stderr,"prsocket_test failed to mmap file %s\n", LARGE_FILE_NAME); failed_already=1; rv = -1; goto done; } #endif datalen = tcp_mesg_size; thread_count = 0; /* * start the server thread */ sparamp = PR_NEW(Server_Param); if (sparamp == NULL) { fprintf(stderr,"prsocket_test: PR_NEW failed\n"); failed_already=1; rv = -1; goto done; } server_sem = PR_NewSem(0); if (server_sem == NULL) { fprintf(stderr,"prsocket_test: PR_NewSem failed\n"); failed_already=1; rv = -1; goto done; } mon2 = PR_NewMonitor(); if (mon2 == NULL) { fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n"); failed_already=1; rv = -1; goto done; } PR_EnterMonitor(mon2); sparamp->addr_sem = server_sem; sparamp->exit_mon = mon2; sparamp->exit_counter = &thread_count; sparamp->datalen = datalen; t = PR_CreateThread(PR_USER_THREAD, TransmitFile_Server, (void *)sparamp, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (t == NULL) { fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); failed_already=1; rv = -1; goto done; } DPRINTF(("Created TCP server = 0x%x\n", t)); thread_count++; /* * wait till the server address is setup */ PR_WaitSem(server_sem); /* * Now start a bunch of client threads */ cparamp = PR_NEW(Client_Param); if (cparamp == NULL) { fprintf(stderr,"prsocket_test: PR_NEW failed\n"); failed_already=1; rv = -1; goto done; } cparamp->server_addr = tcp_server_addr; cparamp->server_addr.inet.ip = PR_htonl(INADDR_LOOPBACK); cparamp->exit_mon = mon2; cparamp->exit_counter = &thread_count; cparamp->datalen = datalen; for (i = 0; i < num_transmitfile_clients; i++) { /* * Every other thread is a LOCAL/GLOBAL thread */ if (i & 1) scope = PR_GLOBAL_THREAD; else scope = PR_LOCAL_THREAD; t = PR_CreateThread(PR_USER_THREAD, TransmitFile_Client, (void *) cparamp, PR_PRIORITY_NORMAL, scope, PR_UNJOINABLE_THREAD, 0); if (t == NULL) { fprintf(stderr,"prsocket_test: PR_CreateThread failed\n"); rv = -1; failed_already=1; goto done; } DPRINTF(("Created TransmitFile client = 0x%lx\n", t)); thread_count++; } /* Wait for server and client threads to exit */ while (thread_count) { PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT); DPRINTF(("Socket_Misc_Test - thread_count = %d\n", thread_count)); } PR_ExitMonitor(mon2); done: if (buf) { PR_DELETE(buf); } #ifdef XP_UNIX munmap(small_file_addr, SMALL_FILE_SIZE); munmap(large_file_addr, LARGE_FILE_SIZE); #endif PR_Close(small_file_fd); PR_Close(large_file_fd); if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) { fprintf(stderr,"prsocket_test: failed to unlink file %s\n", SMALL_FILE_NAME); failed_already=1; } if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) { fprintf(stderr,"prsocket_test: failed to unlink file %s\n", LARGE_FILE_NAME); failed_already=1; } if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) { fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n", TEST_DIR, PR_GetError(), PR_GetOSError()); failed_already=1; } printf("%-29s%s","Socket_Misc_Test",":"); printf("%2d Server %2d Clients\n",1, num_transmitfile_clients); printf("%30s Sizes of Transmitted Files - %4d KB, %2d MB \n",":", SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024)); return rv; }
/* * Delete a module from the Data Base */ SECStatus sftkdb_DeleteSecmodDB(SDBType dbType, const char *appName, const char *filename, const char *dbname, char *args, PRBool rw) { /* SHDB_FIXME implement */ FILE *fd = NULL; FILE *fd2 = NULL; char line[MAX_LINE_LENGTH]; char *dbname2 = NULL; char *block = NULL; char *name = NULL; char *lib = NULL; int name_len, lib_len; PRBool skip = PR_FALSE; PRBool found = PR_FALSE; if (dbname == NULL) { return SECFailure; } if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { return sftkdbCall_DeleteSecmodDB(appName, filename, dbname, args, rw); } if (!rw) { return SECFailure; } dbname2 = strdup(dbname); if (dbname2 == NULL) goto loser; dbname2[strlen(dbname)-1]++; /* do we really want to use streams here */ fd = fopen(dbname, "r"); if (fd == NULL) goto loser; #ifdef WINCE fd2 = fopen(dbname2, "w+"); #else fd2 = lfopen(dbname2, "w+", O_CREAT|O_RDWR|O_TRUNC); #endif if (fd2 == NULL) goto loser; name = sftk_argGetParamValue("name",args); if (name) { name_len = PORT_Strlen(name); } lib = sftk_argGetParamValue("library",args); if (lib) { lib_len = PORT_Strlen(lib); } /* * the following loop takes line separated config files and collapses * the lines to a single string, escaping and quoting as necessary. */ /* loop state variables */ block = NULL; skip = PR_FALSE; while (fgets(line, sizeof(line), fd) != NULL) { /* If we are processing a block (we haven't hit a blank line yet */ if (*line != '\n') { /* skip means we are in the middle of a block we are deleting */ if (skip) { continue; } /* if we haven't found the block yet, check to see if this block * matches our requirements */ if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) && (PORT_Strncmp(line+5,name,name_len) == 0)) || (lib && (PORT_Strncasecmp(line,"library=",8) == 0) && (PORT_Strncmp(line+8,lib,lib_len) == 0)))) { /* yup, we don't need to save any more data, */ PORT_Free(block); block=NULL; /* we don't need to collect more of this block */ skip = PR_TRUE; /* we don't need to continue searching for the block */ found =PR_TRUE; continue; } /* not our match, continue to collect data in this block */ block = sftkdb_DupCat(block,line); continue; } /* we've collected a block of data that wasn't the module we were * looking for, write it out */ if (block) { fwrite(block, PORT_Strlen(block), 1, fd2); PORT_Free(block); block = NULL; } /* If we didn't just delete the this block, keep the blank line */ if (!skip) { fputs(line,fd2); } /* we are definately not in a deleted block anymore */ skip = PR_FALSE; } fclose(fd); fclose(fd2); if (found) { /* rename dbname2 to dbname */ PR_Delete(dbname); PR_Rename(dbname2,dbname); } else { PR_Delete(dbname2); } PORT_Free(dbname2); PORT_Free(lib); PORT_Free(name); PORT_Free(block); return SECSuccess; loser: if (fd != NULL) { fclose(fd); } if (fd2 != NULL) { fclose(fd2); } if (dbname2) { PR_Delete(dbname2); PORT_Free(dbname2); } PORT_Free(lib); PORT_Free(name); return SECFailure; }
PRIntn main(PRIntn argc, char *argv[]) { PRThread *tJitter; PRThread *tAccept; PRThread *tConnect; PRStatus rv; /* This test if valid for WinNT only! */ #if !defined(WINNT) return 0; #endif { /* ** Get command line options */ PLOptStatus os; PLOptState *opt = PL_CreateOptState(argc, argv, "hdrvj:"); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'd': /* debug */ debug = 1; msgLevel = PR_LOG_ERROR; break; case 'v': /* verbose mode */ verbose = 1; msgLevel = PR_LOG_DEBUG; break; case 'j': jitter = atoi(opt->value); if ( jitter == 0) jitter = JITTER_DEFAULT; break; case 'r': resume = PR_TRUE; break; case 'h': /* help message */ Help(); break; default: break; } } PL_DestroyOptState(opt); } lm = PR_NewLogModule("Test"); /* Initialize logging */ /* set concurrency */ PR_SetConcurrency( 4 ); /* setup thread synchronization mechanics */ ml = PR_NewLock(); cv = PR_NewCondVar( ml ); /* setup a tcp socket */ memset(&listenAddr, 0, sizeof(listenAddr)); rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr); PR_ASSERT( PR_SUCCESS == rv ); listenSock = PR_NewTCPSocket(); PR_ASSERT( listenSock ); rv = PR_Bind( listenSock, &listenAddr); PR_ASSERT( PR_SUCCESS == rv ); rv = PR_Listen( listenSock, 5 ); PR_ASSERT( PR_SUCCESS == rv ); /* open a file for writing, provoke bug */ file1 = PR_Open("xxxTestFile", PR_CREATE_FILE | PR_RDWR, 666); /* create Connect thread */ tConnect = PR_CreateThread( PR_USER_THREAD, ConnectThread, NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0 ); PR_ASSERT( tConnect ); /* create jitter off thread */ tJitter = PR_CreateThread( PR_USER_THREAD, JitterThread, NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0 ); PR_ASSERT( tJitter ); /* create acceptread thread */ tAccept = PR_CreateThread( PR_USER_THREAD, AcceptThread, NULL, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0 ); PR_ASSERT( tAccept ); /* wait for all threads to quit, then terminate gracefully */ PR_JoinThread( tConnect ); PR_JoinThread( tAccept ); PR_JoinThread( tJitter ); PR_Close( listenSock ); PR_DestroyCondVar(cv); PR_DestroyLock(ml); PR_Close( file1 ); PR_Delete( "xxxTestFile"); /* test return and exit */ if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); return( (failed_already == PR_TRUE )? 1 : 0 ); } /* main() */