Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #111740 > unrolled thread

How to determine if file is binary or text?

Started byDFS <nospam@dfs.com>
First post2017-06-07 14:40 -0400
Last post2017-06-08 12:03 -0500
Articles 20 on this page of 41 — 21 participants

Back to article view | Back to comp.lang.c


Contents

  How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-07 14:40 -0400
    Re: How to determine if file is binary or text? GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-06-07 20:46 +0200
    Re: How to determine if file is binary or text? bartc <bc@freeuk.com> - 2017-06-07 19:58 +0100
    Re: How to determine if file is binary or text? scott@slp53.sl.home (Scott Lurndal) - 2017-06-07 19:05 +0000
    Re: How to determine if file is binary or text? supercat@casperkitty.com - 2017-06-07 12:10 -0700
    Re: How to determine if file is binary or text? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-07 16:25 -0400
    Re: How to determine if file is binary or text? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2017-06-07 21:44 +0000
      Re: How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-07 18:14 -0400
        Re: How to determine if file is binary or text? GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-06-08 00:23 +0200
          Re: How to determine if file is binary or text? Robert Wessel <robertwessel2@yahoo.com> - 2017-06-08 00:11 -0500
            Re: How to determine if file is binary or text? GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-06-08 15:14 +0200
              Re: How to determine if file is binary or text? Robert Wessel <robertwessel2@yahoo.com> - 2017-06-08 11:06 -0500
            Re: How to determine if file is binary or text? raltbos@xs4all.nl (Richard Bos) - 2017-06-17 18:28 +0000
        Re: How to determine if file is binary or text? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-07 23:30 +0100
          Re: How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-07 20:26 -0400
            Re: How to determine if file is binary or text? bartc <bc@freeuk.com> - 2017-06-08 01:30 +0100
              Re: How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-07 23:50 -0400
                Re: How to determine if file is binary or text? mark.bluemel@gmail.com - 2017-06-08 02:13 -0700
                  Re: How to determine if file is binary or text? mark.bluemel@gmail.com - 2017-06-08 04:05 -0700
                  Re: How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-08 09:21 -0400
                    Re: How to determine if file is binary or text? Ike Naar <ike@iceland.freeshell.org> - 2017-06-08 14:19 +0000
                      Re: How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-08 12:07 -0400
                        Re: How to determine if file is binary or text? scott@slp53.sl.home (Scott Lurndal) - 2017-06-08 16:14 +0000
                          Re: How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-08 12:37 -0400
                            Re: How to determine if file is binary or text? scott@slp53.sl.home (Scott Lurndal) - 2017-06-08 16:54 +0000
                              Re: How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-08 13:14 -0400
                              An old version of what??? (Was: How to determine if file is binary or text?) gazelle@shell.xmission.com (Kenny McCormack) - 2017-06-09 17:13 +0000
                Re: How to determine if file is binary or text? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-08 11:15 +0100
            Re: How to determine if file is binary or text? scott@slp53.sl.home (Scott Lurndal) - 2017-06-08 12:49 +0000
            Re: How to determine if file is binary or text? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2017-06-08 14:01 +0000
            Re: How to determine if file is binary or text? Michael Forsythe <forsythe@example.com> - 2017-06-08 15:33 +0000
              Re: How to determine if file is binary or text? DFS <nospam@dfs.com> - 2017-06-08 18:43 -0400
                Re: How to determine if file is binary or text? jak <please@nospam.tnx> - 2017-06-09 08:46 +0200
        Re: How to determine if file is binary or text? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-07 19:23 -0400
        Re: How to determine if file is binary or text? Barry Schwarz <schwarzb@dqel.com> - 2017-06-07 16:50 -0700
        Re: How to determine if file is binary or text? "Pascal J. Bourguignon" <pjb@informatimago.com> - 2017-06-08 15:51 +0200
    Re: How to determine if file is binary or text? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-06-07 17:17 -0600
      Re: How to determine if file is binary or text? Keith Thompson <kst-u@mib.org> - 2017-06-07 19:21 -0700
        Re: How to determine if file is binary or text? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-06-07 21:37 -0600
    Re: How to determine if file is binary or text? Noob <root@127.0.0.1> - 2017-06-08 08:40 +0200
    Re: How to determine if file is binary or text? gordonb.t9rom@burditt.org (Gordon Burditt) - 2017-06-08 12:03 -0500

