GMC_DCL(tp_FileName, FileName) { tp_FilDsc FilDsc; tp_Str Str; tps_Str StrBuf; int count, i, status; FilDsc = FileName_RFilDsc(FileName, FALSE); if (FilDsc == ERROR) { Writeln(StdOutFD, "Using bootstrap derivation graph."); EnvVarDefS = (tp_Str *)malloc((unsigned)(num_EnvVarS * sizeof(tp_Str))); for (i = 0; i < num_EnvVarS; i += 1) { Str = GetEnv(EnvVarS[i].Name); if (Str == NIL) Str = EnvVarS[i].Default; (void)sprintf(StrBuf, "%s=%s", EnvVarS[i].Name, Str); EnvVarDefS[i] = Malloc_Str(StrBuf); status = putenv(EnvVarDefS[i]); FORBIDDEN(status != 0); }/*for*/; return; }/*if*/; count = fscanf((FILE *)FilDsc, "%d\n", &num_EnvVarS); FORBIDDEN(count != 1); EnvVarDefS = (tp_Str *)malloc((unsigned)(num_EnvVarS * sizeof(tp_Str))); for (i = 0; i < num_EnvVarS; i += 1) { count = fscanf((FILE *)FilDsc, "%[^\1]\1\n", StrBuf); FORBIDDEN(count != 1); EnvVarDefS[i] = Malloc_Str(StrBuf); status = putenv(EnvVarDefS[i]); FORBIDDEN(status != 0); }/*for*/; Close(FilDsc); }/*Read_Env*/
void End_Get_OdinFile(GMC_ARG_VOID) { tp_FilHdr FilHdr; tps_FileName FileName; tp_Status Status; boolean ExecFlag, NeedsData; FORBIDDEN(Client_ToDo(CurrentClient) != NIL); FORBIDDEN(Client_Job(CurrentClient) != NIL); FilHdr = Client_FilHdr(CurrentClient); FORBIDDEN(FilHdr == NIL); ExecFlag = IsAutoExec(FilHdr); NeedsData = ExecFlag || Client_NeedsData(CurrentClient); Set_Client_FilHdr(CurrentClient, (tp_FilHdr)NIL, FALSE); (void)strcpy(FileName, ""); Status = STAT_Unknown; if (Client_Interrupted(CurrentClient)) { Set_Client_Interrupted(CurrentClient, FALSE); goto done; }/*if*/; FilHdr = Deref(FilHdr); if (FilHdr == ERROR) { goto done; }/*if*/; Status = FilHdr_MinStatus(FilHdr, IK_Trans); if (IsList(FilHdr)) { goto done; }/*if*/; if (NeedsData) { FilHdr_DataFileName(FileName, FilHdr); }/*if*/; done:; LocalEnd_Get_OdinFile(FileName, Status, ExecFlag); Ret_FilHdr(FilHdr); }/*End_Get_OdinFile*/
void Read_ENV2(GMC_ARG_VOID) { tps_FileName FileName; tp_FilDsc FilDsc; tps_Str StrBuf; tp_Str Str; int count, status; size_t sz; sz = snprintf(FileName, MAX_FileName, "%s/ENV2", OdinDirName); if (sz >= MAX_FileName) { (void)fprintf(stderr, "File name too long (MAX_FileName=%d): %s/ENV2\n", MAX_FileName, OdinDirName); exit(1); }/*if*/; FilDsc = FileName_RFilDsc(FileName, FALSE); FORBIDDEN(FilDsc == ERROR); for (count = fscanf((FILE *)FilDsc, "%[^\1]\1\n", StrBuf); count == 1; count = fscanf((FILE *)FilDsc, "%[^\1]\1\n", StrBuf)) { Str = Malloc_Str(StrBuf); status = putenv(Str); FORBIDDEN(status != 0); }/*for*/; FORBIDDEN(!EndOfFile(FilDsc)); Close(FilDsc); }/*Read_ENV2*/
GMC_DCL(tp_PrmFHdr, PrmFHdr) { FORBIDDEN(PrmFHdr == ERROR); PrmFHdr->Next = FreePrmFHdr; FORBIDDEN(!PrmFHdr->InUse); FORBIDDEN(PrmFHdr->FilHdr != NIL); PrmFHdr->InUse = FALSE; num_PrmFHdrs -= 1; FreePrmFHdr = PrmFHdr; }/*Rls_PrmFHdr*/
GMC_DCL(tp_DrvPth, DrvPth) { tp_DrvPth DrvPthElm, GroupingDrvPthElm; tp_FilTyp FilTyp; tp_FKind FKind; tp_FilPrm FilPrm, DrvFilPrm; tp_PrmTypLst PrmTypLst; tps_FileName PkgDirName; boolean NoInput_Flag=FALSE; FORBIDDEN(DrvPth == ERROR); if (FilHdr == ERROR || InhFilPrm == ERROR || PrecFilPrm == ERROR) { Ret_FilHdr(FilHdr); return ERROR; }/*if*/; FilPrm = Append_FilPrm(PrecFilPrm, InhFilPrm); GroupingDrvPthElm = (PrecFilPrm == RootFilPrm ? NIL : Find_GroupingDrvPthElm(DrvPth)); for (DrvPthElm = DrvPth; DrvPthElm != NIL; DrvPthElm = DrvPth_Next(DrvPthElm)) { switch (DrvPth_DPType(DrvPthElm)) { case DPT_Drv: { FilTyp = DrvPth_FilTyp(DrvPthElm); FKind = DrvPth_FKind(DrvPthElm); PrmTypLst = DrvPth_PrmTypLst(DrvPthElm); /*select*/{ if (IsGroupingInput_FilTyp(FilTyp)) { DrvFilPrm = FilPrm; }else if (DrvPthElm == GroupingDrvPthElm) { DrvFilPrm = Strip_FilPrm(InhFilPrm, PrmTypLst); DrvFilPrm = Append_FilPrm(PrecFilPrm, DrvFilPrm); }else{ DrvFilPrm = Strip_FilPrm(FilPrm, PrmTypLst); };}/*select*/; if (NoInput_Flag) { FORBIDDEN(FilHdr != ERROR); Get_PkgDirName(PkgDirName, Tool_Package(FilTyp_Tool(FilTyp))); FilHdr = HostFN_FilHdr(PkgDirName); NoInput_Flag = FALSE; }/*if*/; FilHdr = Get_Drv(FilHdr, FKind, FilTyp, DrvFilPrm, DfltIdent); break;}/*case*/; case DPT_Eqv: { if (DrvPth_FilTyp(DrvPthElm) == NoInputFilTyp) { Ret_FilHdr(FilHdr); FilHdr = ERROR; NoInput_Flag = TRUE; }/*if*/; break;}/*case*/; }/*switch*/; }/*for*/; return FilHdr; }/*Do_DrvPth*/
GMC_DCL(tp_Nod, Nod) { tp_Nod SonNod; int i; if (Nod == ERROR) return ERROR; FORBIDDEN(Nod == ERROR); FORBIDDEN(I <= 0); SonNod = Nod->Son; for (i=1; i<I; i++) { if (SonNod == NIL) { return NIL; }/*if*/; SonNod = SonNod->Brother; }/*for*/; return SonNod; }/*Nod_Son*/
void Init_Env(GMC_ARG_VOID) { tps_FileName FileName; boolean Abort; size_t sz; OdinDirName = GetEnv("ODINCACHE"); FORBIDDEN(OdinDirName == NIL); if (!IsDirectory_FileName(OdinDirName)) { SystemError("Odin root <%s> does not exist.\n", OdinDirName); FATALERROR("");}/*if*/; if (OdinDirName[0] != '/') { SystemError("Odin cache pathname <%s> must be absolute.\n", OdinDirName); FATALERROR("");}/*if*/; Set_ModeMask(OdinDirName); sz = snprintf(FileName, MAX_FileName, "%s/FILES", OdinDirName); if (sz >= MAX_FileName) { (void)fprintf(stderr, "File name too long (MAX_FileName=%d): %s/FILES\n", MAX_FileName, OdinDirName); exit(1); }/*if*/; CacheDirName = Malloc_Str(FileName); MakeDirFile(&Abort, CacheDirName); if (Abort) FATALERROR("cannot create odin FILES directory"); sz = snprintf(FileName, MAX_FileName, "%s/JOBS", OdinDirName); if (sz >= MAX_FileName) { (void)fprintf(stderr, "File name too long (MAX_FileName=%d): %s/JOBS\n", MAX_FileName, OdinDirName); exit(1); }/*if*/; JobsDirName = Malloc_Str(FileName); MakeDirFile(&Abort, JobsDirName); if (Abort) FATALERROR("cannot create odin JOBS directory"); sz = snprintf(FileName, MAX_FileName, "%s/ENV", OdinDirName); if (sz >= MAX_FileName) { (void)fprintf(stderr, "File name too long (MAX_FileName=%d): %s/ENV\n", MAX_FileName, OdinDirName); exit(1); }/*if*/; Read_Env(FileName); DumpCore = (GetEnv("DUMPCORE") != NIL); RBS_Cmd = GetEnv("ODIN_RBSCMD"); FORBIDDEN(RBS_Cmd == NIL); ShortCacheNameFlag = (GetEnv("ODIN_SHORTNAMES") != NIL); LocalIPCFlag = (GetEnv("ODIN_LOCALIPC") != NIL); }/*Init_Env*/
GMC_DCL(boolean, IgnoreStatus) { tp_FilPrm FilPrm; tp_FilElm FilElm; *FilHdrPtr = (tp_FilHdr)NIL; *FilPrmPtr = (tp_FilPrm)NIL; if (FilHdr == ERROR) { return; }/*if*/; if (FilHdr_Flag(FilHdr, FLAG_DeRef)) { FilHdr_Error("<%s> is circular.\n", FilHdr); Ret_FilHdr(FilHdr); return; }/*if*/; if (!(IsPntr(FilHdr) && (FilHdr_Status(FilHdr) > STAT_Error || IgnoreStatus))) { *FilHdrPtr = FilHdr; *FilPrmPtr = RootFilPrm; return; }/*if*/; FilElm = LocElm_FilElm(FilHdr_LocElm(FilHdr)); if (IgnoreStatus && FilElm == NIL) { Ret_FilHdr(FilHdr); return; }/*if*/; FORBIDDEN(!IgnoreStatus && (FilElm == NIL || FilElm_Next(FilElm) != NIL)); *FilHdrPtr = FilElm_FilHdr(FilElm); FilPrm = FilElm_FilPrm(FilElm); Ret_FilElm(FilElm); Set_Flag(FilHdr, FLAG_DeRef); Deref_Pntrs(FilHdrPtr, FilPrmPtr, *FilHdrPtr, IgnoreStatus); Clr_Flag(FilHdr, FLAG_DeRef); *FilPrmPtr = Append_FilPrm(*FilPrmPtr, FilPrm); Ret_FilHdr(FilHdr); }/*Deref_Pntrs*/
GMC_DCL(tp_Nod, Att) { FORBIDDEN(Nod == ERROR); Nod->Att = Att; if (Nod->Son != NIL) Set_All_NodAtts(Nod->Son, Att); if (Nod->Brother != NIL) Set_All_NodAtts(Nod->Brother, Att); }/*Set_All_NodAtts*/
GMC_DCL(int, Int) { int status; FORBIDDEN(FilDsc == ERROR); status = fprintf((FILE *)FilDsc, "%d", Int); if (status == EOF) SysCallError(StdOutFD, "fprintf(WriteInt)"); }/*WriteInt*/
GMC_DCL(char, ch) { int status; FORBIDDEN(FilDsc == ERROR); status = putc(ch, (FILE *)FilDsc); if (status == EOF) SysCallError(StdOutFD, "putc(Writech)"); }/*Writech*/
GMC_DCL(tp_Str, Str) { int status; FORBIDDEN(FilDsc == ERROR || Str == ERROR); status = fputs(Str, (FILE *)FilDsc); if (status == EOF) SysCallError(StdOutFD, "fputs(Write)"); }/*Write*/
GMC_DCL(tp_FilDsc, FilDsc) { int status; FORBIDDEN(FilDsc == ERROR); status = fclose((FILE *)FilDsc); if (status == EOF) SysCallError(StdOutFD, "fclose(Close)"); }/*Close*/
GMC_DCL(tp_FilDsc, FilDsc) { int status; FORBIDDEN(FilDsc == ERROR); status = fseek((FILE *)FilDsc, (long)0, 2); if (status == -1) SysCallError(StdOutFD, "fseek(Unwind)"); }/*Unwind*/
GMC_DCL(tp_Sym, Sym) { tp_StackElm StackElm; FORBIDDEN(Sym == ERROR); StackElm = New_StackElm(); StackElm->Value = (tp_Value)Sym; StackElm->Next = SymStack; SymStack = StackElm; }/*Push_SymStack*/
GMC_DCL(int, NumSons) { tp_StackElm StackElm; FORBIDDEN(NumSons < 0); StackElm = New_StackElm(); StackElm->Count = NumSons; StackElm->Next = SonStack; SonStack = StackElm; }/*Push_SonStack*/
GMC_DCL(tp_Nod, Nod) { tp_StackElm StackElm; FORBIDDEN(Nod == ERROR); StackElm = New_StackElm(); StackElm->Value = (tp_Value)Nod; StackElm->Next = NodStack; NodStack = StackElm; }/*Push_NodStack*/
GMC_DCL(tp_FilHdr, FilHdr) { FORBIDDEN(IsTargetsPtr(FilHdr)); while (!IsSource(FilHdr)) { if (IsVTgtText(FilHdr) || FilHdr_FilTyp(FilHdr) == VirTargetsFilTyp) { return FilHdr_Father(FilHdr_Father(FilHdr)); }/*if*/; if (IsVTgt(FilHdr)) { return FilHdr_Father(FilHdr_Father(FilHdr_Father(FilHdr))); }/*if*/; FilHdr = FilHdr_Father(FilHdr); }/*while*/; return FilHdr; }/*Get_BaseVTgtFilHdr*/
GMC_DCL(tp_FilDsc, InFD) { int ichar, status; FORBIDDEN(OutFD == ERROR || InFD == ERROR); ichar = getc((FILE *)InFD); while (ichar != EOF) { status = putc((char)ichar, (FILE *)OutFD); if (status == EOF) SysCallError(StdOutFD, "putc(FileCopy)"); ichar = getc((FILE *)InFD); }/*while*/; }/*FileCopy*/
GMC_DCL(int, Number) { int NumSons, i; FORBIDDEN(Number < 0); NumSons = 0; for (i=0; i<Number; i++) { NumSons = NumSons + TopOf_SonStack(); Pop_SonStack(); }/*for*/; Push_SonStack(NumSons); }/*CollectSons*/
static void Pop_SonStack(GMC_ARG_VOID) { tp_StackElm OldFreeStackElm; FORBIDDEN(SonStack == NIL); OldFreeStackElm = FreeStackElm; FreeStackElm = SonStack; SonStack = SonStack->Next; FreeStackElm->Next = OldFreeStackElm; }/*Pop_SonStack*/
GMC_DCL(tp_Nod, Nod) { tp_Nod SonNod; int NumSons; FORBIDDEN(Nod == ERROR); NumSons = 0; for (SonNod = Nod->Son; SonNod != NIL; SonNod = SonNod->Brother) { NumSons += 1; }/*for*/; return NumSons; }/*Nod_NumSons*/
GMC_DCL(tp_FilDsc, FilDsc2) { int ichar1, ichar2; FORBIDDEN(FilDsc1 == ERROR || FilDsc2 == ERROR); ichar1 = getc((FILE *)FilDsc1); ichar2 = getc((FILE *)FilDsc2); while (ichar1 == ichar2 && ichar1 != EOF) { ichar1 = getc((FILE *)FilDsc1); ichar2 = getc((FILE *)FilDsc2); }/*while*/; return (ichar1 == ichar2); }/*Equal*/
GMC_DCL(tp_FilHdr, FilHdr) { tp_FilHdr ElmFilHdr; if (FilHdr == ERROR) { return ERROR; }/*if*/; if (!IsSymLink(FilHdr) || FilHdr_Status(FilHdr) == STAT_Circular) { return FilHdr; }/*if*/; ElmFilHdr = FilHdr_ElmFilHdr(FilHdr); FORBIDDEN(IsSymLink(ElmFilHdr) || !IsSource(ElmFilHdr)); return ElmFilHdr; }/*Deref_SymLink*/
static void *doit(void *a){ FCGX_Request request; int rc; char *filename; UNUSED(a); FCGX_InitRequest(&request, 0, /* FCGI_FAIL_ACCEPT_ON_INTR */ 0); while(1){ int fd; //Some platforms require accept() serialization, some don't. The documentation claims it to be thread safe // static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; // pthread_mutex_lock(&accept_mutex); rc = FCGX_Accept_r(&request); // pthread_mutex_unlock(&accept_mutex); if(rc < 0) break; //get the filename if((filename = FCGX_GetParam("SCRIPT_FILENAME", request.envp)) == NULL){ FORBIDDEN(request.out); //don't try to open directories }else if(filename[strlen(filename)-1] == '/'){ FORBIDDEN(request.out); //open the file }else if((fd = open(filename, O_RDONLY)) == -1){ NOTFOUND(request.out, filename); //no error, serve it }else{ SENDFILE(request.out, filename); close(fd); } FCGX_Finish_r(&request); } return NULL; }
GMC_DCL(tp_FilPrm, FilPrm) { tp_PrmFHdr PrmFHdr; FORBIDDEN(FilHdr == ERROR || FilPrm == ERROR); /*select*/{ if (FreePrmFHdr == NIL) { PrmFHdr = (tp_PrmFHdr)malloc(sizeof(tps_PrmFHdr)); num_PrmFHdrS += 1; PrmFHdr->InUse = FALSE; }else{ PrmFHdr = FreePrmFHdr; FreePrmFHdr = FreePrmFHdr->Next; };}/*select*/; FORBIDDEN(PrmFHdr->InUse); num_PrmFHdrs += 1; PrmFHdr->InUse = TRUE; PrmFHdr->FilHdr = FilHdr; PrmFHdr->FilPrm = FilPrm; PrmFHdr->Next = NIL; return PrmFHdr; }/*New_PrmFHdr*/
GMC_DCL(tp_Str, Str) { int status; tp_Str StrPtr; FORBIDDEN(FilDsc == ERROR || Str == ERROR); for (StrPtr = Str; *StrPtr != 0; StrPtr++) { if (*StrPtr == '\n') { status = putc('\\', (FILE *)FilDsc); if (status == EOF) SysCallError(StdOutFD, "putc(WriteLine)"); }/*if*/; status = putc(*StrPtr, (FILE *)FilDsc); if (status == EOF) SysCallError(StdOutFD, "putc(WriteLine)"); }/*for*/; status = putc('\n', (FILE *)FilDsc); if (status == EOF) SysCallError(StdOutFD, "putc(WriteLine)"); }/*WriteLine*/
GMC_DCL(tp_Str, ValStr) { tps_Str StrBuf; int status; if (IsDef_EnvVar(VarStr)) { SystemError("Cannot change value of package variable: %s.\n", VarStr); *AbortPtr = TRUE; return; }/*if*/; (void)sprintf(StrBuf, "%s=%s", VarStr, ValStr); status = putenv(Malloc_Str(StrBuf)); FORBIDDEN(status != 0); RBS_VarDef(StrBuf); *AbortPtr = FALSE; }/*Set_HostVar*/
GMC_DCL(int, Status) { tp_Client Client; if (IsServer) { Do_ToBroadcast(); IPC_Finish(); CleanUp(); FOREACH_CLIENT(Client) { if (!Is_LocalClient(Client)) { Ret_Client(Client); }/*if*/; }/*for*/; Purge_Clients(); FORBIDDEN(!Is_LocalClient(CurrentClient)); Ret_Client(CurrentClient); Purge_Clients(); Ret_FilHdr(RootFilHdr); Ret_FilHdr(NetRootFilHdr); Ret_FilHdr(OdinDirFilHdr); Ret_FilHdr(CacheDirFilHdr); Ret_FilHdr(PrmDataDirFilHdr); Ret_FilHdr(StrDirFilHdr); Ret_FilHdr(NilStrFilHdr); Ret_FilHdr(FlagPrmFilHdr); Ret_FilHdr(EmptyFilHdr); Update_Info(); RetAbsPaths(); Free_FilHdrs(); Free_FilInps(); Free_FilElms(); Close_Info(); FORBIDDEN(PrmFHdrs_InUse()); FORBIDDEN(FilHdrs_InUse()); FORBIDDEN(FilInps_InUse()); FORBIDDEN(FilElms_InUse()); }/*if*/; exit(Status); }/*Exit*/
GMC_DCL(boolean, NeedsData) { tp_Nod Root; tp_PrmFHdr PrmFHdr; tp_FilHdr FilHdr; tp_FilPrm FilPrm; boolean AllDone; Root = YY_Parser(OdinExpr, (tp_FileName)NIL, (int *)NIL); FORBIDDEN(Root == ERROR); PrmFHdr = Nod_PrmFHdr(Root); Ret_Nod(Root); Use_PrmFHdr(&FilHdr, &FilPrm, PrmFHdr); if (FilHdr == ERROR) { LocalEnd_Get_OdinFile("", STAT_Unknown, FALSE); return; }/*if*/; Set_Client_FilHdr(CurrentClient, FilHdr, NeedsData); Push_AllReqs(&AllDone); Ret_FilHdr(FilHdr); IsAny_ReadyServerAction = TRUE; }/*Local_Get_OdinFile*/