00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "nufw_source.h"
00025
00026 #include <config.h>
00027 #include "../lib/nuclient.h"
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032 #include <errno.h>
00033 #include <locale.h>
00034 #include <sys/resource.h>
00035 #include <langinfo.h>
00036 #include <stdarg.h>
00037 #include <signal.h>
00038 #include <sys/ioctl.h>
00039 #include <sys/stat.h>
00040 #include <sys/types.h>
00041 #include <termios.h>
00042 #include "proto.h"
00043 #include "security.h"
00044 #include "debug.h"
00045 #define NUTCPC_VERSION PACKAGE_VERSION " $Revision: 5287 $"
00046
00047 #ifdef FREEBSD
00048 #include <sys/syslimits.h>
00049 #include <readpassphrase.h>
00050 #endif
00051
00052 #define MAX_RETRY_TIME 30
00053
00054 #include <nubase.h>
00055 #include <nussl.h>
00056
00057 struct termios orig;
00058 nuauth_session_t *session = NULL;
00059 nuclient_error_t *err = NULL;
00060 struct sigaction old_sigterm;
00061 struct sigaction old_sigint;
00062 int forced_reconnect = 0;
00063 int connected;
00064 static int suppress_ca_warning = 0;
00065 static int suppress_fqdn_verif = 0;
00066
00067 void panic(const char *fmt, ...)
00068 #ifdef __GNUC__
00069 __attribute__((__format__(printf,1,2)))
00070 #endif
00071 ;
00072
00073 typedef struct {
00074 char port[10];
00075 unsigned long interval;
00076 unsigned char donotuselock;
00077 char srv_addr[512];
00078 char password[100];
00079 char nuauthdn[512];
00080 unsigned char debug_mode;
00081 int tempo;
00082 char *certfile;
00083 char *keyfile;
00084 char *cafile;
00085 char *crlfile;
00086 char *pkcs12file;
00087 char *pkcs12password;
00088 char *krb5_service;
00089 } nutcpc_context_t;
00090
00095 void panic(const char *fmt, ...)
00096 {
00097 va_list args;
00098 va_start(args, fmt);
00099 printf("\n");
00100 printf("Fatal error: ");
00101 vprintf(fmt, args);
00102 printf("\n");
00103 fflush(stdout);
00104 exit(EXIT_FAILURE);
00105 va_end(args);
00106 }
00107
00111 char *compute_run_pid()
00112 {
00113 char path_dir[254];
00114 char *home = nu_get_home_dir();
00115 if (home == NULL)
00116 return NULL;
00117 secure_snprintf(path_dir, sizeof(path_dir), "%s/.nufw", home);
00118 if (access(path_dir, R_OK) != 0) {
00119 printf("Creating directory \"%s\"\n", path_dir);
00120 if (mkdir(path_dir, S_IRWXU) != 0) {
00121 printf("Could not create directory \"%s\" (%s)\n", path_dir, strerror(errno));
00122 }
00123 }
00124 secure_snprintf(path_dir, sizeof(path_dir), "%s/.nufw/nutcpc", home);
00125 free(home);
00126 return strdup(path_dir);
00127 }
00128
00132 int test_nutcpc(pid_t *pid)
00133 {
00134 FILE *fd;
00135 int ok = EXIT_FAILURE;
00136 char *runpid = compute_run_pid();
00137
00138 if (runpid) {
00139 fd = fopen(runpid, "r");
00140 if (fd) {
00141 fscanf(fd, "%d", pid);
00142 fclose(fd);
00144 ok = EXIT_SUCCESS;
00145 }
00146 free(runpid);
00147 }
00148 return ok;
00149 }
00150
00157 void kill_nutcpc()
00158 {
00159 pid_t pid;
00160
00161 if (test_nutcpc(&pid) == EXIT_SUCCESS) {
00162 int ret;
00163 char *runpid = compute_run_pid();
00164 ret = kill(pid, SIGTERM);
00165 if (ret == 0) {
00166 printf("nutcpc process killed (pid %lu)\n",
00167 (unsigned long) pid);
00168 unlink(runpid);
00169 free(runpid);
00170 exit(EXIT_SUCCESS);
00171 } else {
00172 switch (errno) {
00173 case ESRCH:
00174 printf("Process does not exist: removing pid file\n");
00175 unlink(runpid);
00176 break;
00177 case EINVAL:
00178 case EPERM:
00179 default:
00180 printf("Bad return from kill\n");
00181 }
00182 free(runpid);
00183 exit(EXIT_FAILURE);
00184 }
00185 } else {
00186 printf("No nutcpc seems to be running\n");
00187 exit(EXIT_FAILURE);
00188 }
00189 exit(EXIT_SUCCESS);
00190 }
00191
00200 void leave_client()
00201 {
00202 char *runpid;
00203 struct termios term;
00204
00205
00206 if (tcgetattr(fileno(stdin), &term) == 0) {
00207 term.c_lflag |= ECHO;
00208 (void) tcsetattr(fileno(stdin), TCSAFLUSH, &term);
00209 }
00210
00211 if (session) {
00212 nu_client_delete(session);
00213 }
00214
00215 runpid = compute_run_pid();
00216 if (runpid != NULL) {
00217 unlink(runpid);
00218 free(runpid);
00219 }
00220 nu_client_global_deinit();
00221 nu_client_error_destroy(err);
00222 }
00223
00230 void exit_clean()
00231 {
00232
00233 (void) sigaction(SIGINT, &old_sigint, NULL);
00234 (void) sigaction(SIGTERM, &old_sigterm, NULL);
00235
00236
00237 printf("\nQuit client\n");
00238 leave_client();
00239 exit(EXIT_SUCCESS);
00240 }
00241
00242 #ifdef FREEBSD
00243 ssize_t getline(char **lineptr, size_t * n, FILE * stream)
00244 {
00245 char *line;
00246 size_t len;
00247
00248
00249 line = fgetln(stream, &len);
00250 if (!line)
00251 return -1;
00252
00253
00254 if (len >= *n) {
00255 char *tmp = realloc(*lineptr, len + 1);
00256 if (tmp == NULL) {
00257 printf("Not enough memory\n");
00258 return -1;
00259 }
00260 *lineptr = tmp;
00261 *n = len + 1;
00262 }
00263 memcpy(*lineptr, line, len);
00264 (*lineptr)[len] = 0;
00265 return len;
00266 }
00267 #endif
00268
00269 #ifndef FREEBSD
00270
00278 ssize_t my_getpass(char **lineptr, size_t * linelen)
00279 {
00280 struct termios new;
00281 int nread;
00282
00283
00284 if (tcgetattr(fileno(stdin), &orig) != 0)
00285 return -1;
00286 new = orig;
00287 new.c_lflag &= ~ECHO;
00288 if (tcsetattr(fileno(stdin), TCSAFLUSH, &new) != 0)
00289 return -1;
00290
00291
00292 nread = getline(lineptr, linelen, stdin);
00293
00294
00295 (void) tcsetattr(fileno(stdin), TCSAFLUSH, &orig);
00296
00297
00298 if (0 < nread) {
00299 char *line = *lineptr;
00300 if (line[nread - 1] == '\n') {
00301 line[nread - 1] = '\0';
00302 nread--;
00303 }
00304 }
00305 printf("\n");
00306 return nread;
00307 }
00308 #endif
00309
00316 char *get_password()
00317 {
00318 size_t password_size = 32;
00319 char *new_pass;
00320 char *question = "Enter password: ";
00321 #ifdef FREEBSD
00322 char *ret;
00323 #else
00324 int ret;
00325 #endif
00326
00327 new_pass = (char *) calloc(password_size, sizeof(char));
00328 #ifdef FREEBSD
00329 ret =
00330 readpassphrase(question, new_pass, password_size,
00331 RPP_REQUIRE_TTY);
00332 if (ret == NULL) {
00333 fprintf(stderr, "unable to read passphrase");
00334 }
00335 #else
00336 printf("%s", question);
00337 ret = my_getpass(&new_pass, &password_size);
00338 if (ret < 0) {
00339 free(new_pass);
00340 printf("Problem when getting password\n");
00341 return NULL;
00342 }
00343 #endif
00344 return new_pass;
00345 }
00346
00353 char *get_username()
00354 {
00355 char *username;
00356 int nread;
00357 size_t username_size = 32;
00358
00359 printf("Enter username: ");
00360 username = (char *) calloc(username_size, sizeof(char));
00361 nread = getline(&username, &username_size, stdin);
00362 if (nread < 0) {
00363 free(username);
00364 printf("Problem when reading username\n");
00365 return NULL;
00366 }
00367 if (0 < nread && username[nread - 1] == '\n') {
00368 username[nread - 1] = 0;
00369 }
00370 return username;
00371 }
00372
00376 static void usage(void)
00377 {
00378 fprintf(stderr, "usage: nutcpc -U username -H host\n");
00379 fprintf(stderr, "\n");
00380 fprintf(stderr, "Options:\n");
00381 fprintf(stderr, " -k: kill active client\n");
00382 fprintf(stderr, " -c: check if there is an active client\n");
00383 fprintf(stderr, " -l: don't create lock file\n");
00384 fprintf(stderr, " -V: display version\n");
00385 fprintf(stderr, "\n");
00386 fprintf(stderr, "Certificate options:\n");
00387 fprintf(stderr, " -C CERTFILE: PEM certificate filename\n");
00388 fprintf(stderr, " -A AUTHFILE: PEM authority certificate filename\n");
00389 fprintf(stderr, " -K KEYFILE: PEM RSA private key filename\n");
00390 fprintf(stderr, " -S PKCS12FILE: PKCS12 key/certificate filename\n");
00391 fprintf(stderr, " -W PKCS12PASS: PKCS12 password\n");
00392 fprintf(stderr, " -R CRLFILE: crl filename\n");
00393 fprintf(stderr, " -Q: suppress warning if no certificate authority is configured\n");
00394 fprintf(stderr, " -N: suppress error if server FQDN does not match certificate CN.\n");
00395 fprintf(stderr, "\n");
00396 fprintf(stderr, "SASL options:\n");
00397 fprintf(stderr, " -Z SERVICE: Kerberos service name (nuauth)\n");
00398 fprintf(stderr, "\n");
00399 fprintf(stderr, "Other options:\n");
00400 fprintf(stderr, " -p PORT: nuauth port number\n");
00401 fprintf(stderr, " -a AUTH_DN: authentication domain name\n");
00402 fprintf(stderr, " -I INTERVAL: check interval in milliseconds\n");
00403 fprintf(stderr, " -q: do not display running nutcpc options on \"ps\"\n");
00404 fprintf(stderr, " -P PASSWORD: specify password (only for debug purpose)\n");
00405 fprintf(stderr, " -d: debug mode (don't go to foreground, daemon)\n");
00406 fprintf(stderr, "\n");
00407 exit(EXIT_FAILURE);
00408 }
00409
00410 void process_hup(int signum)
00411 {
00412 forced_reconnect = 1;
00413 nu_client_reset(session);
00414 connected = 0;
00415 }
00416
00422 void install_signals()
00423 {
00424 struct sigaction action;
00425 action.sa_handler = exit_clean;
00426 sigemptyset(&(action.sa_mask));
00427 action.sa_flags = 0;
00428
00429
00430 if (sigaction(SIGINT, &action, &old_sigint) != 0) {
00431 fprintf(stderr, "Unable to install SIGINT signal handler!\n");
00432 exit(EXIT_FAILURE);
00433 }
00434 if (sigaction(SIGTERM, &action, &old_sigterm) != 0) {
00435 fprintf(stderr, "Unable to install SIGTERM signal handler!\n");
00436 exit(EXIT_FAILURE);
00437 }
00438 memset(&action, 0, sizeof(action));
00439 action.sa_handler = &process_hup;
00440 action.sa_flags = SIGHUP;
00441
00442 if (sigaction(SIGHUP, &action, NULL) != 0)
00443 {
00444 fprintf(stderr, "Warning : Unable to install SIGHUP signal handler!\n");
00445 }
00446 }
00447
00451 void daemonize_process(nutcpc_context_t * context, char *runpid)
00452 {
00453 pid_t p;
00454
00455
00456 p = fork();
00457 if (p < 0) {
00458 fprintf(stderr, "nutcpc: fork failure: %s\n",
00459 strerror(errno));
00460 exit(EXIT_FAILURE);
00461 }
00462
00463
00464 if (p != 0) {
00465 exit(0);
00466 }
00467
00468
00469 p = fork();
00470 if (p < 0) {
00471 fprintf(stderr, "nutcpc: fork falure: %s\n",
00472 strerror(errno));
00473 exit(EXIT_FAILURE);
00474 }
00475
00476
00477 if (p != 0) {
00478 fprintf(stderr, "nutcpc started (pid %d)\n", (int) p);
00479 if (context->donotuselock == 0) {
00480 FILE *RunD;
00481 RunD = fopen(runpid, "w");
00482 free(runpid);
00483 fprintf(RunD, "%d", p);
00484 fclose(RunD);
00485 }
00486 exit(EXIT_SUCCESS);
00487 }
00488
00489
00490
00491 setsid();
00492 (void) chdir("/");
00493 ioctl(STDIN_FILENO, TIOCNOTTY, NULL);
00494 (void) close(STDIN_FILENO);
00495 (void) close(STDOUT_FILENO);
00496 (void) close(STDERR_FILENO);
00497 setpgid(0, 0);
00498 }
00499
00500 void wipe(void *data, size_t datalen)
00501 {
00502 memset(data, 0, datalen);
00503 }
00504
00509 void display_cert(nuauth_session_t* session)
00510 {
00511 char* infos = nu_client_get_cert_infos(session);
00512 printf("User certificate:\n%s\n", infos ? infos : "None");
00513 free(infos);
00514 infos = nu_client_get_server_cert_infos(session);
00515 printf("Server certificate:\n%s\n", infos ? infos : "None");
00516 free(infos);
00517 }
00518
00519
00525 nuauth_session_t *do_connect(nutcpc_context_t * context, char *username)
00526 {
00527 nuauth_session_t *session;
00528
00529 session = nu_client_new_callback(get_username, get_password, 1, err);
00530 if (session == NULL) {
00531 printf("Problem during session callback init\n");
00532 return NULL;
00533 }
00534
00535 if (username) {
00536 nu_client_set_username(session, username);
00537 free(username);
00538 }
00539 if (context->password[0] != 0) {
00540 nu_client_set_password(session, context->password);
00541 }
00542
00543 nu_client_set_debug(session, context->debug_mode);
00544
00545
00546 if(*context->port == '\0')
00547 {
00548 if(nu_client_default_port())
00549 SECURE_STRNCPY(context->port, nu_client_default_port(),
00550 sizeof(context->port));
00551 else
00552 SECURE_STRNCPY(context->port, USERPCKT_SERVICE,
00553 sizeof(context->port));
00554 }
00555
00556 if(*context->srv_addr == '\0')
00557 {
00558 if(nu_client_default_hostname())
00559 SECURE_STRNCPY(context->srv_addr, nu_client_default_hostname(),
00560 sizeof(context->srv_addr));
00561 else
00562 SECURE_STRNCPY(context->srv_addr, NUAUTH_IP,
00563 sizeof(context->srv_addr));
00564 }
00565
00566 if (context->pkcs12file) {
00567 if (!nu_client_set_pkcs12(session, context->pkcs12file, context->pkcs12password, err)) {
00568 goto init_failed;
00569 }
00570 }
00571 else {
00572 if (!nu_client_set_key(session, context->keyfile, context->certfile, err)) {
00573 goto init_failed;
00574 }
00575 }
00576
00577 if (!nu_client_set_ca(session, context->cafile, err)) {
00578 goto init_failed;
00579 }
00580
00581 nu_client_set_ca_suppress_warning(session,suppress_ca_warning);
00582 if (suppress_fqdn_verif)
00583 nu_client_set_fqdn_suppress_verif(session, 1);
00584
00585 if (context->nuauthdn) {
00586 if (!nu_client_set_nuauth_cert_dn(session,
00587 context->nuauthdn,
00588 err)) {
00589 goto init_failed;
00590 }
00591 }
00592
00593 if (!context->crlfile)
00594 context->crlfile = (char *)nu_client_default_tls_crl();
00595 if (context->crlfile) {
00596 if (!nu_client_set_crlfile(session, context->crlfile, err)) {
00597 goto init_failed;
00598 }
00599 }
00600
00601 if (context->krb5_service) {
00602 if (!nu_client_set_krb5_service(session, context->krb5_service)) {
00603 nu_client_delete(session);
00604 fprintf(stderr, "Unable to setup Kerberos5 service\n");
00605 return NULL;
00606 }
00607 }
00608
00609 if (!nu_client_connect(session, context->srv_addr, context->port, err)) {
00610 goto init_failed;
00611 }
00612 return session;
00613 init_failed:
00614
00615 printf("Initialization error: %s\n", nu_client_strerror(session, err));
00616 nu_client_delete(session);
00617 return NULL;
00618 }
00619
00623 void main_loop(nutcpc_context_t * context)
00624 {
00625 int connected = 1;
00626 int ret;
00627 for (;;) {
00628 if (!connected) {
00629 if (forced_reconnect == 0) {
00630 usleep((unsigned long) context->tempo * 1000000);
00631 } else {
00632 context->tempo = 1;
00633 forced_reconnect = 0;
00634 }
00635 if (context->tempo < MAX_RETRY_TIME) {
00636 context->tempo *= 2;
00637 }
00638
00639
00640 if (nu_client_connect
00641 (session, context->srv_addr, context->port,
00642 err) != 0) {
00643 connected = 1;
00644 context->tempo = 1;
00645 } else {
00646 printf("Reconnection error: %s\n",
00647 nu_client_strerror(session, err));
00648 nu_client_reset(session);
00649 }
00650 } else {
00651 forced_reconnect = 0;
00652 ret = nu_client_check(session, err);
00653 if (ret < 0) {
00654
00655 nu_client_reset(session);
00656 connected = 0;
00657 printf("%s\n", nu_client_strerror(session, err));
00658 }
00659 }
00660 }
00661 }
00662
00669 char* copy_filename(char* name)
00670 {
00671 char cwd[PATH_MAX];
00672 char buffer[PATH_MAX];
00673 int ok;
00674 char* ret;
00675 if (name[0] != '/') {
00676 ret = getcwd(cwd, sizeof(cwd));
00677 if (!ret) {
00678 printf("Unable to get current working directory\n");
00679 return NULL;
00680 }
00681 ok = secure_snprintf(buffer, sizeof(buffer), "%s/%s", cwd, name);
00682 if (!ok) {
00683 printf("Unable to copy filename\n");
00684 return NULL;
00685 }
00686 RETURN_NO_LOG strdup(buffer);
00687 } else {
00688 RETURN_NO_LOG strdup(name);
00689 }
00690 }
00691
00695 void parse_cmdline_options(int argc, char **argv,
00696 nutcpc_context_t * context, char **username)
00697 {
00698 int ch;
00699 int index;
00700 int stealth = 0;
00701
00702
00703 context->interval = 100;
00704 context->donotuselock = 0;
00705 context->debug_mode = 0;
00706 context->tempo = 1;
00707
00708
00709 opterr = 0;
00710 while ((ch = getopt(argc, argv, "kcldqNQVu:H:I:U:p:P:a:K:C:A:R:W:S:Z:")) != -1) {
00711 switch (ch) {
00712 case 'H':
00713 SECURE_STRNCPY(context->srv_addr, optarg,
00714 sizeof(context->srv_addr));
00715 break;
00716 case 'P':
00717 SECURE_STRNCPY(context->password, optarg,
00718 sizeof(context->password));
00719 stealth = 1;
00720 break;
00721 case 'd':
00722 context->debug_mode = 1;
00723 break;
00724 case 'I':
00725 context->interval = atoi(optarg);
00726 if (context->interval == 0) {
00727 fprintf(stderr, "nutcpc: bad interval\n");
00728 exit(EXIT_FAILURE);
00729 }
00730 break;
00731 case 'l':
00732 context->donotuselock = 1;
00733 break;
00734 case 'U':
00735 *username = strdup(optarg);
00736 break;
00737 case 'c': {
00738 pid_t pid;
00739 if (test_nutcpc(&pid) == EXIT_SUCCESS) {
00740 printf("nutcpc already running (pid %u)\n",
00741 pid);
00742 exit(EXIT_SUCCESS);
00743 }
00744 printf("No running nutcpc\n");
00745 exit(EXIT_FAILURE);
00746 }
00747 break;
00748 case 'k':
00749 kill_nutcpc();
00750 break;
00751 case 'V':
00752 printf("nutcpc (version " NUTCPC_VERSION ")\n");
00753 exit(0);
00754 case 'p':
00755 SECURE_STRNCPY(context->port, optarg,
00756 sizeof(context->port));
00757 break;
00758 case 'q':
00759 stealth = 1;
00760 break;
00761 case 'N':
00762 suppress_fqdn_verif = 1;
00763 break;
00764 case 'Q':
00765 suppress_ca_warning = 1;
00766 break;
00767 case 'a':
00768 SECURE_STRNCPY(context->nuauthdn, optarg,
00769 sizeof(context->nuauthdn));
00770 break;
00771 case 'C':
00772 context->certfile = copy_filename(optarg);
00773 break;
00774 case 'K':
00775 context->keyfile = copy_filename(optarg);
00776 break;
00777 case 'A':
00778 context->cafile = copy_filename(optarg);
00779 break;
00780 case 'R':
00781 context->crlfile = copy_filename(optarg);
00782 break;
00783 case 'S':
00784 context->pkcs12file = copy_filename(optarg);
00785 break;
00786 case 'W':
00787 context->pkcs12password = strdup(optarg);
00788 break;
00789 case 'Z':
00790 context->krb5_service = strdup(optarg);
00791 break;
00792 default:
00793 usage();
00794 }
00795 }
00796 if (context->password[0] != 0 && !context->debug_mode) {
00797 fprintf(stderr,
00798 "Don't use -P option outside debugging, it's not safe!\n");
00799 exit(EXIT_FAILURE);
00800 }
00801
00802 if ((context->keyfile || context->certfile) && (context->pkcs12file || context->pkcs12password))
00803 {
00804 fprintf(stderr, "Don't mix PKCS12 options with X509/RSA options.\n");
00805 exit(EXIT_FAILURE);
00806 }
00807
00808
00809 if (stealth == 1) {
00810 for (index = argc; 1 < index; index--) {
00811 memset(argv[index - 1], '\0',
00812 strlen(argv[index - 1]));
00813 }
00814 }
00815 }
00816
00820 void init_library(nutcpc_context_t * context, char *username)
00821 {
00822 struct rlimit core_limit;
00823
00824
00825 if (!context->debug_mode && getrlimit(RLIMIT_CORE, &core_limit) == 0) {
00826 core_limit.rlim_cur = 0;
00827 setrlimit(RLIMIT_CORE, &core_limit);
00828 }
00829
00830
00831 if (nu_client_error_init(&err) != 0) {
00832 printf("Cannot init error structure!\n");
00833 exit(EXIT_FAILURE);
00834 }
00835
00836
00837 if (!nu_client_global_init(err)) {
00838 printf("Unable to initiate nuclient library!\n");
00839 printf("Problem: %s\n", nu_client_strerror(session, err));
00840 exit(EXIT_FAILURE);
00841 }
00842
00843
00844
00845
00846 suppress_fqdn_verif |= nu_client_default_suppress_fqdn_verif();
00847 if (!context->cafile)
00848 context->cafile = (char *)nu_client_default_tls_ca();
00849 if (!context->certfile)
00850 context->certfile = (char *)nu_client_default_tls_cert();
00851 if (!context->keyfile)
00852 context->keyfile = (char *)nu_client_default_tls_key();
00853
00854
00855 printf("Connecting to NuFW gateway (%s)\n", context->srv_addr);
00856 session = do_connect(context, username);
00857
00858 if (session) {
00859 display_cert(session);
00860 }
00861
00862
00863 if (session == NULL) {
00864 printf("Unable to initiate connection to NuFW gateway\n");
00865 if (err->error != 0)
00866 printf("Problem: %s\n", nu_client_strerror(session, err));
00867 printf("Authentication failed (check parameters)\n");
00868 exit(EXIT_FAILURE);
00869 }
00870 }
00871
00872 int main(int argc, char **argv)
00873 {
00874 char *runpid = compute_run_pid();
00875 char *username = NULL;
00876 char *default_username = NULL;
00877 nutcpc_context_t context;
00878 memset(&context, 0, sizeof(context));
00879
00880 default_username = nu_get_user_name();
00881
00882
00883 setlocale(LC_ALL, "");
00884
00885 if (!nu_check_version(NUCLIENT_VERSION)) {
00886 fprintf(stderr,
00887 "Wrong version of libnuclient (%s instead of %s)\n",
00888 nu_get_version(), NUCLIENT_VERSION);
00889 exit(EXIT_FAILURE);
00890 }
00891
00892 if (runpid == NULL) {
00893 fprintf(stderr, "Can not determine runpid, leaving\n");
00894 exit(EXIT_FAILURE);
00895 }
00896
00897
00898
00899
00900 parse_cmdline_options(argc, argv, &context, &username);
00901
00902 if (!context.debug_mode) {
00903 if (context.donotuselock == 0) {
00904 if (!access(runpid, R_OK)) {
00905 FILE *fd;
00906 printf("Lock file found: %s\n", runpid);
00907 if ((fd = fopen(runpid, "r"))) {
00908 char line[20];
00909 if (fgets(line, 19, fd)) {
00910 pid_t pid =
00911 (pid_t) atoi(line);
00912 fclose(fd);
00913 if (kill(pid, 0)) {
00914 printf
00915 ("No running process, starting anyway (deleting lockfile)\n");
00916 unlink(runpid);
00917 } else {
00918 printf
00919 ("Kill existing process with \"-k\" or ignore it with \"-l\" option\n");
00920 exit(EXIT_FAILURE);
00921 }
00922 }
00923 }
00924 }
00925 }
00926 }
00927
00928 install_signals();
00929
00930 if (!username)
00931 username = default_username;
00932
00933 init_library(&context, username);
00934
00935
00936
00937
00938
00939
00940 if (!context.debug_mode) {
00941 daemonize_process(&context, runpid);
00942 } else {
00943 fprintf(stderr,
00944 "nutcpc " NUTCPC_VERSION " started (debug)\n");
00945 }
00946 free(runpid);
00947
00948 main_loop(&context);
00949 leave_client();
00950 exit(EXIT_SUCCESS);
00951 }