Page 1 of 3  [1] 2 3  Next page →


#111740 — How to determine if file is binary or text?

FromDFS <nospam@dfs.com>
Date2017-06-07 14:40 -0400
SubjectHow to determine if file is binary or text?
Message-ID<oh9h55$a0q$2@dont-email.me>
binary, such as .xls or .exe or Linux ELF executable
text, such as an ascii .txt file

I've tried:

_Bool is_binary(const void *data, size_t len)
{
	return memchr(data, '\0', len) != NULL;
}

fgets(line,sizeof line, file);
is_binary(line,strlen(line));

but is_binary() always returns 0 no matter the data passed to it.


[toc] | [next] | [standalone]


#111741

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2017-06-07 20:46 +0200
Message-ID<20170607204612.ddd8908519c7cac2f6794335@gmail.com>
In reply to#111740
On Wed, 7 Jun 2017 14:40:31 -0400
DFS <nospam@dfs.com> wrote:

> binary, such as .xls or .exe or Linux ELF executable
> text, such as an ascii .txt file

Actually any file is binary but not all contains printable characters.

[toc] | [prev] | [next] | [standalone]


#111742

Frombartc <bc@freeuk.com>
Date2017-06-07 19:58 +0100
Message-ID<C1YZA.1317$UK2.181@fx01.am4>
In reply to#111740
On 07/06/2017 19:40, DFS wrote:
> binary, such as .xls or .exe or Linux ELF executable
> text, such as an ascii .txt file
> 
> I've tried:
> 
> _Bool is_binary(const void *data, size_t len)
> {
>      return memchr(data, '\0', len) != NULL;
> }
> 
> fgets(line,sizeof line, file);
> is_binary(line,strlen(line));
> 
> but is_binary() always returns 0 no matter the data passed to it.

fgets is designed to read lines of text from a text (ie. non-binary 
file). It will never contain a 0 byte except as a terminator, and that's 
excluded by the strlen length.

Telling the difference between text and binary files, by examining every 
byte, is not easy. Text files will contain bytes of 9, 13, 10 and maybe 
a few others. And they might contain 128 to 255 if non-ASCII.

Binary probably contains other bytes in the range 0 to 31 too. But some 
might not; because binary files can contain ANY data, including embedded 
text files.

So you can't be sure, but can only surmise.

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#111743

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-06-07 19:05 +0000
Message-ID<%7YZA.126585$EH.25153@fx40.iad>
In reply to#111740
DFS <nospam@dfs.com> writes:
>binary, such as .xls or .exe or Linux ELF executable
>text, such as an ascii .txt file
>
>I've tried:
>
>_Bool is_binary(const void *data, size_t len)
>{
>	return memchr(data, '\0', len) != NULL;
>}
>
>fgets(line,sizeof line, file);
>is_binary(line,strlen(line));
>
>but is_binary() always returns 0 no matter the data passed to it.
>
>
>

Here's a C program that detects filetypes in bytestreams.
(All *nix files are bytestreams with no externally imposed format).

https://github.com/file/file/tree/master/src

[toc] | [prev] | [next] | [standalone]


#111744

Fromsupercat@casperkitty.com
Date2017-06-07 12:10 -0700
Message-ID<376897ea-2944-4019-9654-bd71f7972b87@googlegroups.com>
In reply to#111740
Some systems store binary and text files very differently, and have file-mode
flags which keep track of whether something is a binary or a text file.  They
may provide a system-specific means of accessing that information, but require
that files written as text be re-opened as text, and those written as binary be
re-opened as binary.

Other systems treat both kinds of files identically and do not keep track of
whether a file was opened with "w" or "wb" because they have no reason to care
about such things.

Finally, there are systems where certain operations on files are performed
somewhat differently based upon the mode used to open a file, but which
don't keep track of how files on disk are written.  Writing "Hello\n" to a
file in text mode on such a system might produce the exact same bit pattern
as writing "Hello\r\n" in binary mode.

