static int needsReScan( int what, CfgDep *dep ) { int widx, idx; long mt; for (widx = 0; cfgMapT[widx] != what; widx++); idx = cfgMap[widx]; if (checkDep( idx )) { if (!GetDeps()) return -1; idx = cfgMap[widx]; } mt = mTime( cfgFiles[idx].name->str ); if (dep->name != cfgFiles[idx].name) { if (dep->name) delStr( dep->name ); dep->name = cfgFiles[idx].name; dep->name->cnt++; dep->time = mt; return 1; } else if (dep->time != mt) { dep->time = mt; return 1; } else return 0; }
static int checkDep( int idx ) { int dep; if ((dep = cfgFiles[idx].depidx) == -1) return 0; if (checkDep( dep )) return 1; return mTime( cfgFiles[dep].name->str ) != cfgFiles[idx].deptime; }
/* Callback for the rich dependency parser. We use this to do check for invalid * characters and to build a normailzed version of the dependency */ static rpmRC parseRCPOTRichCB(void *cbdata, rpmrichParseType type, const char *n, int nl, const char *e, int el, rpmsenseFlags sense, rpmrichOp op, char **emsg) { struct parseRCPOTRichData *data = cbdata; StringBuf sb = data->sb; rpmRC rc = RPMRC_OK; if (type == RPMRICH_PARSE_ENTER) { appendStringBuf(sb, "("); } else if (type == RPMRICH_PARSE_LEAVE) { appendStringBuf(sb, ")"); } else if (type == RPMRICH_PARSE_SIMPLE) { char *N = xmalloc(nl + 1); char *EVR = NULL; rstrlcpy(N, n, nl + 1); appendStringBuf(sb, N); if (el) { char rel[6], *rp = rel; EVR = xmalloc(el + 1); rstrlcpy(EVR, e, el + 1); *rp++ = ' '; if (sense & RPMSENSE_LESS) *rp++ = '<'; if (sense & RPMSENSE_GREATER) *rp++ = '>'; if (sense & RPMSENSE_EQUAL) *rp++ = '='; *rp++ = ' '; *rp = 0; appendStringBuf(sb, rel); appendStringBuf(sb, EVR); } rc = checkDep(data->spec, N, EVR, emsg); _free(N); _free(EVR); } else if (type == RPMRICH_PARSE_OP) { appendStringBuf(sb, " "); appendStringBuf(sb, rpmrichOpStr(op)); appendStringBuf(sb, " "); } return rc; }
void* processWork(void* data) { int jobs = *(int*)data; int proc = 0; int i = 0; int b = 0; parsed_data_t* parsed = NULL; while(1) { /* Grab next available element from Queue */ pthread_mutex_lock(&accessQueue); parsed = (parsed_data_t*)queue_pop_front(&g_q); pthread_mutex_unlock(&accessQueue); /* Determine whether its dependencies have been met and it's non-NULL */ if(parsed != NULL) { pthread_mutex_lock(&accessProced); for(i = 0; i < parsed->numDeps; ++i) { /* If deps not met, send to back of queue and return to top of loop */ if(checkDep(parsed->deps[i])) { pthread_mutex_lock(&accessQueue); queue_push_back(&g_q, (void*)parsed); pthread_mutex_unlock(&accessQueue); b = 1; break; } } pthread_mutex_unlock(&accessProced); if(b) { b = 0; continue; } } else { /* If NULL, check processed against the number of threads */ /* If processed >= threads, then sleep this thread and wait on signal */ pthread_mutex_lock(&accessProced); proc = queue_size(&g_p); pthread_mutex_unlock(&accessProced); if(proc >= threads || threads > jobs) { pthread_mutex_lock(&waking); sleeping++; pthread_cond_signal(&wakeupMain); pthread_mutex_unlock(&waking); pthread_mutex_lock(&killing); pthread_cond_wait(&killThreads, &killing); pthread_mutex_unlock(&killing); break; } continue; } /* If deps met, then run its commands */ for(i = 0; i < parsed->numCmds; ++i) system(parsed->commands[i]); /* Add to the processed queue */ pthread_mutex_lock(&accessProced); queue_push_back(&g_p, (void*)parsed); proc = queue_size(&g_p); pthread_mutex_unlock(&accessProced); /* If the size of the processed queue == jobs, signal main */ if(proc >= jobs) { pthread_mutex_lock(&waking); sleeping++; pthread_cond_signal(&wakeupMain); pthread_mutex_unlock(&waking); pthread_mutex_lock(&killing); pthread_cond_wait(&killThreads, &killing); pthread_mutex_unlock(&killing); break; } } return 0; }
rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTagVal tagN, int index, rpmsenseFlags tagflags) { const char *r, *re, *v, *ve; char *emsg = NULL; char * N = NULL, * EVR = NULL; rpmTagVal nametag = RPMTAG_NOT_FOUND; rpmsenseFlags Flags; rpmds *pdsp = NULL; rpmRC rc = RPMRC_FAIL; /* assume failure */ switch (tagN) { default: case RPMTAG_REQUIREFLAGS: nametag = RPMTAG_REQUIRENAME; tagflags |= RPMSENSE_ANY; break; case RPMTAG_RECOMMENDFLAGS: nametag = RPMTAG_RECOMMENDNAME; break; case RPMTAG_SUGGESTFLAGS: nametag = RPMTAG_SUGGESTNAME; break; case RPMTAG_SUPPLEMENTFLAGS: nametag = RPMTAG_SUPPLEMENTNAME; break; case RPMTAG_ENHANCEFLAGS: nametag = RPMTAG_ENHANCENAME; break; case RPMTAG_PROVIDEFLAGS: nametag = RPMTAG_PROVIDENAME; break; case RPMTAG_OBSOLETEFLAGS: nametag = RPMTAG_OBSOLETENAME; break; case RPMTAG_CONFLICTFLAGS: nametag = RPMTAG_CONFLICTNAME; break; case RPMTAG_ORDERFLAGS: nametag = RPMTAG_ORDERNAME; break; case RPMTAG_PREREQ: /* XXX map legacy PreReq into Requires(pre,preun) */ nametag = RPMTAG_REQUIRENAME; tagflags |= (RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_PREUN); break; case RPMTAG_TRIGGERPREIN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPREIN; break; case RPMTAG_TRIGGERIN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_TRIGGERPOSTUN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; case RPMTAG_TRIGGERUN: nametag = RPMTAG_TRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_BUILDPREREQ: case RPMTAG_BUILDREQUIRES: nametag = RPMTAG_REQUIRENAME; tagflags |= RPMSENSE_ANY; break; case RPMTAG_BUILDCONFLICTS: nametag = RPMTAG_CONFLICTNAME; break; case RPMTAG_FILETRIGGERIN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_FILETRIGGERUN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_FILETRIGGERPOSTUN: nametag = RPMTAG_FILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; case RPMTAG_TRANSFILETRIGGERIN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERIN; break; case RPMTAG_TRANSFILETRIGGERUN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERUN; break; case RPMTAG_TRANSFILETRIGGERPOSTUN: nametag = RPMTAG_TRANSFILETRIGGERNAME; tagflags |= RPMSENSE_TRIGGERPOSTUN; break; } for (r = field; *r != '\0'; r = re) { SKIPWHITE(r); if (*r == '\0') break; Flags = (tagflags & ~RPMSENSE_SENSEMASK); if (r[0] == '(') { struct parseRCPOTRichData data; if (nametag != RPMTAG_REQUIRENAME && nametag != RPMTAG_CONFLICTNAME && nametag != RPMTAG_RECOMMENDNAME && nametag != RPMTAG_SUPPLEMENTNAME && nametag != RPMTAG_SUGGESTNAME && nametag != RPMTAG_ENHANCENAME) { rasprintf(&emsg, _("No rich dependencies allowed for this type")); goto exit; } data.spec = spec; data.sb = newStringBuf(); if (rpmrichParse(&r, &emsg, parseRCPOTRichCB, &data) != RPMRC_OK) { freeStringBuf(data.sb); goto exit; } if (addReqProv(pkg, nametag, getStringBuf(data.sb), NULL, Flags | RPMSENSE_RICH, index)) { rasprintf(&emsg, _("invalid dependency")); freeStringBuf(data.sb); goto exit; } freeStringBuf(data.sb); re = r; continue; } re = r; SKIPNONWHITE(re); N = xmalloc((re-r) + 1); rstrlcpy(N, r, (re-r) + 1); /* Parse EVR */ EVR = NULL; v = re; SKIPWHITE(v); ve = v; SKIPNONWHITE(ve); re = v; /* ==> next token (if no EVR found) starts here */ /* Check for possible logical operator */ if (ve > v) { rpmsenseFlags sense = rpmParseDSFlags(v, ve - v); if (sense) { Flags |= sense; /* now parse EVR */ v = ve; SKIPWHITE(v); ve = v; SKIPNONWHITE(ve); if (*v == '\0' || ve == v) { rasprintf(&emsg, _("Version required")); goto exit; } EVR = xmalloc((ve-v) + 1); rstrlcpy(EVR, v, (ve-v) + 1); re = ve; /* ==> next token after EVR string starts here */ } } /* check that dependency is well-formed */ if (checkDep(spec, N, EVR, &emsg)) goto exit; if (nametag == RPMTAG_FILETRIGGERNAME || nametag == RPMTAG_TRANSFILETRIGGERNAME) { if (N[0] != '/') { rasprintf(&emsg, _("Only absolute paths are allowed in " "file triggers")); } } /* Deny more "normal" triggers fired by the same pakage. File triggers are ok */ pdsp = packageDependencies(pkg, nametag); rpmdsInit(*pdsp); if (nametag == RPMTAG_TRIGGERNAME) { while (rpmdsNext(*pdsp) >= 0) { if (rstreq(rpmdsN(*pdsp), N) && ((rpmdsFlags(*pdsp) & tagflags))) { rasprintf(&emsg, _("Trigger fired by the same package " "is already defined in spec file")); goto exit; } } } if (addReqProv(pkg, nametag, N, EVR, Flags, index)) { rasprintf(&emsg, _("invalid dependency")); goto exit; } N = _free(N); EVR = _free(EVR); } rc = RPMRC_OK; exit: if (emsg) { int lvl = (rc == RPMRC_OK) ? RPMLOG_WARNING : RPMLOG_ERR; /* Automatic dependencies don't relate to spec lines */ if (tagflags & (RPMSENSE_FIND_REQUIRES|RPMSENSE_FIND_PROVIDES)) { rpmlog(lvl, "%s: %s\n", emsg, r); } else { rpmlog(lvl, _("line %d: %s: %s\n"), spec->lineNum, emsg, spec->line); } free(emsg); } _free(N); _free(EVR); return rc; }