FreeBASIC  0.91.0
io_printer.c
Go to the documentation of this file.
1 /* Linux printer driver */
2 
3 #include "../fb.h"
4 
5 /* DEV_LPT_INFO->driver_opaque := (FILE *) file_handle */
6 
7 static char lp_buf[256];
8 
9 static int exec_lp_cmd( const char *cmd, int test_default )
10 {
11  int have_default = TRUE; // Assume a default printer
12  int result = -1;
13 
14  FILE *fp = popen( cmd, "r" );
15  if( fp ) {
16  while( !feof( fp ) ) {
17  if( !fgets( lp_buf, 256, fp ) ) {
18  if( test_default && have_default && (strlen( lp_buf ) > 2) )
19  if( (lp_buf[0] == 'n' || lp_buf[0] == 'N') &&
20  (lp_buf[1] == 'o' || lp_buf[1] == 'O') )
21  have_default = FALSE;
22  }
23  }
24 
25  result = pclose( fp ) >> 8;
26 
27  if( test_default && !have_default )
28  result = -1;
29  }
30 
31  return result;
32 }
33 
34 int fb_PrinterOpen( DEV_LPT_INFO *devInfo, int iPort, const char *pszDeviceRaw )
35 {
36  int result;
37  char *filename = NULL;
38  FILE *fp;
39 
40  DEV_LPT_PROTOCOL *lpt_proto;
41  if ( !fb_DevLptParseProtocol( &lpt_proto, pszDeviceRaw, strlen(pszDeviceRaw), TRUE ) )
42  {
43  if( lpt_proto!=NULL )
44  free(lpt_proto);
46  }
47 
48  devInfo->iPort = iPort;
49 
50  if( devInfo->iPort==0 ) {
51  /* Use spooler */
52 
53  /* create a buffer for our commands */
54  filename = alloca( strlen(pszDeviceRaw) + 64 );
55 
56  /* set destination, if not default */
57  if( lpt_proto->name && *lpt_proto->name )
58  {
59  /* does printer exist */
60  strcpy(filename, "lpstat -v \"");
61  strcat(filename, lpt_proto->name);
62  strcat(filename, "\" 2>&1 ");
63  if( exec_lp_cmd( filename, FALSE ) != 0 )
64  {
65  if( lpt_proto!=NULL )
66  free(lpt_proto);
68  }
69 
70  /* build command for spooler */
71  strcpy(filename, "lp ");
72  strcat(filename, "-d \"");
73  strcat(filename, lpt_proto->name);
74  strcat(filename, "\" ");
75  }
76  else
77  {
78  /* is there a default printer */
79  strcpy(filename, "lpstat -d 2>&1");
80  if( exec_lp_cmd( filename, TRUE ) != 0 )
81  {
82  if( lpt_proto!=NULL )
83  free(lpt_proto);
85  }
86  /* build command for spooler */
87  strcpy(filename, "lp ");
88  }
89 
90  /* set title, if not default */
91  if( *lpt_proto->title )
92  {
93  strcat(filename, "-t \"");
94  strcat(filename, lpt_proto->title);
95  strcat(filename, "\"");
96  }
97  else
98  {
99  strcat(filename, "-t \"FreeBASIC document\"");
100  }
101 
102  /* do not print job id */
103  strcat(filename, " -s -");
104 
105  {
106  char *ptr = filename;
107  while ((ptr = strpbrk(ptr, "`&;|>^$\\")) != NULL)
108  *ptr = '_';
109  }
110 
111  /* do not print error messages */
112  strcat(filename, " &> /dev/null");
113 
114  fp = popen( filename, "w" );
115  if(fp == NULL )
116  {
117  devInfo->driver_opaque = NULL;
119  }
120  else
121  {
122  devInfo->driver_opaque = fp;
123  result = fb_ErrorSetNum( FB_RTERROR_OK );
124  }
125 
126  } else {
127  /* use direct port io */
128  filename = alloca( 16 );
129  sprintf(filename, "/dev/lp%d", (devInfo->iPort-1));
130  fp = fopen(filename, "wb");
131 
132  if( fp==NULL ) {
133  devInfo->driver_opaque = NULL;
135  } else {
136  devInfo->driver_opaque = fp;
137  result = fb_ErrorSetNum( FB_RTERROR_OK );
138  }
139 
140  }
141 
142  if( lpt_proto!=NULL )
143  free(lpt_proto);
144 
145  return result;
146 }
147 
148 int fb_PrinterWrite( DEV_LPT_INFO *devInfo, const void *data, size_t length )
149 {
150  FILE *fp = (FILE*) devInfo->driver_opaque;
151  if( fwrite( data, length, 1, fp ) != 1 ) {
153  }
154  return fb_ErrorSetNum( FB_RTERROR_OK );
155 }
156 
157 int fb_PrinterWriteWstr( DEV_LPT_INFO *devInfo, const FB_WCHAR *buffer, size_t chars )
158 {
159  FILE *fp = (FILE *) devInfo->driver_opaque;
160 
161  /* !!!FIXME!!! is this ok? */
162  ssize_t bytes;
163  char *temp = alloca( chars * 4 + 1 );
164 
165  fb_WCharToUTF( FB_FILE_ENCOD_UTF8, buffer, chars, temp, &bytes );
166  /* add null-term */
167  temp[bytes] = '\0';
168 
169  if( fwrite( temp, bytes, 1, fp ) != 1 )
171 
172  return fb_ErrorSetNum( FB_RTERROR_OK );
173 }
174 
175 
177 {
178  if( devInfo->iPort == 0 )
179  {
180  /* close spooler */
181  int result = ( pclose( (FILE *) devInfo->driver_opaque ) >> 8 );
182  devInfo->driver_opaque = NULL;
183  if( result )
185  }
186  else
187  {
188  /* close direct port io */
189  fclose( (FILE *) devInfo->driver_opaque );
190  devInfo->driver_opaque = NULL;
191  }
192 
193  return fb_ErrorSetNum( FB_RTERROR_OK );
194 }