The Standard can't require implementations to report whether something is
a text file or binary file because many implementations don't keep track
of such information.  It can't require implementations to allow text files
to be opened in binary mode, nor vice versa, because some systems treat
such files in ways that are fundamentally different.  The net effect is
that the Standard provides nothing beyond "hope for the best" semantics in
cases where one wants to open a file and doesn't know what mode was used
to create it.

[toc] | [prev] | [next] | [standalone]


#111755

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-06-07 16:25 -0400
Message-ID<b1f7d03a-3eb8-01b3-0549-172efd149f0e@verizon.net>
In reply to#111740
On 06/07/2017 02:40 PM, DFS wrote:
> binary, such as .xls or .exe or Linux ELF executable
> text, such as an ascii .txt file
>
> I've tried:
>
> _Bool is_binary(const void *data, size_t len)
> {
> 	return memchr(data, '\0', len) != NULL;
> }
>
> fgets(line,sizeof line, file);

fgets() returns NULL if it's reached the end of the file, or if an I/O 
error has occurred. You should always check for that possibility, and if 
it comes up, DON'T use the input data - there is none, or at least none 
that is usable. Even if you're willing to assume that an I/O error is 
unlikely (I would not recommend doing so), end-of-file is a near 
certainty in typical use contexts.

> is_binary(line,strlen(line));
>
> but is_binary() always returns 0 no matter the data passed to it.

strlen(line) looks for the first '\0' character in the line, and
returns a count of the number of characters that precede that
character. Therefore it's logically impossible for memchr() to find a
'\0' in that portion of the line.

In order to identify whether a file is binary, you first need to define
what you mean by "binary file" in terms of it's contents. The standard
itself only defines binary streams (which can be associated with
files), but it defines them solely in terms of the fact that they were
opened using the 'b' character in the mode passed to fopen(). The use
of that character does not itself cause any detectable affect in the
output file. It's possible to open a file in binary mode, and write to
it data which causes it to look identical to a file opened in text mode.

However, the standard makes an important guarantee for binary streams:
"Data read in from a binary stream shall compare equal to the data that 
were earlier written out to that stream, under the same implementation.
Such a stream may, however, have an implementation-defined number of
null characters appended to the end of the stream." (7.21.2p3).

The corresponding promise for text streams is far more complicated,
imposing conditions for the promise that are easily violated:
"Characters may have to be added, altered, or deleted on input and
output to conform to differing conventions for representing text in the
host environment. Thus, there need not be a one-to-one correspondence
between the characters in a stream and those in the external
representation. Data read in from a text stream will necessarily
compare equal to the data that were earlier written out to that stream
only if: the data consist only of printing characters and the control
characters horizontal tab and new-line; no new-line character is
immediately preceded by space characters; and the last character is a
new-line character. Whether space characters that are written out
immediately before a new-line character appear when read in is
implementation-defined." (7.21.2p2)

As a result, if you open a stream in text mode, it's generally a
mistake to write anything to that stream which violates the conditions
for that guarantee. This provides a basis for defining a binary file in
terms of it contents: a binary file is any file that, when opened in
binary mode, is found to contain any feature that would invalidate the
guarantee provided by 7.21.2p2. Specifically:

Any character for which isprint() is false other than '\t' and '\n'.
Any space character immediately preceding an '\n'.
The last character of the file is not '\n'.

Note that there is no guarantee that you will see any of these things if 
you open the file in text mode. One of the ways in which data written to 
the stream could fail to match the data read from the string is if 
reading a file in text mode causes those features to disappear, and I 
think this is actually fairly common. This means that if they are 
present in the input file, it must be opened in binary mode to reliably 
detect those features.

That's a problem, because text streams uses some implementation-specific 
method of indicating the end of a line, but the fact that it is 
implementation-specific is hidden from the user so long as you use text 
mode. A '\n' character written to a file gets converted into whatever 
method is used to identify the end of a line, and whatever method is 
actually used gets converted to a '\n' character when you read the file.

Methods that are actually in use include:
1. Marking the end of the line with '\n', '\r', '\0', '\r\n', or '\n\r',
depending upon the implementation.

2. Writing the file in fixed-size blocks, with the first part of each
block containing a count of how many bytes of the block have been used - 
the rest of the block may contain random garbage. If the count equals 
the amount of space available, the line continues into the next block. 
If the count is zero, the end of the line is at the start of the block, 
with the line itself being contained in previous blocks. Otherwise, the 
line ends after the last character used.

