src/cmd/fsexam/src/fsexam-plaintext.c
changeset 147 8c4ef02c14b8
equal deleted inserted replaced
146:841e634f8d60 147:8c4ef02c14b8
       
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
       
    24  * Use is subject to license terms.
       
    25  */
       
    26 #ifdef HAVE_CONFIG_H
       
    27 #include <config.h>
       
    28 #endif
       
    29 
       
    30 #include <string.h>
       
    31 #include <stdlib.h>
       
    32 #include <stdio.h>
       
    33 #include <ctype.h>
       
    34 #include <locale.h>
       
    35 
       
    36 #include <glib.h>
       
    37 
       
    38 #include "fsexam-header.h"
       
    39 #include "fsexam-plaintext.h"
       
    40 
       
    41 #define FILE_CMD    "/usr/bin/file"
       
    42 
       
    43 static gchar * 
       
    44 get_utf8_locale (void)
       
    45 {
       
    46     gchar       buf[50];
       
    47     FILE        *fp = NULL;
       
    48     gchar       **argv = NULL;
       
    49     GError      *error = NULL;
       
    50     gint        child_stdout;
       
    51     gboolean    find = FALSE;
       
    52 
       
    53     memset (buf, 0, sizeof (buf));
       
    54 
       
    55     argv = g_new0 (gchar *, 3);
       
    56     argv[0] = "/usr/bin/locale"; 
       
    57     argv[1] = "-a";
       
    58     argv[2] = NULL;
       
    59 
       
    60     if (!g_spawn_async_with_pipes (NULL, argv, NULL,
       
    61                 0, 	/* GSpawnFlags */
       
    62                 NULL,   /* child setup func */
       
    63                 NULL,   /* user data */
       
    64                 NULL,   /* pid */
       
    65                 NULL,
       
    66                 &child_stdout,
       
    67                 NULL,
       
    68                 &error)) {
       
    69         g_print (error->message);
       
    70         goto done;
       
    71     }
       
    72 
       
    73     if ((fp = fdopen (child_stdout, "r")) == NULL) {
       
    74         g_print (_("Can't open pipe file descriptor.\n"));
       
    75         goto done;
       
    76     }
       
    77 
       
    78     while (fgets (buf, sizeof (buf), fp) != NULL) {
       
    79         if (buf[strlen (buf) - 1] == '\n')
       
    80             buf[strlen (buf) -1] = '\0';
       
    81 
       
    82         if (g_str_has_suffix (buf, "UTF-8")) {
       
    83             find = TRUE;
       
    84             break;
       
    85         }
       
    86     }
       
    87 
       
    88 done:
       
    89     if (error != NULL)
       
    90         g_error_free (error);
       
    91 
       
    92     if (fp != NULL)
       
    93         fclose (fp);
       
    94 
       
    95     g_free (argv);
       
    96 
       
    97     if (! find) {
       
    98         g_print (_("The system has no UTF-8 locale\n"));
       
    99         return NULL;
       
   100     }
       
   101 
       
   102     return g_strdup (buf);
       
   103 }
       
   104 
       
   105 static gboolean
       
   106 is_plain_text_by_locale (const gchar *name, const gchar *locale)
       
   107 {
       
   108     gchar       buf[256];
       
   109     FILE        *fp = NULL;
       
   110     gchar       **argv = NULL;
       
   111     gchar       **envp = NULL;
       
   112     GError      *error = NULL;
       
   113     gint        child_stdout;
       
   114     gboolean    retval = FALSE;
       
   115 
       
   116     argv = g_new0 (gchar *, 3);
       
   117     argv[0] = FILE_CMD;
       
   118     argv[1] = (gchar *) name;
       
   119     argv[2] = NULL;
       
   120 
       
   121     envp = g_new0 (gchar *, 4);
       
   122     envp[0] = "LC_ALL=";
       
   123     envp[1] = "LC_MESSAGES=C";
       
   124     if (locale) {
       
   125         envp[2] = g_strdup_printf ("LC_CTYPE=%s", locale);
       
   126     }else{
       
   127         envp[2] = NULL;
       
   128     }
       
   129     envp[3] = NULL;
       
   130 
       
   131     if (!g_spawn_async_with_pipes (NULL, argv, envp,
       
   132                 0, 	    /* GSpawnFlags */
       
   133                 NULL,   /* child setup func */
       
   134                 NULL,   /* user data */
       
   135                 NULL,   /* pid */
       
   136                 NULL,
       
   137                 &child_stdout,
       
   138                 NULL,
       
   139                 &error)) {
       
   140         g_print (error->message);
       
   141         goto done;
       
   142     }
       
   143 
       
   144     if ((fp = fdopen (child_stdout, "r")) == NULL) {
       
   145         g_print (_("Can't open pipe file descriptor.\n"));
       
   146         goto done;
       
   147     }
       
   148 
       
   149     memset (buf, 0, sizeof (buf));
       
   150     fgets (buf, sizeof (buf), fp);
       
   151 
       
   152     if (fsexam_debug () & FSEXAM_DBG_PLAIN_TEXT) {
       
   153         gchar *lc_all = NULL;
       
   154         gchar *lc_ctype = NULL;
       
   155 
       
   156         lc_all = getenv ("LC_ALL");
       
   157         setenv ("LC_ALL", "", TRUE);    /* unset LC_ALL to get LC_CTYPE */
       
   158 
       
   159         if (locale == NULL)
       
   160             lc_ctype = setlocale (LC_CTYPE, NULL);
       
   161         else
       
   162             lc_ctype = (char *)locale;
       
   163         g_print ("LC_CTYPE=%s, file type: %s\n", 
       
   164                 lc_ctype ? lc_ctype : "NULL",
       
   165                 buf ? buf : "Unknown");
       
   166     
       
   167         if (lc_all != NULL)
       
   168             setenv ("LC_ALL", lc_all, TRUE);    /* reset LC_ALL */
       
   169     }
       
   170 
       
   171     if (*buf != '\0') {
       
   172         gchar *p = buf;
       
   173         while (*p != ':') 
       
   174             ++p;
       
   175         ++p;
       
   176         while (isspace (*p)) 
       
   177             ++p;
       
   178 
       
   179         if (strstr (p, "text"))
       
   180             retval = TRUE;
       
   181     }
       
   182 
       
   183 done:
       
   184     if (error != NULL)
       
   185         g_error_free (error);
       
   186     if (fp != NULL)
       
   187         fclose (fp);
       
   188 
       
   189     g_free (argv);
       
   190     g_free (envp[2]);
       
   191     g_free (envp);
       
   192 
       
   193     return retval;
       
   194 }
       
   195 
       
   196 gboolean
       
   197 fsexam_is_plain_text (const gchar *name, FSEXAM_setting *setting)
       
   198 {
       
   199     static gboolean first = TRUE;
       
   200     gboolean    retval = FALSE;
       
   201     GList       *p = NULL;
       
   202     GList       *encode_list = NULL;
       
   203 
       
   204     if (setting->pref->force)
       
   205         return TRUE;
       
   206 
       
   207     /* fast check in current locale */
       
   208     if (is_plain_text_by_locale (name, NULL))
       
   209         return TRUE;
       
   210 
       
   211     /* check on UTF-8 locale */
       
   212     if (first) {
       
   213         setting->utf8_locale = get_utf8_locale ();
       
   214         first = FALSE;
       
   215     }
       
   216 
       
   217     if (setting->utf8_locale != NULL &&
       
   218             is_plain_text_by_locale (name, setting->utf8_locale))
       
   219         return TRUE;
       
   220 
       
   221     encode_list = setting->pref->encode_list;
       
   222     for (p = encode_list; p; p = p->next)
       
   223     {
       
   224         const gchar *locale = encoding_to_locale (id2encoding (
       
   225                                     ((Encoding*) p->data)->encodingID));
       
   226 
       
   227         if (locale == NULL)
       
   228             continue;
       
   229 
       
   230         if (is_plain_text_by_locale (name, locale)) {
       
   231             retval = TRUE;
       
   232             break;
       
   233         }
       
   234     }
       
   235 
       
   236     return retval;
       
   237 }