static /* deallocates a note and */ void freenote(Note *n) { /* its pfield lists */ freeps(n->p); freeps(n->carryp); free((char *) n); }
static void getDfltSrv(char **pdfltSrv) { *pdfltSrv = realloc(*pdfltSrv, theSrv ? strlen(theSrv)+1 : DFLT_SRV_LEN); if ( theSrv ) { strcpy(*pdfltSrv, theSrv); } else { if ( !inet_ntop( AF_INET, &BOOTPSA, *pdfltSrv, DFLT_SRV_LEN ) ) { freeps(pdfltSrv); } } }
static int rshCopy(char **pDfltSrv, char *pathspec, char **pFnam) { int fd = -1, ed = -1, tmpfd = -1, maxfd, got; fd_set r,w,e; struct timeval timeout; int rval = -1; fd = isRshPath( pDfltSrv, pathspec, &ed, 0 ); if ( fd < 0 ) { rval = fd; goto cleanup; } assert( !*pFnam ); *pFnam = strdup("/tmp/rshcpyXXXXXX"); if ( (tmpfd=mkstemp(*pFnam)) < 0 ) { perror("rshCopy() -- creating scratch file"); goto cleanup; } while ( fd >= 0 || ed >= 0 ) { FD_ZERO( &r ); FD_ZERO( &w ); FD_ZERO( &e ); timeout.tv_sec = 5; timeout.tv_usec = 0; maxfd = 0; if ( fd >= 0 ) { FD_SET( fd, &r ); if ( fd > maxfd ) maxfd = fd; } if ( ed >= 0 ) { FD_SET( ed, &r ); if ( ed > maxfd ) maxfd = ed; } maxfd++; got = select(maxfd, &r, &w, &e, &timeout); if ( got <= 0 ) { if ( got ) perror("rshCopy() network select() error"); else fprintf(stderr,"rshCopy() network select() timeout\n"); goto cleanup; } if ( ed >= 0 && FD_ISSET( ed, &r ) ) { if ( cpfd( &ed, 2 ) < 0 ) { perror(" error file descriptor"); goto cleanup; } } if ( fd >= 0 && FD_ISSET( fd, &r ) ) { if ( cpfd( &fd, tmpfd ) < 0 ) { perror(" temp file descriptor"); goto cleanup; } } } rval = tmpfd; tmpfd = -1; cleanup: if ( ed >= 0 ) close(ed); if ( fd >= 0 ) close(fd); if ( tmpfd >= 0 ) { close(tmpfd); unlink( *pFnam ); } if ( rval < 0 ) freeps(pFnam); return rval; }
rtems_task Init( rtems_task_argument ignored ) { GetLine *gl = 0; char *symf = 0, *sysscr=0, *user_script=0, *bufp; int argc = 0; int result = 0; int no_net = 0; char *dfltSrv = 0; char *pathspec = 0; #ifdef NFS_SUPPORT MntDescRec bootmnt = { "/boot", 0, 0 }; MntDescRec homemnt = { "/home", 0, 0 }; #endif char *argv[7]={ "Cexp", /* program name */ 0, 0, 0, 0 }; rtems_libio_set_private_env(); #ifdef HAVE_PCIBIOS #if RTEMS_VERSION_ATLEAST(4,6,99) pci_initialize(); #else pcib_init(); #endif #endif #ifdef STACK_CHECKER_ON { extern void Stack_check_Initialize(); Stack_check_Initialize(); } #endif #ifdef HAVE_LIBBSPEXT bspExtInit(); #endif /* make /tmp directory */ mkTmpDir(); printf("Welcome to RTEMS GeSys\n"); printf("This system $Name: GeSys_2_4 $ was built on %s\n",system_build_date); printf("$Id: init.c,v 1.43 2008/03/22 20:36:13 guest Exp $\n"); #ifdef EARLY_CMDLINE_GET { char *cmdlinetmp; EARLY_CMDLINE_GET(&cmdlinetmp); #ifdef HAVE_LIBNETBOOT /* Let libnetboot process the command line string; all * special name=value pairs recognized by libnetboot will * be removed... */ nvramFixupBsdnetConfig(1, cmdlinetmp); #endif cmdlinePairExtract(cmdlinetmp, putenv, 1); } #endif #if defined(USE_TECLA) /* * Install our special line discipline which implements * TIOCGWINSZ */ printf("Installing TIOCGWINSZ line discipline: %s.\n", ansiTiocGwinszInstall(7) ? "failed" : "ok"); #endif /* * Make sure the time-of-day clock is at least initialized. * The dummy routine just sets the date to 1/1/2000 */ dummy_clock_init(); cexpInit(cexpExcHandlerInstall); printf("To skip initialization, press a key now..."); fflush(stdout); if ( getchar_timeout(fileno(stdin),10) > 0 ) { printf("OK; skipping to shell"); no_net = 1; argc = 1; } printf("\n"); #ifndef CDROM_IMAGE #ifndef SKIP_NETINI #define SKIP_NETINI getenv("SKIP_NETINI") #endif /* check if we have a real ifconfig (first is loopback) */ if ( !no_net && (! (SKIP_NETINI) || !BUILTIN_SYMTAB) && rtems_bsdnet_config.ifconfig ) { gesys_network_start(); } else { fprintf(stderr,"Skipping network initialization - you can do it manually\n"); fprintf(stderr,"by invoking 'gesys_network_start()' (needs BOOTP/DHCP server)\n"); argc = 1; no_net = 1; } #endif #ifndef CDROM_IMAGE if ( BOOTPFN ) { char *slash,*dot; pathspec = malloc(strlen(BOOTPFN) + (BUILTIN_SYMTAB ? strlen(SYSSCRIPT) : strlen(SYMEXT)) + 1); strcpy(pathspec, BOOTPFN); slash = strrchr(pathspec,'/'); if ( BUILTIN_SYMTAB ) { if ( slash ) strcpy(slash+1,SYSSCRIPT); else strcpy(pathspec,SYSSCRIPT); } else { dot = strrchr(pathspec,'.'); if (slash>dot) dot=0; /* substitute suffix */ if (dot) { strcpy(dot,SYMEXT); } else { strcat(pathspec,SYMEXT); } } } { char *tarvar; void *addr; int len; if ( (tarvar=getenv("TARFS")) && 2 == sscanf(tarvar,"%p:%i",&addr,&len) && len > 0 ) { mkdir("/tar",0777); rtems_tarfs_load("/tar",addr,len); } } #else { extern void *gesys_tarfs_image_start; extern unsigned long gesys_tarfs_image_size; printf("Loading TARFS... %s\n", rtems_tarfs_load("/tmp", gesys_tarfs_image_start, gesys_tarfs_image_size) ? "FAILED" : "OK"); pathspec=strdup(BUILTIN_SYMTAB ? "/tmp/"SYSSCRIPT : "/tmp/rtems.sym"); } #endif dflt_fname = "rtems.sym"; #ifdef TFTP_SUPPORT path_prefix = strdup("/TFTP/BOOTP_HOST/"); #elif defined(NFS_SUPPORT) path_prefix = strdup(":/remote/rtems:"); #elif defined(RSH_SUPPORT) path_prefix = strdup("~rtems/"); #endif getDfltSrv(&dfltSrv); #ifdef PSIM { extern int loadTarImg(int verbose, int lun); if ( !pathspec ) { loadTarImg(1, 0); pathspec = strdup("/bin/"SYSSCRIPT); } else { fprintf(stderr,"PSIM: root tarfs not loaded (pathspec was '%s')\n",pathspec); } } #endif if ( no_net && ( !pathspec || LOCAL_PATH != pathType(pathspec) ) ) goto shell_entry; /* omit prompting for the symbol file */ if ( pathspec ) goto firstTimeEntry; /* no pathspec but a builtin symtab -> * skip reading symtab / system script */ if ( BUILTIN_SYMTAB ) goto bare_entry; do { chdir("/"); #ifdef NFS_SUPPORT if ( releaseMount( &bootmnt ) ) { fprintf(stderr,"Unable to unmount /boot NFS - don't know what to do, sorry\n"); break; } #endif freeps(&symf); freeps(&user_script); if (!gl) { assert( gl = new_GetLine(LINE_LENGTH, 10*LINE_LENGTH) ); /* silence warnings about missing .teclarc */ gl_configure_getline(gl,0,0,0); } do { printf("Symbol file can be loaded by:\n"); #ifdef NFS_SUPPORT printf(" NFS: [<uid>.<gid>@][<host>]:<export_path>:<symfile_path>\n"); #endif #ifdef TFTP_SUPPORT printf(" TFTP: [/TFTP/<host_ip>]<symfile_path>\n"); #endif #ifdef RSH_SUPPORT printf(" RSH: [<host>:]~<user>/<symfile_path>\n"); #endif #ifdef USE_TECLA bufp = gl_get_line(gl, "Enter Symbol File Name: ", pathspec, ( pathspec && *pathspec ) ? strlen(pathspec) : 0 ); #else bufp = my_getline(gl, "Enter Symbol File Name: ", LINE_LENGTH); #endif } while (!bufp || !*bufp); pathspec = realloc(pathspec, strlen(bufp) + 1); strcpy(pathspec, bufp); bufp = pathspec + strlen(bufp) - 1; while ( bufp >= pathspec && ('\n' == *bufp || '\r' == *bufp) ) *bufp-- = 0; firstTimeEntry: { int fd = -1, ed = -1; char *slash; getDfltSrv( &dfltSrv ); #ifdef TFTP_SUPPORT chdir("/TFTP/BOOTP_HOST/"); #endif switch ( pathType(pathspec) ) { case LOCAL_PATH: fd = open(pathspec,O_RDONLY); if ( fd >= 0 ) symf = strdup(pathspec); break; #ifdef TFTP_SUPPORT case TFTP_PATH: fd = isTftpPath( &dfltSrv, pathspec, &ed, &symf ); break; #endif #ifdef NFS_SUPPORT case NFS_PATH: fd = isNfsPath( &dfltSrv, pathspec, &ed, &symf, &bootmnt ); break; #endif #ifdef RSH_SUPPORT case RSH_PATH: fd = rshCopy( &dfltSrv, pathspec, &symf ); break; #endif default: fprintf(stderr,"Unrecognized pathspec; maybe remote FS support is not compiled in ?\n"); break; } if ( 0==result && dfltSrv ) { /* allow the default server to be overridden by the pathspec * during the first pass (original pathspec from boot) */ theSrv = strdup(dfltSrv); } if ( (fd < 0) && !BUILTIN_SYMTAB ) { fprintf(stderr,"Unable to open symbol file (%s)\n", -11 == fd ? "not a valid pathspec" : strerror(errno)); continue; } if ( fd >= 0 ) close(fd); if ( ed >= 0 ) close(ed); freeps( &sysscr ); sysscr = strdup(SYSSCRIPT); #if defined(RSH_SUPPORT) && !defined(CDROM_IMAGE) if ( !ISONTMP(symf) ) { #endif if ( (slash = strrchr(symf,'/')) ) { int ch=*(slash+1); *(slash+1)=0; printf("Change Dir to '%s'",symf); if ( chdir(symf) ) printf(" FAILED: %s",strerror(errno)); fputc('\n',stdout); *(slash+1)=ch; } #if defined(RSH_SUPPORT) && !defined(CDROM_IMAGE) } else { char *scrspec = malloc( strlen(pathspec) + strlen(SYSSCRIPT) + 1); strcpy(scrspec, pathspec); if ( (slash = strrchr(scrspec, '/')) ) strcpy( slash+1, SYSSCRIPT ); else strcpy( scrspec, SYSSCRIPT ); getDfltSrv( &dfltSrv ); freeps( &sysscr ); if ( (fd = rshCopy( &dfltSrv, scrspec, &sysscr )) >= 0 ) { close( fd ); } else { freeps( &sysscr ); } freeps(&scrspec); } #endif bare_entry: printf("Trying symfile '%s', system script '%s'\n", BUILTIN_SYMTAB ? "BUILTIN" : symf, sysscr ? sysscr :"(NONE)"); argc = 1; #ifdef DEFAULT_CPU_ARCH_FOR_CEXP if ( DEFAULT_CPU_ARCH_FOR_CEXP && *DEFAULT_CPU_ARCH_FOR_CEXP ) { argv[argc++] = "-a"; argv[argc++] = DEFAULT_CPU_ARCH_FOR_CEXP; } #endif if ( !BUILTIN_SYMTAB ) { argv[argc++] = "-s"; argv[argc++] = symf; } if ( sysscr ) { argv[argc++] = sysscr; } shell_entry: result = argc > 1 ? cexp_main(argc, argv) : 0; if ( ISONTMP( symf ) ) unlink( symf ); if ( sysscr && ISONTMP( sysscr ) ) unlink( sysscr ); freeps(&symf); freeps(&sysscr); if (!result || CEXP_MAIN_NO_SCRIPT==result) { int rc; if (gl) { del_GetLine(gl); gl = 0; } freeps(&pathspec); /* try a user script */ if ((user_script=getenv("INIT"))) { printf("Trying user script '%s':\n",user_script); pathspec = strdup(user_script); user_script = 0; getDfltSrv(&dfltSrv); switch ( pathType( pathspec ) ) { #ifdef NFS_SUPPORT case NFS_PATH: if ( 0 == (rc = isNfsPath( &dfltSrv, pathspec, 0, &user_script, &homemnt ) ) ) { /* valid NFS path; try to mount; */ if ( !bootmnt.uidhost || strcmp( homemnt.uidhost, bootmnt.uidhost ) || !bootmnt.rpath || strcmp( homemnt.rpath , bootmnt.rpath ) ) rc = nfsMount(homemnt.uidhost, homemnt.rpath, homemnt.mntpt); } break; #endif case RSH_PATH: fprintf(stderr,"RSH download of user scripts is not supported\n"); rc = -1; break; #ifdef TFTP_SUPPORT case TFTP_PATH: rc = isTftpPath( &dfltSrv, pathspec, 0, &user_script ); break; #endif case LOCAL_PATH: /* they might refer to a path on the local FS (already mounted NFS) */ user_script = pathspec; pathspec = 0; rc = 0; break; default: fprintf(stderr,"Invalid path specifier; support for remote FS not compiled in?\n"); rc = -1; break; } freeps(&pathspec); argc = 2; if ( rc ) { fprintf(stderr,"Unable to determine filesystem for user script\n"); freeps(&user_script); argc = 1; } else { if ((slash = strrchr(user_script,'/'))) { /* chdir to where the user script resides */ int ch=*(++slash); *(slash)=0; printf("Change Dir to '%s'\n",user_script); chdir(user_script); *(slash)=ch; argv[1]=slash; } else { argv[1]=user_script; } } argc=2; } else { argc=1; } do { result=cexp_main(argc,argv); argc=1; freeps(&user_script); } while (!result || CEXP_MAIN_NO_SCRIPT==result); chdir("/"); #ifdef NFS_SUPPORT releaseMount( &homemnt ); #endif } } switch (result) { case CEXP_MAIN_NO_SYMS : fprintf(stderr,"CEXP_MAIN_NO_SYMS\n"); result = 0; break; case CEXP_MAIN_INVAL_ARG: fprintf(stderr,"CEXP_MAIN_INVAL_ARG\n"); break; case CEXP_MAIN_NO_SCRIPT: fprintf(stderr,"CEXP_MAIN_NO_SCRIPT\n"); break; case CEXP_MAIN_KILLED : fprintf(stderr,"CEXP_MAIN_KILLED\n"); break; case CEXP_MAIN_NO_MEM : fprintf(stderr,"CEXP_MAIN_NO_MEM\n"); break; default: if (result) fprintf(stderr,"unknown error\n"); } } while ( !result ); /* retry asking for a sym-filename */ if (gl) { del_GetLine(gl); gl = 0; } fprintf(stderr,"Unable to execute CEXP - suspending initialization...\n"); rtems_task_suspend(RTEMS_SELF); exit( 1 ); }