3. Writing a file in fixed-size blocks, padded to the end of the
block with null characters. If there's no padding at the end of the 
block, the line continues into the next block. If the block is all 
padding, the end of the line is at the start of the block, with the line 
itself being stored in previous blocks. Otherwise, the end of the line 
occurs after the last non-padding character in the block.
Note that an operating system call may be needed to determine what the 
block size is.

If a file is written in text mode, and read in binary mode, you will
see the actual method used for indicating the end of the line. Note that 
every option listed above for marking end-of-line (other than a simple 
'\n') could cause the file to be mis-identified as binary according to 
the above rules. Therefore, you need to convert whatever method was used 
to identify end-of-line into '\n' characters before applying the above 
rules. Which means your program needs to know what that method is, so 
this can't be done in a portable fashion.

On unix-like systems, '\n' is used to mark the end-of-line, so you can 
ignore that issue entirely. You can tell that Unix and C started out 
very closely related.

[toc] | [prev] | [next] | [standalone]


#111758

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2017-06-07 21:44 +0000
Message-ID<slrnojgstb.1kjn.grahn+nntp@frailea.sa.invalid>
In reply to#111740
On Wed, 2017-06-07, DFS wrote:
> binary, such as .xls or .exe or Linux ELF executable
> text, such as an ascii .txt file

Why do you want to find out?  Few programs have a need for that.

(One I can think of is Gnu diff, which says "binary files differ"
instead of trying to show the textual difference between two
executables.)

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#111761

FromDFS <nospam@dfs.com>
Date2017-06-07 18:14 -0400
Message-ID<oh9tla$p61$1@dont-email.me>
In reply to#111758
On 6/7/2017 5:44 PM, Jorgen Grahn wrote:
> On Wed, 2017-06-07, DFS wrote:
>> binary, such as .xls or .exe or Linux ELF executable
>> text, such as an ascii .txt file
> 
> Why do you want to find out?  Few programs have a need for that.

validate file inputs to my program.

If someone tries to pass a binary file I want to sniff it out.


> (One I can think of is Gnu diff, which says "binary files differ"
> instead of trying to show the textual difference between two
> executables.)

Is that all it says?

> /Jorgen

[toc] | [prev] | [next] | [standalone]


#111764

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2017-06-08 00:23 +0200
Message-ID<20170608002352.b649151a8ab2437ccdbe7b44@gmail.com>
In reply to#111761
On Wed, 7 Jun 2017 18:14:32 -0400
DFS <nospam@dfs.com> wrote:

> validate file inputs to my program.
> 
> If someone tries to pass a binary file I want to sniff it out.

Isn't it enough to check the file extension and signature? Do you assume the
user is exceptionally dumb to feed your program with incompatible files?

[toc] | [prev] | [next] | [standalone]


#111791

FromRobert Wessel <robertwessel2@yahoo.com>
Date2017-06-08 00:11 -0500
Message-ID<rumhjc11ba9ue2u0j3ermjr312367g7vhm@4ax.com>
In reply to#111764
On Thu, 8 Jun 2017 00:23:52 +0200, GOTHIER Nathan
<nathan.gothier@gmail.com> wrote:

>On Wed, 7 Jun 2017 18:14:32 -0400
>DFS <nospam@dfs.com> wrote:
>
>> validate file inputs to my program.
>> 
>> If someone tries to pass a binary file I want to sniff it out.
>
>Isn't it enough to check the file extension and signature? Do you assume the
>user is exceptionally dumb to feed your program with incompatible files?


Why would you assume that the user is not malicious, and is passing a
deliberately malformed input to cause some unpleasant effect?  Only if
you can truly be certain of the users virtue, and skill at maintaining
that virtue (IOW, you can trust that the user has not been fooled be
some other actor into passing a malformed input), can you reasonably
avoid validating the input.

[toc] | [prev] | [next] | [standalone]


#111812

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2017-06-08 15:14 +0200
Message-ID<20170608151418.23db2b85632edc10462bec4a@gmail.com>
In reply to#111791
On Thu, 08 Jun 2017 00:11:53 -0500
Robert Wessel <robertwessel2@yahoo.com> wrote:

