/** * Programme principal */ int main ( int argc, char *argv[] ) { /* exemples d'utilisation des macros du fichier notify.h */ INFO_MSG("Un message INFO_MSG : Debut du programme %s", argv[0]); /* macro INFO_MSG */ WARNING_MSG("Un message WARNING_MSG !"); /* macro INFO_MSG */ DEBUG_MSG("Un message DEBUG_MSG !"); /* macro DEBUG_MSG : uniquement si compil en mode DEBUG_MSG */ FILE *fp = NULL; /* le flux dans lequel les commandes seront lues : stdin (mode shell) ou un fichier */ if ( argc > 2 ) { usage_ERROR_MSG( argv[0] ); exit( EXIT_FAILURE ); } if(argc == 2 && strcmp(argv[1], "-h") == 0) { usage_ERROR_MSG( argv[0] ); exit( EXIT_SUCCESS ); } /*par defaut : mode shell interactif */ fp = stdin; if(argc == 2) { /* mode fichier de commandes */ fp = fopen( argv[1], "r" ); if ( fp == NULL ) { perror( "fopen" ); exit( EXIT_FAILURE ); } } /* boucle principale : lit puis execute une cmd en boucle */ while ( 1 ) { char input[MAX_STR]; if ( acquire_line( fp, input ) == 0 ) { /* Une nouvelle ligne a ete acquise dans le flux fp*/ int res = parse_and_execute_cmd_string(input); /* execution de la commande */ switch(res) { case CMD_OK_RETURN_VALUE: /* tout s'est bien passé */ break; case CMD_EMPTY_RETURN_VALUE: /* commande vide */ /* rien a faire ! */ break; case CMD_EXIT_RETURN_VALUE: /* sortie propre du programme */ if ( fp != stdin ) { fclose( fp ); } exit(EXIT_SUCCESS); break; default: /* erreur durant l'execution de la commande */ /* En mode "fichier" toute erreur implique la fin du programme ! */ if ( fp != stdin ) { fclose( fp ); /*macro ERROR_MSG : message d'erreur puis fin de programme ! */ ERROR_MSG("ERREUR DETECTEE. Aborts"); } break; } } if( fp != stdin && feof(fp) ) { /* mode fichier, fin de fichier => sortie propre du programme */ DEBUG_MSG("FIN DE FICHIER"); fclose( fp ); exit(EXIT_SUCCESS); } } /* tous les cas de sortie du programme sont gérés plus haut*/ ERROR_MSG("SHOULD NEVER BE HERE\n"); }
int main(int argc, char **argv) { int option; while ((option = getopt(argc, argv, "ace:fhlnr:s:u:zLK:O:S:")) != -1) { switch (option) { case 'a': slflags |= IFF_LINK2; slflags &= ~IFF_LINK0; break; case 'c': slflags |= IFF_LINK0; slflags &= ~IFF_LINK2; break; case 'e': exit_cmd = (char*) strdup (optarg); break; case 'f': foreground = 1; break; case 'h': flow_control |= CRTSCTS; break; case 'l': modem_control = CLOCAL; /* clear HUPCL too */ break; case 'n': slflags |= IFF_LINK1; break; case 'r': redial_cmd = (char*) strdup (optarg); break; case 's': speed = atoi(optarg); break; case 'u': config_cmd = (char*) strdup (optarg); break; case 'z': redial_on_startup = 1; break; case 'L': uucp_lock = 1; break; case 'K': keepal = atoi(optarg); break; case 'O': outfill = atoi(optarg); break; case 'S': sl_unit = atoi(optarg); break; case '?': default: usage(); exit_handler(1); } } if (optind == argc - 1) dev = argv[optind]; if (optind < (argc - 1)) warnx("too many args, first='%s'", argv[optind]); if (optind > (argc - 1)) warnx("not enough args"); if (dev == NULL) { usage(); exit_handler(2); } if (strncmp(_PATH_DEV, dev, sizeof(_PATH_DEV) - 1)) { strcpy(tty_path, _PATH_DEV); strcat(tty_path, "/"); strncat(tty_path, dev, 10); dev = tty_path; } dvname = strrchr(dev, '/'); /* always succeeds */ dvname++; /* trailing tty pathname component */ snprintf(pidfilename, sizeof(pidfilename), "%sslattach.%s.pid", _PATH_VARRUN, dvname); printf("%s\n",pidfilename); if (!foreground) daemon(0,0); /* fork, setsid, chdir /, and close std*. */ /* daemon() closed stderr, so log errors from here on. */ openlog("slattach",LOG_CONS|LOG_PID,LOG_DAEMON); acquire_line(); /* get tty device as controlling terminal */ setup_line(0); /* configure for slip line discipline */ slip_discipline(); /* switch to slip line discipline */ /* upon INT log a timestamp and exit. */ if (signal(SIGINT,sigint_handler) == SIG_ERR) syslog(LOG_NOTICE,"cannot install SIGINT handler: %m"); /* upon TERM log a timestamp and exit. */ if (signal(SIGTERM,sigterm_handler) == SIG_ERR) syslog(LOG_NOTICE,"cannot install SIGTERM handler: %m"); /* upon HUP redial and reconnect. */ if (signal(SIGHUP,sighup_handler) == SIG_ERR) syslog(LOG_NOTICE,"cannot install SIGHUP handler: %m"); if (redial_on_startup) sighup_handler(0); else if (!(modem_control & CLOCAL)) { if (ioctl(fd, TIOCMGET, &comstate) < 0) syslog(LOG_NOTICE,"cannot get carrier state: %m"); if (!(comstate & TIOCM_CD)) { /* check for carrier */ /* force a redial if no carrier */ kill (getpid(), SIGHUP); } else configure_network(); } else configure_network(); /* configure the network if needed. */ for (;;) { sigset_t mask; sigemptyset(&mask); sigsuspend(&mask); } }
/* sighup_handler() is invoked when carrier drops, eg. before redial. */ static void sighup_handler(int signo __unused) { if(exiting) return; if (redial_cmd == NULL) { syslog(LOG_NOTICE,"SIGHUP on %s (sl%d); exiting", dev, unit); exit_handler(1); } again: /* invoke a shell for redial_cmd or punt. */ if (*redial_cmd) { /* Non-empty redial command */ syslog(LOG_NOTICE,"SIGHUP on %s (sl%d); running '%s'", dev, unit, redial_cmd); acquire_line(); /* reopen dead line */ setup_line(CLOCAL); if (locked) { if (uucp_lock) uu_unlock(dvname); /* for redial */ locked = 0; } if (system(redial_cmd)) goto again; if (uucp_lock) { int res; if ((res = uu_lock(dvname)) != UU_LOCK_OK) { if (res != UU_LOCK_INUSE) syslog(LOG_ERR, "uu_lock: %s", uu_lockerr(res)); syslog(LOG_ERR, "can't relock %s after %s, aborting", dev, redial_cmd); exit_handler(1); } locked = 1; } /* Now check again for carrier (dial command is done): */ if (!(modem_control & CLOCAL)) { tty.c_cflag &= ~CLOCAL; if (tcsetattr(fd, TCSAFLUSH, &tty) < 0) { syslog(LOG_ERR, "tcsetattr(TCSAFLUSH): %m"); exit_handler(1); } ioctl(fd, TIOCMGET, &comstate); if (!(comstate & TIOCM_CD)) { /* check for carrier */ /* force a redial if no carrier */ goto again; } } else setup_line(0); } else { /* Empty redial command */ syslog(LOG_NOTICE,"SIGHUP on %s (sl%d); reestablish connection", dev, unit); acquire_line(); /* reopen dead line */ setup_line(0); /* restore ospeed from hangup (B0) */ /* If modem control, just wait for carrier before attaching. If no modem control, just fall through immediately. */ if (!(modem_control & CLOCAL)) { int carrier = 0; syslog(LOG_NOTICE, "waiting for carrier on %s (sl%d)", dev, unit); /* Now wait for carrier before attaching line. */ /* We must poll since CLOCAL prevents signal. */ while (! carrier) { sleep(2); ioctl(fd, TIOCMGET, &comstate); if (comstate & TIOCM_CD) carrier = 1; } syslog(LOG_NOTICE, "carrier now present on %s (sl%d)", dev, unit); } } slip_discipline(); configure_network(); }
/** * Programme principal */ int main ( int argc, char *argv[] ) { /* exemples d'utilisation des macros du fichier notify.h */ INFO_MSG("Debut du programme %s", argv[0]); /* macro INFO_MSG */ interpreteur inter=init_inter(); /* structure gardant les infos et états de l'interpreteur*/ FILE *fp = NULL; /* le flux dans lequel les commande seront lues : stdin (mode shell) ou un fichier */ registre r=NULL; r = registre_new(35); mem memory = NULL; setRegisterValue(r,31,0xff7ff000); if ( argc > 2 ) { usage_ERROR_MSG( argv[0] ); exit( EXIT_FAILURE ); } if(argc == 2 && strcmp(argv[1], "-h") == 0) { usage_ERROR_MSG( argv[0] ); exit( EXIT_SUCCESS ); } /*par defaut : mode shell interactif */ fp = stdin; inter->mode = INTERACTIF; if(argc == 2) { /* mode fichier de commandes */ fp = fopen( argv[1], "r" ); if ( fp == NULL ) { perror( "fopen" ); exit( EXIT_FAILURE ); } inter->mode = SCRIPT; } bp bpi=NULL; /* boucle infinie : lit puis execute une cmd en boucle */ while ( 1 ) { if (acquire_line( fp, inter) == 0 ) { /* Une nouvelle ligne a ete acquise dans le flux fp*/ int res = execute_cmd(inter,r,&memory,&bpi); /* execution de la commande */ // traitement des erreurs switch(res) { case CMD_OK_RETURN_VALUE: break; case CMD_EXIT_RETURN_VALUE: /* sortie propre du programme */ if ( fp != stdin ) { fclose( fp ); } del_inter(inter); registre_del(r); del_mem(memory); exit(EXIT_SUCCESS); break; default: /* erreur durant l'execution de la commande */ /* En mode "fichier" toute erreur implique la fin du programme ! */ if (inter->mode == SCRIPT) { fclose( fp ); del_inter(inter); registre_del(r); del_mem(memory); /*macro ERROR_MSG : message d'erreur puis fin de programme ! */ ERROR_MSG("ERREUR DETECTEE. Aborts"); } break; } } if( inter->mode == SCRIPT && feof(fp) ) { /* mode fichier, fin de fichier => sortie propre du programme */ DEBUG_MSG("FIN DE FICHIER"); fclose( fp ); del_inter(inter); registre_del(r); del_mem(memory); exit(EXIT_SUCCESS); } } /* tous les cas de sortie du programme sont gérés plus haut*/ ERROR_MSG("SHOULD NEVER BE HERE\n"); }