/* ** Parse a text URI into an HtmlUri structure. */ static HtmlUri *ParseUri(const char *zUri){ HtmlUri *p; int n; p = HtmlAlloc( sizeof(*p) ); if( p==0 ) return 0; memset(p, 0, sizeof(*p)); if( zUri==0 || zUri[0]==0 ) return p; while( isspace(zUri[0]) ){ zUri++; } n = ComponentLength(zUri, "", ":/?# "); if( n>0 && zUri[n]==':' ){ p->zScheme = StrNDup(zUri, n); zUri += n+1; } n = ComponentLength(zUri, "//", "/?# "); if( n>0 ){ p->zAuthority = StrNDup(&zUri[2], n-2); zUri += n; } n = ComponentLength(zUri, "", "?# "); if( n>0 ){ p->zPath = StrNDup(zUri, n); zUri += n; } n = ComponentLength(zUri, "?", "# "); if( n>0 ){ p->zQuery = StrNDup(&zUri[1], n-1); zUri += n; } n = ComponentLength(zUri, "#", " "); if( n>0 ){ p->zFragment = StrNDup(&zUri[1], n-1); } return p; }
INLINE STRPTR GetTaskName( struct Task *task, UWORD *namelen ) { struct Process *pr = (struct Process *) task; STRPTR name = NULL; // ENTER(); // DBG_POINTER(task); #define b2c(x) ( x << 2 ) /* BPTR to C string */ if(namelen) (*namelen) = 0; if (task->tc_Node.ln_Type == NT_PROCESS && pr->pr_CLI != (BPTR)NULL) { struct CommandLineInterface *cli = (struct CommandLineInterface *)BADDR(pr->pr_CLI); if(cli && cli->cli_Module && cli->cli_CommandName) { STRPTR bn = (STRPTR) b2c(cli->cli_CommandName); if(*bn > 0) { if((name = StrNDup( &bn[1], *bn ))) { if(namelen) (*namelen) = *bn; } } } } if( name == NULL ) { UWORD len = strlen(task->tc_Node.ln_Name); if((name = StrNDup(task->tc_Node.ln_Name, len ))) { if(namelen) (*namelen) = len; } } // DBG_STRING(name); // RETURN(name); return(name); }
/* ** Replace the string in *pzDest with the string in zSrc */ static void ReplaceStr(char **pzDest, const char *zSrc){ if( *pzDest!=0 ) HtmlFree(*pzDest); if( zSrc==0 ){ *pzDest = 0; }else{ *pzDest = StrNDup(zSrc, -1); } }
static void addServers( char **srv, int bType ) { char *name, *class2; const char *dtx, *cls; struct display *d; for (; *srv; srv++) { if ((cls = strchr( *srv, '_' ))) { if (!StrNDup( &name, *srv, cls - *srv )) return; if (!StrDup( &class2, cls )) { free( name ); return; } } else { if (!StrDup( &name, *srv )) return; class2 = 0; } if ((d = FindDisplayByName( name ))) { if (d->class2) free( d->class2 ); dtx = "existing"; } else { if (!(d = NewDisplay( name ))) { free( name ); if (class2) free( class2 ); return; } dtx = "new"; } d->stillThere = 1; d->class2 = class2; d->displayType = (*name == ':' ? dLocal : dForeign) | bType; if ((bType & d_lifetime) == dReserve) { if (d->status == notRunning) d->status = reserve; } else { if (d->status == reserve) d->status = notRunning; } Debug( "found %s %s%s display: %s %s\n", dtx, ((d->displayType & d_location) == dLocal) ? "local" : "foreign", ((d->displayType & d_lifetime) == dReserve) ? " reserve" : "", d->name, d->class2 ); free( name ); } }
/** extract filename between '`' and "'" * Make v4.0 changed this: the first separator is now "'" */ static char* targetName(const char* line) { char* p; char* b=strchr(line,'`'); if(b==NULL) b=strchr(line,'\'');//GNU make 4.0 char* e=( b==NULL ? NULL : strchr(b+1,'\'') ); if(b==NULL || e==NULL || b>e) { fprintf(stderr,"Cannot get target name in \"%s\".\n",line); exit(EXIT_FAILURE); } p= StrNDup(b+1,(e-b)-1); if(p==NULL) OUT_OF_MEMORY; return p; }
static bool ParsePair(ParserT *parser, JsonPairT *pair) { TokenT *string = ParserMatch(parser, TOK_STRING); if (!string) { parser->errmsg = "string expected"; return false; } if (!ParserMatch(parser, TOK_COLON)) { parser->errmsg = "':' expected"; return false; } if (!ParseValue(parser, &pair->value)) return false; pair->key = StrNDup(string->value + 1, string->size - 2); return true; }
INLINE STRPTR StrDup( STRPTR string ) { return( StrNDup ( string, (ULONG) strlen( string ) + 1 )); }
int main( int argc, char **argv ) { int oldpid, oldumask, fd, noDaemonMode; char *pt, *errorLogFile, **opts; /* make sure at least world write access is disabled */ if (((oldumask = umask( 022 )) & 002) == 002) (void)umask( oldumask ); /* give /dev/null as stdin */ if ((fd = open( "/dev/null", O_RDONLY )) > 0) { dup2( fd, 0 ); close( fd ); } if (fcntl( 1, F_GETFD ) < 0) dup2( 0, 1 ); if (fcntl( 2, F_GETFD ) < 0) dup2( 0, 2 ); if (argv[0][0] == '/') { if (!StrDup( &progpath, argv[0] )) Panic( "Out of memory" ); } else #ifdef __linux__ { /* note that this will resolve symlinks ... */ int len; char fullpath[PATH_MAX]; if ((len = readlink( "/proc/self/exe", fullpath, sizeof(fullpath) )) < 0) Panic( "Invoke with full path specification or mount /proc" ); if (!StrNDup( &progpath, fullpath, len )) Panic( "Out of memory" ); } #else # if 0 Panic( "Must be invoked with full path specification" ); # else { char directory[PATH_MAX+1]; if (!getcwd( directory, sizeof(directory) )) Panic( "Can't find myself (getcwd failed)" ); if (strchr( argv[0], '/' )) StrApp( &progpath, directory, "/", argv[0], (char *)0 ); else { int len; char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1]; if (!(path = getenv( "PATH" ))) Panic( "Can't find myself (no PATH)" ); len = strlen( argv[0] ); name = nambuf + PATH_MAX - len; memcpy( name, argv[0], len + 1 ); *--name = '/'; do { if (!(pathe = strchr( path, ':' ))) pathe = path + strlen( path ); len = pathe - path; if (!len || (len == 1 && *path == '.')) { len = strlen( directory ); path = directory; } thenam = name - len; if (thenam >= nambuf) { memcpy( thenam, path, len ); if (!access( thenam, X_OK )) goto found; } path = pathe; } while (*path++ != '\0'); Panic( "Can't find myself (not in PATH)" ); found: if (!StrDup( &progpath, thenam )) Panic( "Out of memory" ); } } # endif #endif prog = strrchr( progpath, '/' ) + 1; #if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE) Title = argv[0]; TitleLen = (argv[argc - 1] + strlen( argv[argc - 1] )) - Title; #endif /* * Parse command line options */ noDaemonMode = getppid(); errorLogFile = 0; if (!(opts = Malloc( 2 * sizeof(char *) ))) return 1; opts[0] = (char *)""; opts[1] = 0; while (*++argv) { if (**argv != '-') break; pt = *argv + 1; if (*pt == '-') pt++; if (!strcmp( pt, "help" ) || !strcmp( pt, "h" )) { printf( "Usage: %s [options] [tty]\n" " -daemon\t - Daemonize even when started by init\n" " -nodaemon\t - Don't daemonize even when started from command line\n" " -config <file> - Use alternative master configuration file\n" " -xrm <res>\t - Override frontend-specific resource\n" " -error <file>\t - Use alternative log file\n" " -debug <num>\t - Debug option bitfield:\n" "\t\t\t0x1 - core log\n" "\t\t\t0x2 - config reader log\n" "\t\t\t0x4 - greeter log\n" "\t\t\t0x8 - IPC log\n" "\t\t\t0x10 - session sub-daemon post-fork delay\n" "\t\t\t0x20 - config reader post-start delay\n" "\t\t\t0x40 - greeter post-start delay\n" "\t\t\t0x80 - don't use syslog\n" "\t\t\t0x100 - core Xauth log\n" "\t\t\t0x400 - valgrind config reader and greeter\n" "\t\t\t0x800 - strace config reader and greeter\n" , prog ); exit( 0 ); } else if (!strcmp( pt, "daemon" )) noDaemonMode = 0; else if (!strcmp( pt, "nodaemon" )) noDaemonMode = 1; else if (argv[1] && !strcmp( pt, "config" )) StrDup( opts, *++argv ); else if (argv[1] && !strcmp( pt, "xrm" )) opts = addStrArr( opts, *++argv, -1 ); else if (argv[1] && !strcmp( pt, "debug" )) sscanf( *++argv, "%i", &debugLevel ); else if (argv[1] && (!strcmp( pt, "error" ) || !strcmp( pt, "logfile" ))) errorLogFile = *++argv; else { fprintf( stderr, "\"%s\" is an unknown option or is missing a parameter\n", *argv ); exit( 1 ); } } /* * Only allow root to run in non-debug mode to avoid problems */ if (!debugLevel && getuid()) { fprintf( stderr, "Only root wants to run %s\n", prog ); exit( 1 ); } InitErrorLog( errorLogFile ); if (noDaemonMode != 1) BecomeDaemon(); /* * Step 1 - load configuration parameters */ if (!InitResources( opts ) || ScanConfigs( FALSE ) < 0) LogPanic( "Config reader failed. Aborting ...\n" ); /* SUPPRESS 560 */ if ((oldpid = StorePid())) { if (oldpid == -1) LogError( "Can't create/lock pid file %s\n", pidFile ); else LogError( "Can't lock pid file %s, another xdm is running (pid %d)\n", pidFile, oldpid ); exit( 1 ); } #ifdef NEED_ENTROPY AddOtherEntropy(); #endif /* * We used to clean up old authorization files here. As authDir is * supposed to be /var/run/xauth or /tmp, we needn't to care for it. */ #ifdef XDMCP init_session_id(); #else Debug( "not compiled for XDMCP\n" ); #endif if (pipe( signalFds )) LogPanic( "Unable to create signal notification pipe.\n" ); RegisterInput( signalFds[0] ); RegisterCloseOnFork( signalFds[0] ); RegisterCloseOnFork( signalFds[1] ); (void)Signal( SIGTERM, SigHandler ); (void)Signal( SIGINT, SigHandler ); (void)Signal( SIGHUP, SigHandler ); (void)Signal( SIGCHLD, SigHandler ); (void)Signal( SIGUSR1, SigHandler ); /* * Step 2 - run a sub-daemon for each entry */ #ifdef XDMCP UpdateListenSockets(); #endif openCtrl( 0 ); MainLoop(); closeCtrl( 0 ); if (sdRec.how) { commitBootOption(); if (Fork() <= 0) { char *cmd = sdRec.how == SHUT_HALT ? cmdHalt : cmdReboot; execute( parseArgs( (char **)0, cmd ), (char **)0 ); LogError( "Failed to execute shutdown command %\"s\n", cmd ); exit( 1 ); } else { sigset_t mask; sigemptyset( &mask ); sigaddset( &mask, SIGCHLD ); sigaddset( &mask, SIGHUP ); sigsuspend( &mask ); } } Debug( "nothing left to do, exiting\n" ); return 0; }
// ------------------------------------------------------------------------ bool S4::Interpreter::NextWord(S4::Lexeme *lexeme) { lexeme->kind = Lexeme::endOfInput; while (isspace(*programCounter)) { programCounter++; } if (*programCounter) { const char *startOfLexeme = programCounter; if (*programCounter == '\'' || *programCounter == '"' || *programCounter == '`') { char quote = *(programCounter++); int escapedQuotes = 0; int escapedChars = 0; while (*programCounter) { if (programCounter[0] == quote) { if (programCounter[1] == quote) { escapedQuotes = 1; programCounter += 2; continue; } else if (!programCounter[1] || isspace(programCounter[1])) { // end of text break; } } else if (programCounter[0] == '\\') { escapedChars = 1; } programCounter++; } lexeme->kind = Lexeme::text; // don't include the quotes in the copy // if (*programCounter == quote) { // advance past the closing quote before the copy programCounter++; lexeme->data.text = StrNDup(startOfLexeme + 1, (programCounter - 1) - (startOfLexeme + 1)); } else { // unterminated string, sigh lexeme->data.text = StrNDup(startOfLexeme + 1, programCounter - (startOfLexeme + 1)); } // TODO: combine quotes and backslash logic // if (escapedQuotes) { char *src = lexeme->data.text; while (*src && !(src[0] == quote && src[1] == quote)) { src++; } char *dst = src; while (*src) { if (src[0] == quote && src[1] == quote) { src++; *(dst++) = *(src++); } else { *(dst++) = *(src++); } } *dst = 0; } if (escapedChars) { char *src = lexeme->data.text; while (*src && *src != '\\') { src++; } char *dst = src; while (*src) { if (*src != '\\') { *(dst++) = *(src++); } else { switch (*(++src)) { // inspired by C strings case 0: // never escape null bytes (or quotes for that matter) break; case '0': // \0 is a null byte in the string *(dst++) = 0; src++; break; case 'n': // \n is a newline *(dst++) = '\n'; src++; break; case 'r': // \r is a carriage return *(dst++) = '\r'; src++; break; case 't': // \t is a tab *(dst++) = '\t'; src++; break; default: *(dst++) = *(src++); break; } } } *dst = 0; } return lexeme; } if (isdigit(programCounter[0]) || ((programCounter[0] == '-' || programCounter[1] == '+') && isdigit(programCounter[1]))) { do { programCounter++; } while (isdigit(programCounter[0])); if (isspace(*programCounter) || !*programCounter) { lexeme->kind = Lexeme::integer; lexeme->data.integer = atoi(startOfLexeme); return lexeme; } if (programCounter[0] == '.' && isdigit(programCounter[1])) { do { programCounter++; } while (isdigit(programCounter[0])); if (isspace(*programCounter) || !*programCounter) { lexeme->kind = Lexeme::number; lexeme->data.number = strtod(startOfLexeme, 0); return lexeme; } } } while (*programCounter && !isspace(*programCounter)) { programCounter++; } lexeme->kind = Lexeme::symbol; lexeme->data.symbol = StrNDup(startOfLexeme, programCounter - startOfLexeme); return lexeme; } lexeme->kind = Lexeme::endOfInput; return false; }
static LONG PathWalk(Global_T *g, UBYTE *FullName, LONG FullNameLen, UBYTE *LinkPath, /* Buf to get result into, IN/OUTPUT name of LINK */ ULONG BufLen, /* length of buf above */ LONG *Res2) /* OUTPUT */ { UBYTE *PComp; /* points to current path component */ UBYTE *WorkPath = NULL; DCEntry *ParDir, *ActDir; NEntry *ActNEnt; ACEntry *ACE; LONG LastElement = 0; /* flag: if set, last element of directory is found */ /* (init important !) */ LONG Pos = 0; /* fn_ScanPath needs this as buffer */ /* (init important !) */ LONG Res = 1; D(DBF_ALWAYS, "\tPathWalk(\"%s\")", FullName); WorkPath = StrNDup(FullName, FullNameLen); /* we will modify WorkPath */ if(!WorkPath) { *Res2 = ERROR_NO_FREE_STORE; Res = 0; } else { /* get (cached) root handle */ ParDir = GetDirEntry(g, NULL, /* no name entry */ g->g_MntAttr.fileid, &g->g_MntFh, NULL, /* currently not used */ Res2); if(ParDir) { if(FullNameLen) /* Filename != "" */ { do { PComp = fn_ScanPath(WorkPath, FullNameLen, &Pos, &LastElement); ASSERT(PComp); D(DBF_ALWAYS,"\tPComp = \"%s\"", PComp); if(*PComp == '/') /* goto parent dir, not allowed in this version, must be unified path ! */ { E(DBF_ALWAYS, "FIXME: *** parent dir reference not allowed !!"); Res = 0; break; } ActNEnt = GetNameEntry(g, ParDir, PComp, &ACE, Res2); if(!ActNEnt) { Res = 0; break; } if((ActNEnt->ne_FType != NFDIR) && (ActNEnt->ne_FType != NFLNK)) { *Res2 = ERROR_INVALID_COMPONENT_NAME; Res = 0; break; } if(ActNEnt->ne_FType == NFLNK) { nfspath u_lpath; ASSERT(ACE); ASSERT(LinkPath); u_lpath = nfs_ReadLink(g->g_NFSClnt, &ACE->ace_NFSFh, Res2); if(u_lpath) { D(DBF_ALWAYS,"\treadlink returned: %s", u_lpath); #if 0 if(UseUnixLinks(g)) ; #endif if(fn_InsertLink(LinkPath, BufLen, g->g_VolumeName, FullName, PComp-WorkPath, strlen(PComp), u_lpath, Res2) == NULL) { if(*Res2 == ERROR_NO_FREE_STORE) Res = -1; else Res = 0; } else Res = 2; } else { Res = 0; } break; } /* note: GetDirEntry will modify ActNEnt if necessary */ ActDir = GetDirEntry(g, ActNEnt, DCE_ID_UNUSED, &ACE->ace_NFSFh, PComp, Res2); ParDir = ActDir; } while(!LastElement && ParDir); } else { /* filename: "" */ LinkPath[0] = 0; Res = 1; } } else Res = 0; fn_Delete(&WorkPath); } return Res; }
int StrDup(char **dst, const char *src) { return StrNDup(dst, src, -1); }
void Load_Inputs_Src_List (void) { int i; char w[256]; t_input_src * input_src = NULL; t_tfile * tf; t_list * lines; int line_cnt; // Open and read file ConsolePrint (Msg_Get (MSG_Inputs_Src_Loading)); tf = tfile_read (Inputs.FileName); if (tf == NULL) Quit_Msg (meka_strerror()); ConsolePrint ("\n"); // Parse each line line_cnt = 0; for (lines = tf->data_lines; lines; lines = lines->next) { char *line; line_cnt += 1; line = lines->elem; if (StrNull(line)) continue; if (line[0] == '[' && line[strlen(line) - 1] == ']') { input_src = Inputs_Sources_Add (StrNDup (line + 1, strlen(line) - 2)); // ConsolePrintf ("new source --> %s <--\n", CurSrc->Name); continue; } strlwr(line); if (!parse_getword(w, sizeof(w), &line, "=", ';', PARSE_FLAGS_NONE)) continue; for (i = 0; Inputs_Src_List_KeyWords[i]; i++) if (strcmp(w, Inputs_Src_List_KeyWords[i]) == 0) { // FIXME: this is ugly if (input_src == NULL && strcmp (w, "joy_driver") != 0 && strcmp (w, "mouse_speed_x") != 0 && strcmp (w, "mouse_speed_y") != 0 && strcmp (w, "cabinet_mode") != 0) { tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Missing), line_cnt); } parse_skip_spaces(&line); if (!parse_getword(w, sizeof(w), &line, "", ';', PARSE_FLAGS_NONE)) { tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Equal), line_cnt); } switch (Load_Inputs_Src_Parse_Var(i, w, input_src)) { case MEKA_ERR_SYNTAX: tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Syntax_Param), line_cnt); case MEKA_ERR_INCOHERENT : tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Inconsistency), line_cnt); break; // FIXME: EMPTY is not handled there } break; } if (!Inputs_Src_List_KeyWords [i]) { tfile_free(tf); Quit_Msg (Msg_Get (MSG_Inputs_Src_Unrecognized), line_cnt, w); } } // Free file data tfile_free(tf); // Verify that we have enough inputs sources if (Inputs.Sources_Max == 0) Quit_Msg (Msg_Get (MSG_Inputs_Src_Not_Enough)); }
static void manage(struct sockaddr *from, int fromlen, int length, int fd) { CARD32 sessionID; CARD16 displayNumber; ARRAY8 displayClass; int expectlen; struct protoDisplay *pdpy; struct display *d; char *name = NULL; char *class2 = NULL; XdmcpNetaddr from_save; ARRAY8 clientAddress, clientPort; CARD16 connectionType; Debug("<manage> %d\n", length); displayClass.data = 0; displayClass.length = 0; if(XdmcpReadCARD32(&buffer, &sessionID) && XdmcpReadCARD16(&buffer, &displayNumber) && XdmcpReadARRAY8(&buffer, &displayClass)) { expectlen = 4 + /* session ID */ 2 + /* displayNumber */ 2 + displayClass.length; /* displayClass */ if(expectlen != length) { Debug("<manage> length error got %d expect %d\n", length, expectlen); goto abort; } pdpy = FindProtoDisplay((XdmcpNetaddr)from, fromlen, displayNumber); Debug("<manage> session ID %ld, pdpy %p\n", (long)sessionID, pdpy); if(!pdpy || pdpy->sessionID != sessionID) { /* * We may have already started a session for this display * but it hasn't seen the response in the form of an * XOpenDisplay() yet. So check if it is in the list of active * displays, and if so check that the session id's match. * If all this is true, then we have a duplicate request that * can be ignored. */ if(!pdpy && (d = FindDisplayByAddress((XdmcpNetaddr)from, fromlen, displayNumber)) && d->sessionID == sessionID) { Debug("manage: got duplicate pkt, ignoring\n"); goto abort; } Debug("session ID %ld refused\n", (long)sessionID); if(pdpy) Debug("existing session ID %ld\n", (long)pdpy->sessionID); send_refuse(from, fromlen, sessionID, fd); } else { name = NetworkAddressToName(pdpy->connectionType, &pdpy->connectionAddress, from, pdpy->displayNumber); if(!name) { Debug("could not compute display name\n"); send_failed(from, fromlen, "(no name)", sessionID, "out of memory", fd); goto abort; } Debug("computed display name: %s\n", name); if((d = FindDisplayByName(name))) { Debug("terminating active session for %s\n", d->name); StopDisplay(d); } if(displayClass.length) { if(!StrNDup(&class2, (char *)displayClass.data, displayClass.length)) { send_failed(from, fromlen, name, sessionID, "out of memory", fd); goto abort; } } if(!(from_save = (XdmcpNetaddr)Malloc(fromlen))) { send_failed(from, fromlen, name, sessionID, "out of memory", fd); goto abort; } memmove(from_save, from, fromlen); if(!(d = NewDisplay(name))) { free((char *)from_save); send_failed(from, fromlen, name, sessionID, "out of memory", fd); goto abort; } d->class2 = class2; class2 = 0; d->displayType = dForeign | dTransient | dFromXDMCP; d->sessionID = pdpy->sessionID; d->from.data = (unsigned char *)from_save; d->from.length = fromlen; d->displayNumber = pdpy->displayNumber; ClientAddress(from, &clientAddress, &clientPort, &connectionType); d->useChooser = 0; d->xdmcpFd = fd; if(IsIndirectClient(&clientAddress, connectionType)) { Debug("IsIndirectClient\n"); ForgetIndirectClient(&clientAddress, connectionType); if(UseChooser(&clientAddress, connectionType)) { d->useChooser = 1; Debug("use chooser for %s\n", d->name); } } d->clientAddr = clientAddress; d->connectionType = connectionType; d->remoteHost = NetworkAddressToHostname(pdpy->connectionType, &pdpy->connectionAddress); XdmcpDisposeARRAY8(&clientPort); if(pdpy->fileAuthorization) { d->authorizations = (Xauth **)Malloc(sizeof(Xauth *)); if(!d->authorizations) { free((char *)from_save); free((char *)d); send_failed(from, fromlen, name, sessionID, "out of memory", fd); goto abort; } d->authorizations[0] = pdpy->fileAuthorization; d->authNum = 1; pdpy->fileAuthorization = 0; } DisposeProtoDisplay(pdpy); Debug("starting display %s,%s\n", d->name, d->class2); if(LoadDisplayResources(d) < 0) { LogError( "Unable to read configuration for display %s; " "stopping it.\n", d->name); StopDisplay(d); } else StartDisplay(d); CloseGetter(); } } abort: XdmcpDisposeARRAY8(&displayClass); if(name) free((char *)name); if(class2) free((char *)class2); }