> Why would you assume that the user is not malicious, and is passing a
> deliberately malformed input to cause some unpleasant effect?  Only if
> you can truly be certain of the users virtue, and skill at maintaining
> that virtue (IOW, you can trust that the user has not been fooled be
> some other actor into passing a malformed input), can you reasonably
> avoid validating the input.

Why would you assume the programmer support any malicious users? If the user
feed the program with bad data it is reasonable the programmer let him down
with his incompatible data. However it requires little effort to filter the
input data by the file extension and signature.

[toc] | [prev] | [next] | [standalone]


#111828

FromRobert Wessel <robertwessel2@yahoo.com>
Date2017-06-08 11:06 -0500
Message-ID<7jsijc5eepsq90pjc82td18u9n1snanidn@4ax.com>
In reply to#111812
On Thu, 8 Jun 2017 15:14:18 +0200, GOTHIER Nathan
<nathan.gothier@gmail.com> wrote:

>On Thu, 08 Jun 2017 00:11:53 -0500
>Robert Wessel <robertwessel2@yahoo.com> wrote:
>
>> Why would you assume that the user is not malicious, and is passing a
>> deliberately malformed input to cause some unpleasant effect?  Only if
>> you can truly be certain of the users virtue, and skill at maintaining
>> that virtue (IOW, you can trust that the user has not been fooled be
>> some other actor into passing a malformed input), can you reasonably
>> avoid validating the input.
>
>Why would you assume the programmer support any malicious users? If the user
>feed the program with bad data it is reasonable the programmer let him down
>with his incompatible data. However it requires little effort to filter the
>input data by the file extension and signature.


Because bad inputs happen, even if the user has no intentions of
providing such.  Think of all the virii and worms distributed because
the convinced users with no ill intentions to click on a link or open
an email attachment, which exploited some bug in the code handling
that - often a buffer overflow or some such.  Which is really a
failure to properly sanitize the input.

Sure, I don't want to support my user feeding a binary file, or
actively maliciously formed file, to my program, but it's my ethical
responsibility to ensure that nothing actually bad happens when the
user does it accidentally (other than my issuing an error message
saying "what the heck is that?").  Triggering a latent bug or exploit
in my code is *not* acceptable.

Consider:  I *could* read the next line of the input file with a
gets(), into a fixed size automatic object, and that would be nice and
simple (for me).  Now I *know* that no valid line of input can be more
than some limited length, but using the above approach leaves my
program vulnerable (on most C implementations) to a stack-smashing
attack and arbitrary code execution if someone feeds it an input file
longer than my fixed length input buffer.  Reading the input file
properly, and reporting an error for a too-long line, is certainly
more complex for the programmer, but better that than the situation
where someone asks the user, "Hey, John, could you run this file
through the fizzbin program for me?", and poor, well meaning, John
ends up with his machine 0wn3d.

[toc] | [prev] | [next] | [standalone]


#112404

Fromraltbos@xs4all.nl (Richard Bos)
Date2017-06-17 18:28 +0000
Message-ID<5945742d.2132921@news.xs4all.nl>
In reply to#111791
Robert Wessel <robertwessel2@yahoo.com> wrote:

> On Thu, 8 Jun 2017 00:23:52 +0200, GOTHIER Nathan
> >DFS <nospam@dfs.com> wrote:
> >
> >> validate file inputs to my program.
> >> 
> >> If someone tries to pass a binary file I want to sniff it out.
> >
> >Isn't it enough to check the file extension and signature? Do you assume the
> >user is exceptionally dumb to feed your program with incompatible files?
> 
> Why would you assume that the user is not malicious, and is passing a
> deliberately malformed input to cause some unpleasant effect?  Only if
> you can truly be certain of the users virtue, and skill at maintaining
> that virtue (IOW, you can trust that the user has not been fooled be
> some other actor into passing a malformed input), can you reasonably
> avoid validating the input.

Not only that, but everybody makes mistakes. Accidentally typing
file.tct instead of file.txt, or accidentally dragging film.avi instead
of file.txt (the preceding filename, you see), is something anyone could
do - and will, at least once.

Richard

[toc] | [prev] | [next] | [standalone]


#111765

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-06-07 23:30 +0100
Message-ID<87poefe8h1.fsf@bsb.me.uk>
In reply to#111761
DFS <nospam@dfs.com> writes:

