home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / git-4.3 / git-4 / git-4.3.11 / src / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  14.5 KB  |  724 lines

  1. /* misc.c -- Miscelaneous functions used in git/gitps/gitview.  */
  2.  
  3. /* Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
  4.  
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. /* Written by Tudor Hulubei and Andrei Pitis.  */
  20.  
  21.  
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25.  
  26. #include <stdio.h>
  27.  
  28. #ifdef HAVE_STDLIB_H
  29. #include <stdlib.h>
  30. #else /* !HAVE_STDLIB_H */
  31. #include "ansi_stdlib.h"
  32. #endif /* !HAVE_STDLIB_H */
  33.  
  34. #include <signal.h>
  35.  
  36. #include <sys/types.h>
  37. #include <pwd.h>
  38.  
  39. #ifdef HAVE_UNISTD_H
  40. #include <unistd.h>
  41. #endif /* HAVE_UNISTD_H */
  42.  
  43. #include "xstring.h"
  44. #include "xmalloc.h"
  45. #include "configure.h"
  46. #include "file.h"
  47. #include "tty.h"
  48. #include "misc.h"
  49.  
  50.  
  51. static char CONFIGFILE_PREFIX[] = "/.gitrc.";
  52. static char term[] = TERMDIR;
  53.  
  54. char  *tty_name;
  55. size_t tty_name_len;
  56. char  *login_name;
  57. size_t login_name_len;
  58.  
  59.  
  60. char *day_name[] =
  61. {
  62.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  63. };
  64.  
  65.  
  66. char *month_name[] =
  67. {
  68.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  69.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  70. };
  71.  
  72.  
  73. /* The pointer to the head of the file type attributes list.  */
  74. file_type_info_t *fti_head = NULL;
  75.  
  76. void fatal PROTO ((char *));
  77.  
  78.  
  79. void
  80. display_exit_message(signame)
  81.     char *signame;
  82. {
  83.     struct tm *time = get_local_time();
  84.  
  85.     fprintf(stderr, "%s %d %2d:%02d:%02d %s[%d]: exiting on %s signal\n",
  86.         month_name[time->tm_mon], time->tm_mday, time->tm_hour,
  87.         time->tm_min, time->tm_sec, program, (int)pid, signame);
  88. }
  89.  
  90.  
  91. RETSIGTYPE
  92. fatal_signal(signum)
  93.     int signum;
  94. {
  95.     extern void clean_up PROTO (());
  96.  
  97.     clean_up();
  98.  
  99.     switch (signum)
  100.     {
  101.     case SIGTERM:
  102.     case SIGQUIT:
  103.  
  104.         display_exit_message((signum == SIGTERM) ? "TERM" : "QUIT");
  105.         break;
  106.  
  107.     case SIGHUP:
  108.     case SIGINT:
  109.  
  110.         display_exit_message((signum == SIGHUP) ? "HUP" : "INT");
  111.         break;
  112.  
  113.     case SIGSEGV:
  114.  
  115.         display_exit_message("SEGV");
  116.         goto ask_report;
  117.         break;
  118.  
  119.     default:
  120.  
  121.         fprintf(stderr,
  122.             "%s: got a stupid signal (%d). Unless it was a joke ...\n",
  123.             program, signum);
  124.       ask_report:
  125.         fprintf(stderr, "%s: please report to tudorh@pub.ro\n",
  126.             program);
  127.         break;
  128.     }
  129.  
  130.     exit(signum);
  131. }
  132.  
  133.  
  134. void
  135. configuration_fatal_error(configfile)
  136.     char *configfile;
  137. {
  138.     fprintf(stderr, "%s: installation problem: \n", program);
  139.     fprintf(stderr, "%s: cannot find configuration file '%s'.\n\n",
  140.         program, configfile);
  141. }
  142.  
  143.  
  144. void
  145. configuration_warning(configfile)
  146.     char *configfile;
  147. {
  148.     fprintf(stderr,
  149.         "\n%s: Cannot open configuration file '%s'.\n",
  150.         program, configfile);
  151.     fprintf(stderr,
  152.         "%s: See the info documentation for details.\n",
  153.         program);
  154.     fprintf(stderr,
  155.        "%s: If the TERM environment variable is, say, vt102, your\n",
  156.         program);
  157.     fprintf(stderr,
  158.         "%s: configuration file name is '.gitrc.vt102'.\n",
  159.         program);
  160.     fprintf(stderr,
  161.        "%s: You can copy a configuration file in your home directory\n",
  162.         program);
  163.     fprintf(stderr,
  164.         "%s: and modify it in order to overwrite the default one.\n",
  165.         program);
  166.     fprintf(stderr,
  167.         "%s: Try modifying '.gitrc.generic'...\n\n",
  168.         program);
  169. }
  170.  
  171.  
  172. void
  173. common_configuration_init()
  174. {
  175.     int config_ok;
  176.  
  177.     char *configfile = xmalloc(strlen(term) + 1 + strlen(CONFIGFILE_PREFIX) +
  178.                    strlen(tty_type) + 1);
  179.     strcpy(configfile, term);
  180.     strcat(configfile, CONFIGFILE_PREFIX);
  181.     strcat(configfile, "common");
  182.  
  183.     config_ok = configuration_init(configfile);
  184.  
  185.     if (!config_ok)
  186.     {
  187.     configuration_fatal_error(configfile);
  188.     exit(1);
  189.     }
  190. }
  191.  
  192.  
  193. int
  194. specific_configuration_init()
  195. {
  196.     int config_ok;
  197.  
  198.     char *configfile = xmalloc(strlen(home) + 1 + strlen(CONFIGFILE_PREFIX) +
  199.                    strlen(tty_type) + 1);
  200.     strcpy(configfile, home);
  201.     strcat(configfile, CONFIGFILE_PREFIX);
  202.     strcat(configfile, tty_type);
  203.  
  204.     config_ok = configuration_init(configfile);
  205.  
  206.     if (!config_ok)
  207.     {
  208.     xfree(configfile);
  209.     configfile = xmalloc(strlen(term) + 1 + strlen(CONFIGFILE_PREFIX) +
  210.                  strlen(tty_type) + 1);
  211.     strcpy(configfile, term);
  212.     strcat(configfile, CONFIGFILE_PREFIX);
  213.     strcat(configfile, tty_type);
  214.  
  215.     config_ok = configuration_init(configfile);
  216.  
  217.     if (!config_ok)
  218.     {
  219.         configuration_warning(configfile);
  220.  
  221.         xfree(configfile);
  222.         configfile = xmalloc(strlen(term) + 1 + strlen(CONFIGFILE_PREFIX) +
  223.                  10 + 1);
  224.         strcpy(configfile, term);
  225.         strcat(configfile, CONFIGFILE_PREFIX);
  226.         strcat(configfile, "generic");
  227.  
  228.         config_ok = configuration_init(configfile);
  229.  
  230.         if (!config_ok)
  231.         {
  232.         configuration_fatal_error(configfile);
  233.         exit(1);
  234.         }
  235.  
  236.         return 0;
  237.     }
  238.     }
  239.  
  240.     xfree(configfile);
  241.  
  242.     return 1;
  243. }
  244.  
  245.  
  246. void
  247. use_section(section)
  248.     char *section;
  249. {
  250.     if (configuration_section(section) == -1)
  251.     {
  252.     fprintf(stderr,
  253.         "%s: can't find section %s in the configuration file.\n",
  254.         program, section);
  255.     exit(1);
  256.     }
  257. }
  258.  
  259.  
  260. int
  261. get_int_var(var_name, default_value)
  262.     char *var_name;
  263.     int default_value;
  264. {
  265.     char *data;
  266.  
  267.     configuration_getvarinfo(var_name, &data, 1, DO_SEEK);
  268.  
  269.     return data ? atoi(data) : default_value;
  270. }
  271.  
  272.  
  273. int
  274. get_const_var(var_name, options, options_no, default_value)
  275.     char *var_name, *options[];
  276.     int options_no, default_value;
  277. {
  278.     int i;
  279.     char *data;
  280.  
  281.     configuration_getvarinfo(var_name, &data, 1, DO_SEEK);
  282.  
  283.     if (data)
  284.     {
  285.     for (i = 0; i < options_no; i++)
  286.         if (strcmp(data, options[i]) == 0)
  287.         break;
  288.  
  289.     if (i == options_no)
  290.         fprintf(stderr, "%s: invalid %s (%s).\n", program, var_name, data);
  291.     else
  292.         return i;
  293.     }
  294.  
  295.     return default_value;
  296. }
  297.  
  298.  
  299. int
  300. get_flag_var(var_name, default_value)
  301.     char *var_name;
  302.     int default_value;
  303. {
  304.     char *data;
  305.  
  306.     configuration_getvarinfo(var_name, &data, 1, DO_SEEK);
  307.  
  308.     if (data)
  309.     {
  310.     if (strcmp(data, "ON")  == 0)
  311.         return 1;
  312.  
  313.     if (strcmp(data, "OFF") == 0)
  314.         return 0;
  315.  
  316.     fprintf(stderr, "%s: invalid %s (%s).\n", program, var_name, data);
  317.     return default_value;
  318.     }
  319.  
  320.     return default_value;
  321. }
  322.  
  323.  
  324. char *
  325. get_string_var(var_name, default_value)
  326.     char *var_name, *default_value;
  327. {
  328.     char *data;
  329.  
  330.     configuration_getvarinfo(var_name, &data, 1, DO_SEEK);
  331.  
  332.     if (data)
  333.     return xstrdup(data);
  334.  
  335.     return default_value;
  336. }
  337.  
  338.  
  339. void
  340. get_colorset_var(charset, colorset_name, fields_no)
  341.     int *charset;
  342.     char *colorset_name[];
  343.     int fields_no;
  344. {
  345.     int i, index;
  346.     char *data;
  347.  
  348.     for (i = 0; i < fields_no; i++)
  349.     {
  350.     configuration_getvarinfo(colorset_name[i], &data, 1, DO_SEEK);
  351.  
  352.     if (data)
  353.     {
  354.         index = tty_get_color_index(data);
  355.         if (index == -1)
  356.         fprintf(stderr, "%s: invalid %s (%s).\n",
  357.             program, colorset_name[i], data);
  358.         else
  359.         charset[i] = index;
  360.     }
  361.     }
  362. }
  363.  
  364.  
  365. /*
  366.  * Clear the path, that is, convert paths like /etc/./././///./ into their
  367.  * cleaner form: /etc.  Stolen from the Thix kernel.  Enhanced to clean
  368.  * paths like /usr/local/bin/../lib as well.
  369.  */
  370.  
  371. char *
  372. clear_path(path)
  373.     char *path;
  374. {
  375.     char *cpath = path;
  376.     char *opath = path;
  377.  
  378.     if (*opath == '/')
  379.     *cpath++ = *opath++;
  380.     else
  381.     fatal("relative path encounter");
  382.  
  383.     while (*opath)
  384.     {
  385.     while (*opath == '/' ||
  386.            (*opath == '.' && (*(opath + 1) == '/' || *(opath + 1) == 0)))
  387.         opath++;
  388.  
  389.     if (*opath == '.' &&
  390.         *(opath + 1) == '.' &&
  391.         (*(opath + 2) == '/' || *(opath + 2) == '\0'))
  392.     {
  393.         /* This is something like /usr/local/bin/.. and we ar
  394.            going to remove the trailing .. along with the
  395.            directory that no longer meakes sense: bin.  */
  396.  
  397.         /* Check for /..  and do nothing if this is the case.  */
  398.         if (cpath - 1 != path)
  399.         {
  400.         for (cpath -= 2; *cpath != '/'; cpath--);
  401.         cpath++;
  402.         }
  403.  
  404.         opath += 2;
  405.         continue;
  406.     }
  407.  
  408.     while (*opath && *opath != '/')
  409.         *cpath++ = *opath++;
  410.  
  411.     if (*opath)
  412.         *cpath++ = '/';
  413.     }
  414.  
  415.     if (*(cpath - 1) == '/' && cpath - path > 1)
  416.     cpath--;
  417.  
  418.     *cpath = 0;
  419.     return path;
  420. }
  421.  
  422.  
  423. void
  424. get_tty_name()
  425. {
  426.     if ((tty_name = ttyname(1)) == NULL)
  427.     {
  428.     fprintf(stderr, "%s: can't get terminal name.\n", program);
  429.     exit(1);
  430.     }
  431.  
  432.     tty_name_len = strlen(tty_name);
  433. }
  434.  
  435.  
  436. void
  437. get_login_name()
  438. {
  439.     struct passwd *pwd;
  440.     int euid = geteuid();
  441.  
  442.     if ((pwd = getpwuid(euid)) == NULL)
  443.     {
  444.     fprintf(stderr,
  445.         "%s: OOOPS, I can't get your user name (euid = %d) !\n",
  446.         program, euid);
  447.     fprintf(stderr,
  448.         "%s: Your account no longer exists or you are a SYSTEM CRACKER !! :-)\n",
  449.         program);
  450.     fprintf(stderr, "%s: Correct the problem and try again.\n", program);
  451.     exit(1);
  452.     }
  453.  
  454.     login_name     = xstrdup(pwd->pw_name);
  455.     login_name_len = strlen(login_name);
  456. }
  457.  
  458.  
  459. void
  460. truncate_long_name(name, dest, len)
  461.     char *name, *dest;
  462.     size_t len;
  463. {
  464.     size_t name_len = strlen(name);
  465.  
  466.     if (name_len > len)
  467.     {
  468.     dest[0] = dest[1] = dest[2] = '.';
  469.     memcpy(dest + 3, name + name_len - len + 3, len - 3);
  470.     }
  471.     else
  472.     memcpy(dest, name, name_len);
  473. }
  474.  
  475.  
  476. char *
  477. truncate_string(path, temppath, len)
  478.     char *path;
  479.     char *temppath;
  480.     size_t len;
  481. {
  482.     truncate_long_name(path, temppath, len);
  483.     temppath[min(len, strlen(path))] = 0;
  484.     return temppath;
  485. }
  486.  
  487.  
  488. int
  489. get_file_length(handle)
  490.     int handle;
  491. {
  492.     int tmp, length;
  493.  
  494.     tmp    = lseek(handle, 0, SEEK_CUR);
  495.     length = lseek(handle, 0, SEEK_END);
  496.     lseek(handle, tmp, SEEK_SET);
  497.     return length;
  498. }
  499.  
  500.  
  501. struct tm *
  502. get_local_time()
  503. {
  504.     time_t __time;
  505.  
  506.     /* Get the broken-down time representation.  */
  507.     __time = time(NULL);
  508.     return localtime(&__time);
  509. }
  510.  
  511.  
  512. #ifndef HAVE_PUTENV
  513. #ifndef HAVE_SETENV
  514. #ifdef NeXT
  515. /*
  516.  * m68k-next-nextstep (NeXT - Next Step 3.2) seems to lack putenv().
  517.  * I have included /NextDeveloper/Source/GNU/debug/gdb/gdb/putenv.c
  518.  * here.  Paul Nevai <nevai@ops.mps.ohio-state.edu> used it to make
  519.  * git compile on the NeXT.
  520.  */
  521.  
  522. /*
  523.  * Path: hoptoad!pacbell!ames!ll-xn!mit-eddie!uw-beaver!ssc-vax!uvicctr!tholm
  524.  * From: tholm@uvicctr.UUCP (Terrence W. Holm)
  525.  * Newsgroups: comp.os.minix
  526.  * Subject: putenv(3)
  527.  * Message-ID: <395@uvicctr.UUCP>
  528.  * Date: 5 May 88 06:40:52 GMT
  529.  * Organization: University of Victoria, Victoria B.C. Canada
  530.  *
  531.  * EFTH Minix report #2  - May 1988 -  putenv(3)
  532.  *
  533.  * This is an implementation of putenv(3) that we
  534.  * wrote for Minix. Please consider this a public
  535.  * domain program.
  536.  *
  537.  */
  538.  
  539. extern char **environ;
  540.  
  541. /****************************************************************/
  542. /*                                */
  543. /*      int                            */
  544. /*    putenv( entry )                        */
  545. /*                                */
  546. /*        The "entry" should follow the form         */
  547. /*        "NAME=VALUE". This routine will search the     */
  548. /*        user environment for "NAME" and replace its     */
  549. /*        value with "VALUE".                */
  550. /*                                */
  551. /*        Note that "entry" is not copied, it is used     */
  552. /*        as the environment entry. This means that it     */
  553. /*        must not be unallocated or otherwise modifed     */
  554. /*        by the caller, unless it is replaced by a     */
  555. /*        subsequent putenv().                */
  556. /*                                */
  557. /*        If the name is not found in the environment,     */
  558. /*        then a new vector of pointers is allocated,     */
  559. /*        "entry" is put at the end and the global     */
  560. /*        variable "environ" is updated.            */
  561. /*                                */
  562. /*        This function normally returns NULL, but -1    */
  563. /*        is returned if it can not allocate enough     */
  564. /*        space using malloc(3), or "entry" does not    */
  565. /*        contain a '='.                    */
  566. /*                                */
  567. /****************************************************************/
  568.  
  569.  
  570. int
  571. putenv(entry)
  572.     char *entry;
  573. {
  574.     unsigned length;
  575.     unsigned size;
  576.     char     *temp;
  577.     char     **p;
  578.     char     **new_environ;
  579.  
  580.     /* Find the length of the "NAME=".  */
  581.     temp = strchr(entry,'=');
  582.  
  583.     if (temp == 0)
  584.     return -1;
  585.  
  586.     length = (unsigned) (temp - entry + 1);
  587.  
  588.     /* Scan through the environment looking for "NAME="  */
  589.     for (p = environ; *p != 0 ; p++)
  590.     if (strncmp(entry, *p, length) == 0)
  591.     {
  592.         *p = entry;
  593.         return 0;
  594.     }
  595.  
  596.  
  597.     /*  The name was not found, build a bigger environment  */
  598.     size = p - environ;
  599.     new_environ = (char **)malloc((size + 2) * sizeof(char *));
  600.  
  601.     if (new_environ == (char **)NULL)
  602.     return -1;
  603.  
  604.     memcpy((char *)new_environ, (char *)environ, size * sizeof(char *));
  605.  
  606.     new_environ[size]   = entry;
  607.     new_environ[size+1] = NULL;
  608.  
  609.     environ = new_environ;
  610.  
  611.     return 0;
  612. }
  613. #else
  614. /* I guess we are simply out of luck.  #error ?  */
  615. #endif /* NeXT */
  616. #endif /* HAVE_SETENV */
  617. #endif /* HAVE_PUTENV */
  618.  
  619.  
  620. /*
  621.  * Check if it is a background command.  We are doing this by looking
  622.  * for a '&' at the end of the command string.
  623.  */
  624.  
  625. int
  626. is_a_bg_command(cmd)
  627.     char *cmd;
  628. {
  629.     int i;
  630.  
  631.     for (i = strlen(cmd) - 1; i >= 0; i--)
  632.     {
  633.     if (cmd[i] == '&')
  634.         return 1;
  635.  
  636.     /* Skip spaces and tabs.  */
  637.     if (cmd[i] != ' ' && cmd[i] != key_TAB)
  638.         return 0;
  639.     }
  640.  
  641.     /* No '&' found.  */
  642.     return 0;
  643. }
  644.  
  645.  
  646. /*
  647.  * Check if it is a empty command (containing only spaces and ';'s.
  648.  * My guess that almost any command that doesn't contain at least one
  649.  * alphanumeric character should be considered as being empty, but I
  650.  * don't want to take any chances.
  651.  */
  652.  
  653. int
  654. is_an_empty_command(cmd)
  655.     char *cmd;
  656. {
  657.     for (; *cmd; cmd++)
  658.     if (*cmd != ' ' && *cmd != ';')
  659.         return 0;
  660.  
  661.     return 1;
  662. }
  663.  
  664.  
  665. void
  666. get_file_type_info()
  667. {
  668.     char *contents[3];
  669.     unsigned char regexp[80];
  670.     int brightness, foreground, background;
  671.     file_type_info_t *previous = NULL, *fti, *fti_head1 = NULL;
  672.  
  673.  
  674.     for (;;)
  675.     {
  676.     configuration_getvarinfo((char *)regexp, contents, 3, NO_SEEK);
  677.  
  678.     if (*regexp == 0)
  679.         break;
  680.  
  681.     if (contents[0])
  682.         foreground = tty_get_color_index(contents[0]);
  683.     else
  684.         foreground = -1;
  685.  
  686.     if (contents[1])
  687.         background = tty_get_color_index(contents[1]);
  688.     else
  689.         background = -1;
  690.  
  691.     if (contents[2])
  692.         brightness = tty_get_color_index(contents[2]);
  693.     else
  694.         brightness = -1;
  695.  
  696.     /* Insert the just obtained file type entry into the list.  */
  697.  
  698.     fti = (file_type_info_t *)xmalloc(sizeof(file_type_info_t));
  699.  
  700.     if (fti_head1 == NULL)
  701.         fti_head1 = previous = fti;
  702.     else
  703.         previous->next = fti;
  704.  
  705.     fti->regexp     = xstrdup(regexp);
  706.     fti->foreground = foreground;
  707.     fti->background = background;
  708.     fti->brightness = brightness;
  709.     fti->next       = NULL;
  710.  
  711.     previous = fti;
  712.     }
  713.  
  714.     /* Fixed by Marian Ciobanu <ciobi@liis.sfos.ro>, October 24, 1995.  */
  715.     if (fti_head1)
  716.     if (fti_head)
  717.     {
  718.         previous->next = fti_head;
  719.         fti_head = fti_head1;
  720.     }
  721.     else
  722.         fti_head = fti_head1;
  723. }
  724.