/[rdesktop]/jpeg/rdesktop/trunk/rdesktop.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /jpeg/rdesktop/trunk/rdesktop.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 974 by astrand, Thu Aug 4 12:50:15 2005 UTC revision 1309 by stargo, Wed Nov 1 20:52:01 2006 UTC
# Line 27  Line 27 
27  #include <sys/time.h>           /* gettimeofday */  #include <sys/time.h>           /* gettimeofday */
28  #include <sys/times.h>          /* times */  #include <sys/times.h>          /* times */
29  #include <ctype.h>              /* toupper */  #include <ctype.h>              /* toupper */
 #include <limits.h>             /* PATH_MAX */  
30  #include <errno.h>  #include <errno.h>
31  #include "rdesktop.h"  #include "rdesktop.h"
32    
# Line 51  Line 50 
50  char g_title[64] = "";  char g_title[64] = "";
51  char g_username[64];  char g_username[64];
52  char g_hostname[16];  char g_hostname[16];
53  char keymapname[PATH_MAX] = "";  char g_keymapname[PATH_MAX] = "";
54  int g_keylayout = 0x409;        /* Defaults to US keyboard layout */  unsigned int g_keylayout = 0x409;       /* Defaults to US keyboard layout */
55  int g_keyboard_type = 0x4;      /* Defaults to US keyboard layout */  int g_keyboard_type = 0x4;      /* Defaults to US keyboard layout */
56  int g_keyboard_subtype = 0x0;   /* Defaults to US keyboard layout */  int g_keyboard_subtype = 0x0;   /* Defaults to US keyboard layout */
57  int g_keyboard_functionkeys = 0xc;      /* Defaults to US keyboard layout */  int g_keyboard_functionkeys = 0xc;      /* Defaults to US keyboard layout */
# Line 70  int g_pos = 0;                 /* 0 position unspecifi Line 69  int g_pos = 0;                 /* 0 position unspecifi
69                                     2 xpos neg,                                     2 xpos neg,
70                                     4 ypos neg  */                                     4 ypos neg  */
71  extern int g_tcp_port_rdp;  extern int g_tcp_port_rdp;
72  int g_server_bpp = 8;  int g_server_depth = -1;
73  int g_win_button_size = 0;      /* If zero, disable single app mode */  int g_win_button_size = 0;      /* If zero, disable single app mode */
74  BOOL g_bitmap_compression = True;  BOOL g_bitmap_compression = True;
75  BOOL g_sendmotion = True;  BOOL g_sendmotion = True;
# Line 85  BOOL g_fullscreen = False; Line 84  BOOL g_fullscreen = False;
84  BOOL g_grab_keyboard = True;  BOOL g_grab_keyboard = True;
85  BOOL g_hide_decorations = False;  BOOL g_hide_decorations = False;
86  BOOL g_use_rdp5 = True;  BOOL g_use_rdp5 = True;
87    BOOL g_rdpclip = True;
88  BOOL g_console_session = False;  BOOL g_console_session = False;
89  BOOL g_numlock_sync = False;  BOOL g_numlock_sync = False;
90    BOOL lspci_enabled = False;
91  BOOL g_owncolmap = False;  BOOL g_owncolmap = False;
92  BOOL g_ownbackstore = True;     /* We can't rely on external BackingStore */  BOOL g_ownbackstore = True;     /* We can't rely on external BackingStore */
93    BOOL g_seamless_rdp = False;
94  uint32 g_embed_wnd;  uint32 g_embed_wnd;
95  uint32 g_rdp5_performanceflags =  uint32 g_rdp5_performanceflags =
96          RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;          RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
97    /* Session Directory redirection */
98    BOOL g_redirect = False;
99    char g_redirect_server[64];
100    char g_redirect_domain[16];
101    char g_redirect_password[64];
102    char g_redirect_username[64];
103    char g_redirect_cookie[128];
104    uint32 g_redirect_flags = 0;
105    
106  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
107  BOOL g_rdpsnd = False;  BOOL g_rdpsnd = False;
# Line 138  usage(char *program) Line 148  usage(char *program)
148  #ifdef HAVE_ICONV  #ifdef HAVE_ICONV
149          fprintf(stderr, "   -L: local codepage\n");          fprintf(stderr, "   -L: local codepage\n");
150  #endif  #endif
151            fprintf(stderr, "   -A: enable SeamlessRDP mode\n");
152          fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");          fprintf(stderr, "   -B: use BackingStore of X-server (if available)\n");
153          fprintf(stderr, "   -e: disable encryption (French TS)\n");          fprintf(stderr, "   -e: disable encryption (French TS)\n");
154          fprintf(stderr, "   -E: disable encryption from client to server\n");          fprintf(stderr, "   -E: disable encryption from client to server\n");
# Line 168  usage(char *program) Line 179  usage(char *program)
179          fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");          fprintf(stderr, "         '-r printer:mydeskjet': enable printer redirection\n");
180          fprintf(stderr,          fprintf(stderr,
181                  "             or      mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");                  "             or      mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");
182          fprintf(stderr, "         '-r sound:[local|off|remote]': enable sound redirection\n");  #ifdef WITH_RDPSND
183            fprintf(stderr,
184                    "         '-r sound:[local[:driver[:device]]|off|remote]': enable sound redirection\n");
185          fprintf(stderr, "                     remote would leave sound on server\n");          fprintf(stderr, "                     remote would leave sound on server\n");
186            fprintf(stderr, "                     available drivers for 'local':\n");
187            rdpsnd_show_help();
188    #endif
189            fprintf(stderr,
190                    "         '-r clipboard:[off|PRIMARYCLIPBOARD|CLIPBOARD]': enable clipboard\n");
191            fprintf(stderr, "                      redirection.\n");
192            fprintf(stderr,
193                    "                      'PRIMARYCLIPBOARD' looks at both PRIMARY and CLIPBOARD\n");
194            fprintf(stderr, "                      when sending data to server.\n");
195            fprintf(stderr, "                      'CLIPBOARD' looks at only CLIPBOARD.\n");
196    #ifdef WITH_SCARD
197            fprintf(stderr, "         '-r scard[:\"Scard Name\"=\"Alias Name[;Vendor Name]\"[,...]]\n");
198            fprintf(stderr, "          example: -r scard:\"eToken PRO 00 00\"=\"AKS ifdh 0\"\n");
199            fprintf(stderr,
200                    "                   \"eToken PRO 00 00\" -> Device in Linux/Unix enviroment\n");
201            fprintf(stderr,
202                    "                   \"AKS ifdh 0\"       -> Device shown in Windows enviroment \n");
203            fprintf(stderr, "          example: -r scard:\"eToken PRO 00 00\"=\"AKS ifdh 0;AKS\"\n");
204            fprintf(stderr,
205                    "                   \"eToken PRO 00 00\" -> Device in Linux/Unix enviroment\n");
206            fprintf(stderr,
207                    "                   \"AKS ifdh 0\"       -> Device shown in Windows enviroment \n");
208            fprintf(stderr,
209                    "                   \"AKS\"              -> Device vendor name                 \n");
210    #endif
211          fprintf(stderr, "   -0: attach to console\n");          fprintf(stderr, "   -0: attach to console\n");
212          fprintf(stderr, "   -4: use RDP version 4\n");          fprintf(stderr, "   -4: use RDP version 4\n");
213          fprintf(stderr, "   -5: use RDP version 5 (default)\n");          fprintf(stderr, "   -5: use RDP version 5 (default)\n");
# Line 275  print_disconnect_reason(uint16 reason) Line 313  print_disconnect_reason(uint16 reason)
313          fprintf(stderr, "disconnect: %s.\n", text);          fprintf(stderr, "disconnect: %s.\n", text);
314  }  }
315    
316    static void
317    rdesktop_reset_state(void)
318    {
319            rdp_reset_state();
320    }
321    
322  static BOOL  static BOOL
323  read_password(char *password, int size)  read_password(char *password, int size)
324  {  {
# Line 367  main(int argc, char *argv[]) Line 411  main(int argc, char *argv[])
411          char fullhostname[64];          char fullhostname[64];
412          char domain[16];          char domain[16];
413          char password[64];          char password[64];
414          char shell[128];          char shell[256];
415          char directory[32];          char directory[256];
416          BOOL prompt_password, deactivated;          BOOL prompt_password, deactivated;
417          struct passwd *pw;          struct passwd *pw;
418          uint32 flags, ext_disc_reason = 0;          uint32 flags, ext_disc_reason = 0;
# Line 376  main(int argc, char *argv[]) Line 420  main(int argc, char *argv[])
420          int c;          int c;
421          char *locale = NULL;          char *locale = NULL;
422          int username_option = 0;          int username_option = 0;
423            BOOL geometry_option = False;
424            int run_count = 0;      /* Session Directory support */
425            BOOL continue_connect = True;   /* Session Directory support */
426            char *rdpsnd_optarg = NULL;
427    
428  #ifdef HAVE_LOCALE_H  #ifdef HAVE_LOCALE_H
429          /* Set locale according to environment */          /* Set locale according to environment */
# Line 400  main(int argc, char *argv[]) Line 448  main(int argc, char *argv[])
448  #endif  #endif
449    
450          while ((c = getopt(argc, argv,          while ((c = getopt(argc, argv,
451                             VNCOPT "u:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)                             VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
452          {          {
453                  switch (c)                  switch (c)
454                  {                  {
# Line 418  main(int argc, char *argv[]) Line 466  main(int argc, char *argv[])
466                                  break;                                  break;
467  #endif  #endif
468    
469                            case 'A':
470                                    g_seamless_rdp = True;
471                                    break;
472    
473                          case 'u':                          case 'u':
474                                  STRNCPY(g_username, optarg, sizeof(g_username));                                  STRNCPY(g_username, optarg, sizeof(g_username));
475                                  username_option = 1;                                  username_option = 1;
# Line 464  main(int argc, char *argv[]) Line 516  main(int argc, char *argv[])
516                                  break;                                  break;
517    
518                          case 'k':                          case 'k':
519                                  STRNCPY(keymapname, optarg, sizeof(keymapname));                                  STRNCPY(g_keymapname, optarg, sizeof(g_keymapname));
520                                  break;                                  break;
521    
522                          case 'g':                          case 'g':
523                                    geometry_option = True;
524                                  g_fullscreen = False;                                  g_fullscreen = False;
525                                  if (!strcmp(optarg, "workarea"))                                  if (!strcmp(optarg, "workarea"))
526                                  {                                  {
# Line 575  main(int argc, char *argv[]) Line 628  main(int argc, char *argv[])
628                                  break;                                  break;
629    
630                          case 'a':                          case 'a':
631                                  g_server_bpp = strtol(optarg, NULL, 10);                                  g_server_depth = strtol(optarg, NULL, 10);
632                                  if (g_server_bpp != 8 && g_server_bpp != 16 && g_server_bpp != 15                                  if (g_server_depth != 8 &&
633                                      && g_server_bpp != 24)                                      g_server_depth != 16 &&
634                                        g_server_depth != 15 && g_server_depth != 24)
635                                  {                                  {
636                                          error("invalid server bpp\n");                                          error("Invalid server colour depth.\n");
637                                          return 1;                                          return 1;
638                                  }                                  }
639                                  break;                                  break;
# Line 590  main(int argc, char *argv[]) Line 644  main(int argc, char *argv[])
644                                  break;                                  break;
645    
646                          case 'x':                          case 'x':
647                                  if (strncmp("modem", optarg, 1) == 0)                                  if (str_startswith(optarg, "m"))        /* modem */
648                                  {                                  {
649                                          g_rdp5_performanceflags =                                          g_rdp5_performanceflags =
650                                                  RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |                                                  RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG |
651                                                  RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;                                                  RDP5_NO_MENUANIMATIONS | RDP5_NO_THEMING;
652                                  }                                  }
653                                  else if (strncmp("broadband", optarg, 1) == 0)                                  else if (str_startswith(optarg, "b"))   /* broadband */
654                                  {                                  {
655                                          g_rdp5_performanceflags = RDP5_NO_WALLPAPER;                                          g_rdp5_performanceflags = RDP5_NO_WALLPAPER;
656                                  }                                  }
657                                  else if (strncmp("lan", optarg, 1) == 0)                                  else if (str_startswith(optarg, "l"))   /* lan */
658                                  {                                  {
659                                          g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;                                          g_rdp5_performanceflags = RDP5_DISABLE_NOTHING;
660                                  }                                  }
# Line 616  main(int argc, char *argv[]) Line 670  main(int argc, char *argv[])
670    
671                          case 'r':                          case 'r':
672    
673                                  if (strncmp("sound", optarg, 5) == 0)                                  if (str_startswith(optarg, "sound"))
674                                  {                                  {
675                                          optarg += 5;                                          optarg += 5;
676    
677                                          if (*optarg == ':')                                          if (*optarg == ':')
678                                          {                                          {
679                                                  *optarg++;                                                  optarg++;
680                                                  while ((p = next_arg(optarg, ',')))                                                  while ((p = next_arg(optarg, ',')))
681                                                  {                                                  {
682                                                          if (strncmp("remote", optarg, 6) == 0)                                                          if (str_startswith(optarg, "remote"))
683                                                                  flags |= RDP_LOGON_LEAVE_AUDIO;                                                                  flags |= RDP_LOGON_LEAVE_AUDIO;
684    
685                                                          if (strncmp("local", optarg, 5) == 0)                                                          if (str_startswith(optarg, "local"))
686  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
687                                                            {
688                                                                    rdpsnd_optarg =
689                                                                            next_arg(optarg, ':');
690                                                                  g_rdpsnd = True;                                                                  g_rdpsnd = True;
691                                                            }
692    
693  #else  #else
694                                                                  warning("Not compiled with sound support\n");                                                                  warning("Not compiled with sound support\n");
695  #endif  #endif
696    
697                                                          if (strncmp("off", optarg, 3) == 0)                                                          if (str_startswith(optarg, "off"))
698  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
699                                                                  g_rdpsnd = False;                                                                  g_rdpsnd = False;
700  #else  #else
# Line 654  main(int argc, char *argv[]) Line 713  main(int argc, char *argv[])
713  #endif  #endif
714                                          }                                          }
715                                  }                                  }
716                                  else if (strncmp("disk", optarg, 4) == 0)                                  else if (str_startswith(optarg, "disk"))
717                                  {                                  {
718                                          /* -r disk:h:=/mnt/floppy */                                          /* -r disk:h:=/mnt/floppy */
719                                          disk_enum_devices(&g_num_devices, optarg + 4);                                          disk_enum_devices(&g_num_devices, optarg + 4);
720                                  }                                  }
721                                  else if (strncmp("comport", optarg, 7) == 0)                                  else if (str_startswith(optarg, "comport"))
722                                  {                                  {
723                                          serial_enum_devices(&g_num_devices, optarg + 7);                                          serial_enum_devices(&g_num_devices, optarg + 7);
724                                  }                                  }
725                                  else if (strncmp("lptport", optarg, 7) == 0)                                  else if (str_startswith(optarg, "lspci"))
726                                    {
727                                            lspci_enabled = True;
728                                    }
729                                    else if (str_startswith(optarg, "lptport"))
730                                  {                                  {
731                                          parallel_enum_devices(&g_num_devices, optarg + 7);                                          parallel_enum_devices(&g_num_devices, optarg + 7);
732                                  }                                  }
733                                  else if (strncmp("printer", optarg, 7) == 0)                                  else if (str_startswith(optarg, "printer"))
734                                  {                                  {
735                                          printer_enum_devices(&g_num_devices, optarg + 7);                                          printer_enum_devices(&g_num_devices, optarg + 7);
736                                  }                                  }
737                                  else if (strncmp("clientname", optarg, 7) == 0)                                  else if (str_startswith(optarg, "clientname"))
738                                  {                                  {
739                                          g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);                                          g_rdpdr_clientname = xmalloc(strlen(optarg + 11) + 1);
740                                          strcpy(g_rdpdr_clientname, optarg + 11);                                          strcpy(g_rdpdr_clientname, optarg + 11);
741                                  }                                  }
742                                    else if (str_startswith(optarg, "clipboard"))
743                                    {
744                                            optarg += 9;
745    
746                                            if (*optarg == ':')
747                                            {
748                                                    optarg++;
749    
750                                                    if (str_startswith(optarg, "off"))
751                                                            g_rdpclip = False;
752                                                    else
753                                                            cliprdr_set_mode(optarg);
754                                            }
755                                            else
756                                                    g_rdpclip = True;
757                                    }
758                                    else if (strncmp("scard", optarg, 5) == 0)
759                                    {
760    #ifdef WITH_SCARD
761                                            scard_enum_devices(&g_num_devices, optarg + 5);
762    #else
763                                            warning("Not compiled with smartcard support\n");
764    #endif
765                                    }
766                                  else                                  else
767                                  {                                  {
768                                          warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound\n");                                          warning("Unknown -r argument\n\n\tPossible arguments are: comport, disk, lptport, printer, sound, clipboard, scard\n");
769                                  }                                  }
770                                  break;                                  break;
771    
# Line 711  main(int argc, char *argv[]) Line 798  main(int argc, char *argv[])
798          STRNCPY(server, argv[optind], sizeof(server));          STRNCPY(server, argv[optind], sizeof(server));
799          parse_server_and_port(server);          parse_server_and_port(server);
800    
801            if (g_seamless_rdp)
802            {
803                    if (g_win_button_size)
804                    {
805                            error("You cannot use -S and -A at the same time\n");
806                            return 1;
807                    }
808                    g_rdp5_performanceflags &= ~RDP5_NO_FULLWINDOWDRAG;
809                    if (geometry_option)
810                    {
811                            error("You cannot use -g and -A at the same time\n");
812                            return 1;
813                    }
814                    if (g_fullscreen)
815                    {
816                            error("You cannot use -f and -A at the same time\n");
817                            return 1;
818                    }
819                    if (g_hide_decorations)
820                    {
821                            error("You cannot use -D and -A at the same time\n");
822                            return 1;
823                    }
824                    if (g_embed_wnd)
825                    {
826                            error("You cannot use -X and -A at the same time\n");
827                            return 1;
828                    }
829                    if (!g_use_rdp5)
830                    {
831                            error("You cannot use -4 and -A at the same time\n");
832                            return 1;
833                    }
834                    g_width = -100;
835                    g_grab_keyboard = False;
836            }
837    
838          if (!username_option)          if (!username_option)
839          {          {
840                  pw = getpwuid(getuid());                  pw = getpwuid(getuid());
# Line 752  main(int argc, char *argv[]) Line 876  main(int argc, char *argv[])
876                  STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));                  STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
877          }          }
878    
879          if (keymapname[0] == 0)          if (g_keymapname[0] == 0)
880          {          {
881                  if (locale && xkeymap_from_locale(locale))                  if (locale && xkeymap_from_locale(locale))
882                  {                  {
883                          fprintf(stderr, "Autoselected keyboard map %s\n", keymapname);                          fprintf(stderr, "Autoselected keyboard map %s\n", g_keymapname);
884                  }                  }
885                  else                  else
886                  {                  {
887                          STRNCPY(keymapname, "en-us", sizeof(keymapname));                          STRNCPY(g_keymapname, "en-us", sizeof(g_keymapname));
888                  }                  }
889          }          }
890          if (locale)          if (locale)
# Line 786  main(int argc, char *argv[]) Line 910  main(int argc, char *argv[])
910    
911  #ifdef WITH_RDPSND  #ifdef WITH_RDPSND
912          if (g_rdpsnd)          if (g_rdpsnd)
913                  rdpsnd_init();          {
914                    if (!rdpsnd_init(rdpsnd_optarg))
915                    {
916                            warning("Initializing sound-support failed!\n");
917                    }
918            }
919  #endif  #endif
920    
921            if (lspci_enabled)
922                    lspci_init();
923    
924          rdpdr_init();          rdpdr_init();
925    
926          if (!rdp_connect(server, flags, domain, password, shell, directory))          while (run_count < 2 && continue_connect)       /* add support for Session Directory; only reconnect once */
927                  return 1;          {
928                    if (run_count == 0)
929                    {
930                            if (!rdp_connect(server, flags, domain, password, shell, directory))
931                                    return 1;
932                    }
933                    else if (!rdp_reconnect
934                             (server, flags, domain, password, shell, directory, g_redirect_cookie))
935                            return 1;
936    
937          /* By setting encryption to False here, we have an encrypted login                  /* By setting encryption to False here, we have an encrypted login
938             packet but unencrypted transfer of other packets */                     packet but unencrypted transfer of other packets */
939          if (!packet_encryption)                  if (!packet_encryption)
940                  g_encryption = False;                          g_encryption = False;
941    
942    
943          DEBUG(("Connection successful.\n"));                  DEBUG(("Connection successful.\n"));
944          memset(password, 0, sizeof(password));                  memset(password, 0, sizeof(password));
945    
946          if (ui_create_window())                  if (run_count == 0)
947          {                          if (!ui_create_window())
948                  rdp_main_loop(&deactivated, &ext_disc_reason);                                  continue_connect = False;
949                  ui_destroy_window();  
950                    if (continue_connect)
951                            rdp_main_loop(&deactivated, &ext_disc_reason);
952    
953                    DEBUG(("Disconnecting...\n"));
954                    rdp_disconnect();
955    
956                    if ((g_redirect == True) && (run_count == 0))   /* Support for Session Directory */
957                    {
958                            /* reset state of major globals */
959                            rdesktop_reset_state();
960    
961                            STRNCPY(domain, g_redirect_domain, sizeof(domain));
962                            STRNCPY(g_username, g_redirect_username, sizeof(g_username));
963                            STRNCPY(password, g_redirect_password, sizeof(password));
964                            STRNCPY(server, g_redirect_server, sizeof(server));
965                            flags |= RDP_LOGON_AUTO;
966    
967                            g_redirect = False;
968                    }
969                    else
970                    {
971                            continue_connect = False;
972                            ui_destroy_window();
973                            break;
974                    }
975    
976                    run_count++;
977          }          }
978    
         DEBUG(("Disconnecting...\n"));  
         rdp_disconnect();  
979          cache_save_state();          cache_save_state();
980          ui_deinit();          ui_deinit();
981    
# Line 936  xmalloc(int size) Line 1102  xmalloc(int size)
1102          return mem;          return mem;
1103  }  }
1104    
1105    /* Exit on NULL pointer. Use to verify result from XGetImage etc */
1106    void
1107    exit_if_null(void *ptr)
1108    {
1109            if (ptr == NULL)
1110            {
1111                    error("unexpected null pointer. Out of memory?\n");
1112                    exit(1);
1113            }
1114    }
1115    
1116  /* strdup */  /* strdup */
1117  char *  char *
1118  xstrdup(const char *s)  xstrdup(const char *s)
# Line 1084  next_arg(char *src, char needle) Line 1261  next_arg(char *src, char needle)
1261                          while (*(mvp + 1) != (char) 0x00)                          while (*(mvp + 1) != (char) 0x00)
1262                          {                          {
1263                                  *mvp = *(mvp + 1);                                  *mvp = *(mvp + 1);
1264                                  *mvp++;                                  mvp++;
1265                          }                          }
1266                          *mvp = (char) 0x00;                          *mvp = (char) 0x00;
1267                          p = nextval;                          p = nextval;
# Line 1122  toupper_str(char *p) Line 1299  toupper_str(char *p)
1299  }  }
1300    
1301    
1302    BOOL
1303    str_startswith(const char *s, const char *prefix)
1304    {
1305            return (strncmp(s, prefix, strlen(prefix)) == 0);
1306    }
1307    
1308    
1309    /* Split input into lines, and call linehandler for each
1310       line. Incomplete lines are saved in the rest variable, which should
1311       initially point to NULL. When linehandler returns False, stop and
1312       return False. Otherwise, return True.  */
1313    BOOL
1314    str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data)
1315    {
1316            char *buf, *p;
1317            char *oldrest;
1318            size_t inputlen;
1319            size_t buflen;
1320            size_t restlen = 0;
1321            BOOL ret = True;
1322    
1323            /* Copy data to buffer */
1324            inputlen = strlen(input);
1325            if (*rest)
1326                    restlen = strlen(*rest);
1327            buflen = restlen + inputlen + 1;
1328            buf = (char *) xmalloc(buflen);
1329            buf[0] = '\0';
1330            if (*rest)
1331                    STRNCPY(buf, *rest, buflen);
1332            strncat(buf, input, inputlen);
1333            p = buf;
1334    
1335            while (1)
1336            {
1337                    char *newline = strchr(p, '\n');
1338                    if (newline)
1339                    {
1340                            *newline = '\0';
1341                            if (!linehandler(p, data))
1342                            {
1343                                    p = newline + 1;
1344                                    ret = False;
1345                                    break;
1346                            }
1347                            p = newline + 1;
1348                    }
1349                    else
1350                    {
1351                            break;
1352    
1353                    }
1354            }
1355    
1356            /* Save in rest */
1357            oldrest = *rest;
1358            restlen = buf + buflen - p;
1359            *rest = (char *) xmalloc(restlen);
1360            STRNCPY((*rest), p, restlen);
1361            xfree(oldrest);
1362    
1363            xfree(buf);
1364            return ret;
1365    }
1366    
1367    /* Execute the program specified by argv. For each line in
1368       stdout/stderr output, call linehandler. Returns false on failure. */
1369    BOOL
1370    subprocess(char *const argv[], str_handle_lines_t linehandler, void *data)
1371    {
1372            pid_t child;
1373            int fd[2];
1374            int n = 1;
1375            char output[256];
1376            char *rest = NULL;
1377    
1378            if (pipe(fd) < 0)
1379            {
1380                    perror("pipe");
1381                    return False;
1382            }
1383    
1384            if ((child = fork()) < 0)
1385            {
1386                    perror("fork");
1387                    return False;
1388            }
1389    
1390            /* Child */
1391            if (child == 0)
1392            {
1393                    /* Close read end */
1394                    close(fd[0]);
1395    
1396                    /* Redirect stdout and stderr to pipe */
1397                    dup2(fd[1], 1);
1398                    dup2(fd[1], 2);
1399    
1400                    /* Execute */
1401                    execvp(argv[0], argv);
1402                    perror("Error executing child");
1403                    _exit(128);
1404            }
1405    
1406            /* Parent. Close write end. */
1407            close(fd[1]);
1408            while (n > 0)
1409            {
1410                    n = read(fd[0], output, 255);
1411                    output[n] = '\0';
1412                    str_handle_lines(output, &rest, linehandler, data);
1413            }
1414            xfree(rest);
1415    
1416            return True;
1417    }
1418    
1419    
1420  /* not all clibs got ltoa */  /* not all clibs got ltoa */
1421  #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)  #define LTOA_BUFSIZE (sizeof(long) * 8 + 1)
1422    

Legend:
Removed from v.974  
changed lines
  Added in v.1309

  ViewVC Help
Powered by ViewVC 1.1.26