> On 6/7/2017 5:44 PM, Jorgen Grahn wrote:
>> On Wed, 2017-06-07, DFS wrote:
>>> binary, such as .xls or .exe or Linux ELF executable
>>> text, such as an ascii .txt file
>>
>> Why do you want to find out?  Few programs have a need for that.
>
> validate file inputs to my program.
>
> If someone tries to pass a binary file I want to sniff it out.

Now that's a very helpful insight.  Rather than worry about a term that
has other meanings ("binary"), focus on what is is about the input that
you want to prohibit.  That, for you, will become the crucial test.
Define what is acceptable and what is not, and test for that.

The main reason to avoid the term "binary" is that it's not really an
intrinsic property of a file -- it's a property of how a program
processes a file.  You get one set of guarantees when you open a file as
a text file and another if you open it as a binary file.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#111773

FromDFS <nospam@dfs.com>
Date2017-06-07 20:26 -0400
Message-ID<oha5b6$e96$2@dont-email.me>
In reply to#111765
On 6/7/2017 6:30 PM, Ben Bacarisse wrote:
> DFS <nospam@dfs.com> writes:
> 
>> On 6/7/2017 5:44 PM, Jorgen Grahn wrote:
>>> On Wed, 2017-06-07, DFS wrote:
>>>> binary, such as .xls or .exe or Linux ELF executable
>>>> text, such as an ascii .txt file
>>>
>>> Why do you want to find out?  Few programs have a need for that.
>>
>> validate file inputs to my program.
>>
>> If someone tries to pass a binary file I want to sniff it out.
> 
> Now that's a very helpful insight.  Rather than worry about a term that
> has other meanings ("binary"), focus on what is is about the input that
> you want to prohibit.  That, for you, will become the crucial test.
> Define what is acceptable and what is not, and test for that.
> 
> The main reason to avoid the term "binary" is that it's not really an
> intrinsic property of a file -- it's a property of how a program
> processes a file.  You get one set of guarantees when you open a file as
> a text file and another if you open it as a binary file.
> 
> <snip>


I'm on Windows, but I installed the GNUWin32 port which includes 
'file.exe' (the Linux 'file' command).


int is_textfile(char *fname)
{
	char cmd[] = {0};
	sprintf(cmd,"file %s",fname);
	char *ftype = {system(cmd)};
	printf("filetype = %s\n",ftype);
}


output is

filename.txt; ASCII English text, with very long lines, with CRLF line 
terminators
filetype = (null)


So it runs the 'file' command and prints it, but it isn't getting 
captured in the ftype variable.

I tried _popen(cmd,"r") but the same thing happens: the value from the 
file command isn't captured.

Any ideas?





[toc] | [prev] | [next] | [standalone]


#111775

Frombartc <bc@freeuk.com>
Date2017-06-08 01:30 +0100
Message-ID<KU0_A.348038$op5.91911@fx39.am4>
In reply to#111773
On 08/06/2017 01:26, DFS wrote:
> On 6/7/2017 6:30 PM, Ben Bacarisse wrote:
>> DFS <nospam@dfs.com> writes:
>>
>>> On 6/7/2017 5:44 PM, Jorgen Grahn wrote:
>>>> On Wed, 2017-06-07, DFS wrote:
>>>>> binary, such as .xls or .exe or Linux ELF executable
>>>>> text, such as an ascii .txt file
>>>>
>>>> Why do you want to find out?  Few programs have a need for that.
>>>
>>> validate file inputs to my program.
>>>
>>> If someone tries to pass a binary file I want to sniff it out.
>>
>> Now that's a very helpful insight.  Rather than worry about a term that
>> has other meanings ("binary"), focus on what is is about the input that
>> you want to prohibit.  That, for you, will become the crucial test.
>> Define what is acceptable and what is not, and test for that.
>>
>> The main reason to avoid the term "binary" is that it's not really an
>> intrinsic property of a file -- it's a property of how a program
>> processes a file.  You get one set of guarantees when you open a file as
>> a text file and another if you open it as a binary file.
>>
>> <snip>
> 
> 
> I'm on Windows, but I installed the GNUWin32 port which includes 
> 'file.exe' (the Linux 'file' command).
> 
> 
> int is_textfile(char *fname)
> {
>      char cmd[] = {0};
>      sprintf(cmd,"file %s",fname);
>      char *ftype = {system(cmd)};
>      printf("filetype = %s\n",ftype);
> }
> 
> 
> output is
> 
> filename.txt; ASCII English text, with very long lines, with CRLF line 
> terminators
> filetype = (null)
> 
> 
> So it runs the 'file' command and prints it, but it isn't getting 
> captured in the ftype variable.
> 
> I tried _popen(cmd,"r") but the same thing happens: the value from the 
> file command isn't captured.
> 
> Any ideas?

