PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { int retval = PAM_IGNORE; gray_slist_t slist; cntl_flags = 0; debug_level = 0; gray_log_init(0, MODULE_NAME, LOG_AUTHPRIV); gray_parseopt(pam_opt, argc, argv); if (la_str) { double max_la, la; if (fpread(la_str, &max_la)) return PAM_SERVICE_ERR; if (get_la(&la) == 0 && la >= max_la) { _pam_log(LOG_ERR, "load average too high: %.2g >= %.2g", la, max_la); return PAM_IGNORE; } } if (motd_file_name) { char *file; slist = gray_slist_create(); gray_expand_string(pamh, motd_file_name, slist); gray_slist_append_char(slist, 0); file = gray_slist_finish(slist); retval = read_file(pamh, file); gray_slist_free(&slist); } else if (optindex >= 0) { int i; char **xargv; argc -= optindex; argv += optindex; if (!argc) { _pam_log(LOG_INFO, "empty command line"); return retval; } xargv = gray_malloc((argc + 1) * sizeof (xargv[0])); slist = gray_slist_create(); for (i = 0; i < argc; i++) { gray_expand_string(pamh, argv[i], slist); gray_slist_append_char(slist, 0); xargv[i] = gray_slist_finish(slist); } xargv[i] = NULL; retval = exec_file(pamh, xargv, logfile_name); free(xargv); gray_slist_free(&slist); } else _pam_log(LOG_ERR, "invalid usage: either file or exec must be specified"); return retval; }
int btree_init(BTreePtr btree, FILE* fp) { ssize_t nbytes = 0; void* buf = NULL; buf = ALLOC(512); assert(buf != NULL); // First, init the fork record for future calls. btree->fp = fp; // Now load up the header node. if ( (nbytes = fpread(btree->fp, buf, sizeof(BTNodeDescriptor), 0)) < 0 ) { SFREE(buf); return -1; } btree->nodeDescriptor = *(BTNodeDescriptor*)buf; swap_BTNodeDescriptor(&btree->nodeDescriptor); // If there's a header record, we'll likely want that as well. if (btree->nodeDescriptor.numRecords > 0) { memset(buf, 0, 512); if ( (nbytes = fpread(btree->fp, buf, sizeof(BTHeaderRec), sizeof(BTNodeDescriptor))) < 0 ) { SFREE(buf); return -1; } btree->headerRecord = *(BTHeaderRec*)buf; swap_BTHeaderRec(&btree->headerRecord); // Next comes 128 bytes of "user" space for record 2 that we don't care about. // TODO: Then the remainder of the node is allocation bitmap data for record 3 which we'll care about later. } // Init the node cache. cache_init(&btree->nodeCache, 100); SFREE(buf); return 0; }
/* FIXME: Linux-specific */ static int get_la(double *ret) { char buf[80]; int rc = -1; FILE *fp = fopen("/proc/loadavg", "r"); if (!fp) return -1; if (!fgets(buf, sizeof(buf), fp)) _pam_log(LOG_ERR, "cannot read /proc/loadavg: %s", strerror(errno)); else { char *p = strchr(buf, ' '); if (*p) { *p = 0; rc = fpread(buf, ret); } else rc = -1; } fclose(fp); return rc; }
int btree_get_node(BTreeNodePtr* outNode, const BTreePtr tree, bt_nodeid_t nodeNumber) { BTreeNodePtr node = NULL; ssize_t bytes_read = 0; trace("Tree %u: getting node %d", tree->treeID, nodeNumber); if(nodeNumber >= tree->headerRecord.totalNodes) { error("Node %u is beyond file range.", nodeNumber); return -1; } if ((nodeNumber != 0) && (BTIsNodeUsed(tree, nodeNumber) == false)) { debug2("Node %u is unused.", nodeNumber); return -1; } node = ALLOC(sizeof(struct _BTreeNode)); assert(node != NULL); node->nodeSize = tree->headerRecord.nodeSize; node->nodeNumber = nodeNumber; node->nodeOffset = node->nodeNumber * node->nodeSize; node->bTree = tree; node->treeID = tree->treeID; node->data = ALLOC(node->nodeSize); assert(node->data != NULL); node->dataLen = node->nodeSize; assert(tree->nodeCache != NULL); // Check the tree's node cache for a previous load. if (cache_get(tree->nodeCache, (void*)node->data, node->nodeSize, nodeNumber) == 1) { debug("Loaded a cached node for %u:%u", node->treeID, nodeNumber); } else { assert(node->data != NULL); bytes_read = fpread(node->bTree->fp, node->data, node->nodeSize, node->nodeOffset); if (bytes_read < 0) { error("Error reading from fork."); btree_free_node(node); return bytes_read; } if ((size_t)bytes_read != node->nodeSize) { warning("node read failed: expected %zd bytes, got %zd", node->nodeSize, bytes_read); } else if (tree->nodeCache != NULL) { cache_set(tree->nodeCache, (char*)node->data, node->nodeSize, nodeNumber); } } assert(node->nodeDescriptor->numRecords > 0); if ( swap_BTreeNode(node) < 0 ) { error("node %u: byte-swap of node failed.", node->nodeNumber); btree_free_node(node); errno = EINVAL; return -1; } node->recordCount = node->nodeDescriptor->numRecords; *outNode = node; return 0; }