system() returns the exit() code from the program it runs. It will be an 
integer (0 for success, anything else for failure).

To capture actual text output (that would be printed in the screen), try:

  system("command params >tempfile");      // stdout output
  system("command params 2>tempfile");     // stderr output

But then you have to open "tempfile" and print it out. Maybe another 
command:

  system("type tempfile");

if on Windows.

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#111788

FromDFS <nospam@dfs.com>
Date2017-06-07 23:50 -0400
Message-ID<ohahch$9su$2@dont-email.me>
In reply to#111775
On 6/7/2017 8:30 PM, bartc wrote:
> On 08/06/2017 01:26, DFS wrote:
>> On 6/7/2017 6:30 PM, Ben Bacarisse wrote:
>>> DFS <nospam@dfs.com> writes:
>>>
>>>> On 6/7/2017 5:44 PM, Jorgen Grahn wrote:
>>>>> On Wed, 2017-06-07, DFS wrote:
>>>>>> binary, such as .xls or .exe or Linux ELF executable
>>>>>> text, such as an ascii .txt file
>>>>>
>>>>> Why do you want to find out?  Few programs have a need for that.
>>>>
>>>> validate file inputs to my program.
>>>>
>>>> If someone tries to pass a binary file I want to sniff it out.
>>>
>>> Now that's a very helpful insight.  

Sarcasm?


>>> Rather than worry about a term that
>>> has other meanings ("binary"), focus on what is is about the input that
>>> you want to prohibit.  That, for you, will become the crucial test.
>>> Define what is acceptable and what is not, and test for that.
>>>
>>> The main reason to avoid the term "binary" is that it's not really an
>>> intrinsic property of a file -- it's a property of how a program
>>> processes a file.  You get one set of guarantees when you open a file as
>>> a text file and another if you open it as a binary file.
>>>
>>> <snip>
>>
>>
>> I'm on Windows, but I installed the GNUWin32 port which includes 
>> 'file.exe' (the Linux 'file' command).
>>
>>
>> int is_textfile(char *fname)
>> {
>>      char cmd[] = {0};
>>      sprintf(cmd,"file %s",fname);
>>      char *ftype = {system(cmd)};
>>      printf("filetype = %s\n",ftype);
>> }
>>
>>
>> output is
>>
>> filename.txt; ASCII English text, with very long lines, with CRLF line 
>> terminators
>> filetype = (null)
>>
>>
>> So it runs the 'file' command and prints it, but it isn't getting 
>> captured in the ftype variable.
>>
>> I tried _popen(cmd,"r") but the same thing happens: the value from the 
>> file command isn't captured.
>>
>> Any ideas?
> 
> system() returns the exit() code from the program it runs. It will be an 
> integer (0 for success, anything else for failure).

The docs say

"If command is not NULL, system returns the value that is returned by 
the command interpreter. It returns the value 0 only if the command 
interpreter returns the value 0."

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/system-wsystem

So I'm not sure what's happening.


> To capture actual text output (that would be printed in the screen), try:
> 
>   system("command params >tempfile");      // stdout output
>   system("command params 2>tempfile");     // stderr output
> 
> But then you have to open "tempfile" and print it out. Maybe another 
> command:
> 
>   system("type tempfile");
> 
> if on Windows.


Very kludgey.  Does popen() on Linux work better than this?

I had to do the reverse with VBA Excel (pass a file as a param so the bc 
app would write to stdout)

[toc] | [prev] | [next] | [standalone]


#111802

Frommark.bluemel@gmail.com
Date2017-06-08 02:13 -0700
Message-ID<6638cc40-dd84-4f1a-a60f-5860a172f4a8@googlegroups.com>
In reply to#111788
On Thursday, 8 June 2017 04:51:09 UTC+1, DFS  wrote:

> The docs say
> 
> "If command is not NULL, system returns the value that is returned by 
> the command interpreter. It returns the value 0 only if the command 
> interpreter returns the value 0."
> 
> https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/system-wsystem
> 
> So I'm not sure what's happening.

The value returned by a program is not the same as the messages output by a program...

#include <stdio.h>

int main(int argc, char** argv)
{
  printf("Hello World\n");
  return 0;
}

The value returned is not "Hello World\n". You could probably have worked
that out from the fact that the "system" function returns an int not a char *.

If you have support for pipes, that's the appropriate way to handle command 
output. Did you actually try reading the stream created by "_popen"?

[toc] | [prev] | [next] | [standalone]


#111805

Frommark.bluemel@gmail.com
Date2017-06-08 04:05 -0700
Message-ID<74884d5d-f13d-4e25-acf6-16060a3498a8@googlegroups.com>
In reply to#111802
On Thursday, 8 June 2017 10:13:55 UTC+1, mark.b...@gmail.com  wrote:
> On Thursday, 8 June 2017 04:51:09 UTC+1, DFS  wrote:
> 
> > The docs say
> > 
> > "If command is not NULL, system returns the value that is returned by 
> > the command interpreter. It returns the value 0 only if the command 
> > interpreter returns the value 0."
> > 
> > https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/system-wsystem
> > 
> > So I'm not sure what's happening.
> 
> The value returned by a program is not the same as the messages output by a program...
> 
> #include <stdio.h>
> 
> int main(int argc, char** argv)
> {
>   printf("Hello World\n");
>   return 0;
> }
> 
> The value returned is not "Hello World\n". You could probably have worked
> that out from the fact that the "system" function returns an int not a char *.
> 
> If you have support for pipes, that's the appropriate way to handle command 
> output. Did you actually try reading the stream created by "_popen"?

BTW I don't think your approach is sensible - as others have pointed out, the
distinction is far from simple and you'd be better off testing your files for
conforming to some processing rules than trying to draw a simple dichotomy.
However, I may as well try and deal with some of your misunderstandings...

[toc] | [prev] | [next] | [standalone]


#111813

FromDFS <nospam@dfs.com>
Date2017-06-08 09:21 -0400
Message-ID<ohbips$e1a$2@dont-email.me>
In reply to#111802
On 6/8/2017 5:13 AM, mark.bluemel@gmail.com wrote:
> On Thursday, 8 June 2017 04:51:09 UTC+1, DFS  wrote:
> 
>> The docs say
>>
>> "If command is not NULL, system returns the value that is returned by
>> the command interpreter. It returns the value 0 only if the command
>> interpreter returns the value 0."
>>
>> https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/system-wsystem
>>
>> So I'm not sure what's happening.
> 
> The value returned by a program is not the same as the messages output by a program...
> 
> #include <stdio.h>
> 
> int main(int argc, char** argv)
> {
>    printf("Hello World\n");
>    return 0;
> }
> 
> The value returned is not "Hello World\n". You could probably have worked
> that out from the fact that the "system" function returns an int not a char *.

If I wish hard enough will it return char data?



> If you have support for pipes, that's the appropriate way to handle command
> output. Did you actually try reading the stream created by "_popen"?

I did.  _popen returns the output of 'file', but crashes my program.

http://imgur.com/a/NfnrL


int is_textfile(char *fname)
{
	//run the GNUWin32 file command
	char psBuffer[128];
	FILE *pPipe;

	char cmd[] = {0};
	sprintf(cmd,"file %s",fname);
		
	if((pPipe = _popen(cmd,"rt")) == NULL) {exit(1);}
	while(fgets(psBuffer, 128, pPipe))
	{
	   //how to check for 'ASCII'?
	   printf(psBuffer);    //this prints the stream
	}  		
	if (feof(pPipe)) {_pclose(pPipe);}
	return 0;
}


if (is_textfile(filein)!=0)    //CRASHES on this line
{
  printf("'%s' is not a text file.\n",filein);
  return -1;
}


Also, can you write the code to look for 'ASCII' in the psBuffer data? 
I tried strstr() and couldn't get it to work.

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web