[UnixCompendium] / trunk / unix.info-7 Repository:
ViewVC logotype

Annotation of /trunk/unix.info-7

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (view) (download)

1 : root 1 This is unix.info, produced by makeinfo version 4.0 from unix.texinfo.
2 :    
3 :     
4 :     File: unix.info, Node: lex and yacc, Next: Ex 6, Prev: Database example in C, Up: C programming
5 :    
6 :     Text parsing tools: `lex' and `yacc'
7 :     ====================================
8 :    
9 :     _This section is a taster only. You only need to know what lex and
10 :     yacc are, not how they work._
11 :    
12 :     `lex' and `yacc' are two tools for the C programmer who wishes to
13 :     make a text parser. A text parser is a program which reads a text file
14 :     and interprets the symbols in it. Every programming language must
15 :     include a text parser, for instance.
16 :    
17 :     The `yacc' (yet another compiler compiler) program generates C code
18 :     which parses a textfile, given a description of the syntax rules for
19 :     the file. In other words, we define the logical structure of the text
20 :     file, according to the way we wish to interpret it and give the rules
21 :     to `yacc'. `yacc' produces C code from this which does the job.
22 :    
23 :     `lex' is a `lexer'. It is normally used together with `yacc'. `lex'
24 :     _tokenizes_ or identifies symbols in a file. What that means is that it
25 :     reads in a file and matches _types_ of string in the file which are
26 :     defined in terms of regular expressions by the programmer, and returns
27 :     symbolic values for those strings.
28 :    
29 :     Although `lex' can be used by independently of `yacc', it is
30 :     normally used to identify the different _types_ of string which define
31 :     the syntax of a file. For example, suppose `yacc' was parsing a C
32 :     program. On the beginning of a line, it might expect to find either a
33 :     variable name or a preprocessor symbol. A variable name is just a
34 :     string consisting of characters from the set `0-9a-Z_', whereas a
35 :     preprocessor command always starts with the character `#'. `yacc'
36 :     passes control to `lex' which reads the file and matches the first
37 :     object on the line. If it finds a variable, it returns to `yacc' a
38 :     _token_ which is a number or value corresponding to `variable'.
39 :     Similarly, if it finds a preprocessor command, it returns a token for
40 :     that. If it doesn't match either type it returns something else and
41 :     `yacc' signals a syntax error.
42 :    
43 :     Here is a `yacc' file which parses a file consisting of lines of the
44 :     form a+b, where $a$ and $b$ are numbers - any other syntax is incorrect.
45 :     We could have used this later in the example program for the
46 :     client-server example, *Note Sockets::.
47 :    
48 :     You can learn more about lex and yacc in _"Lex and Yacc", J. Levine,
49 :     T. Mason and D. Brown, O'Reilly and Assoc._
50 :    
51 :     %{
52 :     /*******************************************************************/
53 :     /* */
54 :     /* PARSER for a + b protocol */
55 :     /* */
56 :     /* The section between the single %'s gets copied verbatim into */
57 :     /* the resulting C code yacc generates -- including this comment! */
58 :     /* */
59 :     /*******************************************************************/
60 :    
61 :     #include <stdio.h>
62 :    
63 :     extern char *yytext;
64 :    
65 :     %}
66 :    
67 :     %token NUMBER PLUS
68 :    
69 :     %%
70 :    
71 :     specification: { yyerror("Warning: invalid statement");}
72 :     | statement;
73 :    
74 :     statement: NUMBER PLUS NUMBER;
75 :    
76 :     The lexer to go with this parser generates the tokens NUMBER and PLUS
77 :     used by `yacc':
78 :    
79 :     %{
80 :     /*******************************************************************/
81 :     /* */
82 :     /* LEXER for a + b protocol */
83 :     /* */
84 :     /* Returns token types NUMBER and PLUS to yacc, one at a time */
85 :     /* */
86 :     /*******************************************************************/
87 :    
88 :    
89 :     #include "y.tab.h" /* yacc produces this -- need this line! */
90 :    
91 :    
92 :     %}
93 :    
94 :    
95 :     number [0-9]+
96 :     plus [+]
97 :    
98 :     %%
99 :    
100 :    
101 :     number {
102 :     return NUMBER;
103 :     }
104 :    
105 :     plus {
106 :     return PLUS;
107 :     }
108 :    
109 :     . {
110 :     return yytext[0];
111 :     }
112 :    
113 :     %%
114 :    
115 :     /* EOF */
116 :    
117 :     The main program which uses `yacc' and `lex' looks like this:
118 :    
119 :    
120 :     extern FILE *yyin;
121 :    
122 :     main ()
123 :    
124 :     {
125 :    
126 :     if ((yyin = fopen("My_Input_File","r")) == NULL) /* Open file */
127 :     {
128 :     printf("Can't open file\n");
129 :     exit (1);
130 :     }
131 :    
132 :     while (!feof(yyin))
133 :     {
134 :     yyparse();
135 :     }
136 :    
137 :     fclose (yyin);
138 :     }
139 :    
140 :     
141 :     File: unix.info, Node: Ex 6, Prev: lex and yacc, Up: C programming
142 :    
143 :     Exercises
144 :     =========
145 :    
146 :     1. Write a daemon program with a signal handler which makes a log of
147 :     the heaviest (maximum cpu) process running, every five minutes. The
148 :     program should exit if the log file becomes greater than 5-kbytes.
149 :    
150 :     2. Rewrite in C the perl program which lists all the files in the
151 :     current directory containing a certain string.
152 :    
153 :     3. Write a version of `more' which prints control characters safely.
154 :     See the `cat -e' command.
155 :    
156 :     4. Write a Makefile to create a shared library from a number of
157 :     object files.
158 :    
159 :    
160 :     
161 :     File: unix.info, Node: Network programming, Next: Programming idioms, Prev: C programming, Up: Top
162 :    
163 :     Network Programming
164 :     *******************
165 :    
166 :     Client-server communication is the basis of modern operating system
167 :     technology. The Unix socket mechanism makes stream-based communication
168 :     virtually transparent.
169 :    
170 :     * Menu:
171 :    
172 :     * Sockets::
173 :     * Multithreading a server::
174 :     * System databases::
175 :     * DNS::
176 :     * C and NFS::
177 :     * Ex 7::
178 :    
179 :     
180 :     File: unix.info, Node: Sockets, Next: Multithreading a server, Prev: Network programming, Up: Network programming
181 :    
182 :     Socket streams
183 :     ==============
184 :    
185 :     Analogous to filestreams are _sockets_ or TCP/IP _network
186 :     connections_. A socket is a two-way (read/write) pseudo-file node. An
187 :     open socket stream is like an open file-descriptor. Berkeley sockets
188 :     are part of the standard C library.
189 :    
190 :     There are two main kinds of socket: TCP/IP sockets and Unix domain
191 :     sockets. Unix sockets can be used to provide local interprocess
192 :     communication using a filestream communication protocol. TCP/IP sockets
193 :     open file descriptors across the network. A TCP/IP socket is a file
194 :     stream associated with an IP address and a port number. We write to a
195 :     socket descriptor just as with a file descriptor, either with `write()'
196 :     or using `send()'.
197 :    
198 :     When sending binary data over a network we have to be careful about
199 :     machine level representations of data. Operating systems (actually the
200 :     hardware they run on) fall into two categories known as _big endian_
201 :     and _little endian_. The names refer to the _byte-order_ of numerical
202 :     representations. The names indicate how large integers (which require
203 :     say 32 bits or more) are stored in memory. Little endian systems store
204 :     the least significant byte first, while big endian systems store the
205 :     most significant byte first. For example, the representation of the
206 :     number 34,677,374 has either of these forms.
207 :    
208 :    
209 :     -----------------------------------
210 :     Big | 2 | 17 | 34 | 126 |
211 :     -----------------------------------
212 :    
213 :     -----------------------------------
214 :     Little | 126 | 34 | 17 | 2 |
215 :     -----------------------------------
216 :    
217 :     Obviously if we are transferring data from one host to another, both
218 :     hosts have to agree on the data representation otherwise there would be
219 :     disastrous consequences. This means that there has to be a common
220 :     standard of _network byte ordering_. For example, Solaris (SPARC
221 :     hardware) uses network byte ordering (big endian), while GNU/Linux
222 :     (Intel hardware) uses the opposite (little endian). This means that
223 :     Intel systems have to convert the format every time something is
224 :     transmitted over the network. Unix systems provide generic functions
225 :     for converting between host-byteorder and network-byteorder for small
226 :     and long integer data:
227 :    
228 :     htonl, htons, ntohl, ntohs
229 :    
230 :     Here we list two example programs which show how to make a client-server
231 :     pair. The server enters a loop, and listens for connections from any
232 :     clients (the generic address `INADDR_ANY' is a wildcard for any address
233 :     on the current local network segment). The client program sends
234 :     requests to the server as a protocol in the form of a string of the type
235 :     `a + b'. Normally `a' and `b' are numbers, in which case the server
236 :     returns their sum to the client. If the message has the special form
237 :     `halt + *', where the star is arbitrary, then the server shuts down.
238 :     Any other form of message results in an error, which the server signals
239 :     to the client.
240 :    
241 :     The basic structure of the client-server components in terms of
242 :     system calls is this:
243 :    
244 :    
245 :     Client:
246 :    
247 :     socket() CREATE A SOCKET
248 :     connect() CONTACT A SERVER SOCKET (IP + PORT)
249 :    
250 :     while (?)
251 :     {
252 :     send() SEND TO SERVER
253 :     recv() RECEIVE FROM SERVER
254 :     }
255 :    
256 :     Server:
257 :    
258 :     socket() CREATE A SOCKET
259 :     bind() ASSOCIATES THE SOCKET WITH A FIXED ADDRESS
260 :     listen() CREATE A LISTEN QUEUE
261 :    
262 :     while()
263 :     {
264 :     reply=accept() ACCEPT A CONNECTION REQUEST
265 :     recv() RECEIVE FROM CLIENT
266 :     send() SEND TO CLIENT
267 :     }
268 :    
269 :     /**********************************************************************/
270 :     /* */
271 :     /* The client part of a client-server pair. This simply takes two */
272 :     /* numbers and adds them together, returning the result to the client */
273 :     /* */
274 :     /* Compiled with: */
275 :     /* cc server.c */
276 :     /* */
277 :     /* User types: */
278 :     /* 3 + 5 */
279 :     /* a + b */
280 :     /* halt + server */
281 :     /**********************************************************************/
282 :    
283 :     #include <stdio.h>
284 :     #include <sys/types.h>
285 :     #include <sys/socket.h>
286 :     #include <netinet/in.h>
287 :     #include <netdb.h>
288 :    
289 :    
290 :     #define PORT 9000 /* Arbitrary non-reserved port */
291 :     #define HOST "nexus.iu.hioslo.no"
292 :     #define bufsize 20
293 :    
294 :     /**********************************************************************/
295 :     /* Main */
296 :     /**********************************************************************/
297 :    
298 :     main (argc,argv)
299 :    
300 :     int argc;
301 :     char *argv[];
302 :    
303 :     { struct sockaddr_in cin;
304 :     struct hostent *hp;
305 :     char buffer[bufsize];
306 :     int sd;
307 :    
308 :     if (argc != 4)
309 :     {
310 :     printf("syntax: client a + b\n");
311 :     exit(1);
312 :     }
313 :    
314 :     if ((hp = gethostbyname(HOST)) == NULL)
315 :     {
316 :     perror("gethostbyname: ");
317 :     exit(1);
318 :     }
319 :    
320 :     memset(&cin,0,sizeof(cin)); /* Another way to zero memory */
321 :    
322 :     cin.sin_family = AF_INET;
323 :     cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
324 :     cin.sin_port = htons(PORT);
325 :    
326 :     printf("Trying to connect to %s = %s\n",HOST,inet_ntoa(cin.sin_addr));
327 :    
328 :     if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1)
329 :     {
330 :     perror("socket");
331 :     exit(1);
332 :     }
333 :    
334 :     if (connect(sd,&cin,sizeof(cin)) == -1)
335 :     {
336 :     perror("connect");
337 :     exit(1);
338 :     }
339 :    
340 :     sprintf(buffer,"%s + %s",argv[1],argv[3]);
341 :    
342 :     if (send(sd,buffer,strlen(buffer),0) == -1)
343 :     {
344 :     perror ("send");
345 :     exit(1);
346 :     }
347 :    
348 :     if (recv(sd,buffer,bufsize,0) == -1)
349 :     {
350 :     perror("recv");
351 :     exit (1);
352 :     }
353 :    
354 :     printf ("Server responded with %s\n",buffer);
355 :    
356 :     close (sd);
357 :     unlink("./socket");
358 :     }
359 :    
360 :     /**********************************************************************/
361 :     /* */
362 :     /* The server part of a client-server pair. This simply takes two */
363 :     /* numbers and adds them together, returning the result to the client */
364 :     /* */
365 :     /* Compiled with: */
366 :     /* cc server.c */
367 :     /* */
368 :     /**********************************************************************/
369 :    
370 :     #include <stdio.h>
371 :     #include <sys/types.h>
372 :     #include <sys/socket.h>
373 :     #include <netinet/in.h>
374 :     #include <netdb.h>
375 :    
376 :    
377 :     #define PORT 9000
378 :     #define bufsize 20
379 :     #define queuesize 5
380 :     #define true 1
381 :     #define false 0
382 :    
383 :     /**********************************************************************/
384 :     /* Main */
385 :     /**********************************************************************/
386 :    
387 :     main ()
388 :    
389 :     { struct sockaddr_in cin;
390 :     struct sockaddr_in sin;
391 :     struct hostent *hp;
392 :     char buffer[bufsize];
393 :     int sd, sd_client, addrlen;
394 :    
395 :    
396 :     memset(&sin,0,sizeof(sin)); /* Another way to zero memory */
397 :     sin.sin_family = AF_INET;
398 :     sin.sin_addr.s_addr = INADDR_ANY; /* Broadcast address */
399 :     sin.sin_port = htons(PORT);
400 :    
401 :    
402 :     if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1)
403 :     {
404 :     perror("socket");
405 :     exit(1);
406 :     }
407 :    
408 :     if (bind(sd,&sin,sizeof(sin)) == -1) /* Must have this on server */
409 :     {
410 :     perror("bind");
411 :     exit(1);
412 :     }
413 :    
414 :     if (listen(sd,queuesize) == -1)
415 :     {
416 :     perror("listen");
417 :     exit(1);
418 :     }
419 :    
420 :     while (true)
421 :     {
422 :     if ((sd_client = accept(sd,&cin,&addrlen)) == -1)
423 :     {
424 :     perror("accept");
425 :     exit(1);
426 :     }
427 :    
428 :     if (recv(sd_client,buffer,sizeof(buffer),0) == -1)
429 :     {
430 :     perror("recv");
431 :     exit(1);
432 :     }
433 :    
434 :     if (!DoService(buffer))
435 :     {
436 :     break;
437 :     }
438 :    
439 :     if (send(sd_client,buffer,strlen(buffer),0) == -1)
440 :     {
441 :     perror("send");
442 :     exit(1);
443 :     }
444 :    
445 :     close (sd_client);
446 :     }
447 :    
448 :     close (sd);
449 :     printf("Server closing down...\n");
450 :     }
451 :    
452 :    
453 :     /**************************************************************/
454 :    
455 :     DoService(buffer)
456 :    
457 :     char *buffer;
458 :    
459 :     /* This is the protocol section. Here we must */
460 :     /* check that the incoming data are sensible */
461 :    
462 :     { int a=0,b=0;
463 :    
464 :     printf("Received: %s\n",buffer);
465 :     sscanf(buffer,"%d + %d\n",&a,&b);
466 :    
467 :     if (a > 0 && b> 0)
468 :     {
469 :     sprintf(buffer,"%d + %d = %d",a,b,a+b);
470 :     return true;
471 :     }
472 :     else
473 :     {
474 :     if (strncmp("halt",buffer,4) == 0)
475 :     {
476 :     sprintf(buffer,"Server closing down!");
477 :     return false;
478 :     }
479 :     else
480 :     {
481 :     sprintf(buffer,"Invalid protocol");
482 :     return true;
483 :     }
484 :     }
485 :     }
486 :    
487 :     In the example we use `streams' to implement a typical input/output
488 :     behaviour for C. A stream interface is a so-called reliable protocol.
489 :     There are other kinds of sockets too, called _unrealiable_, or UDP
490 :     sockets. Features to notice on the server are that we must bind to a
491 :     specific address. The client is always implicitly bound to an address
492 :     since a socket connection always originates from the machine on which
493 :     the client is running. On the server however we want to know which
494 :     addresses we shall be receiving requests from. In the above example we
495 :     use the generic wildcard address `INADDR_ANY' which means that any host
496 :     can connect to the server. Had we been more specific, we could have
497 :     limited communication to two machines only.
498 :    
499 :     By calling `listen()' we set up a queue for incoming connections.
500 :     Rather than forking a separate process to handle each request we set up
501 :     a queue of a certain depth. If we exceed this depth then new clients
502 :     rtying to connect will be refused connection.
503 :    
504 :     The `accept' call is the mechanism which extracts a `reply handle'
505 :     from the socket. Using the handle obtained from this call we can reply
506 :     to the client without having to open a special socket explicitly.
507 :    
508 :     An improved server side connection can be setup, reading the service
509 :     name from `/etc/services' and setting reusable socket options to avoid
510 :     busy signals, like this:
511 :    
512 :     struct sockaddr_in cin, sin;
513 :     struct servent *server;
514 :     int sd, addrlen = sizeof(cin);
515 :     int portnumber, yes=1;
516 :    
517 :     if ((server = getservbyname(SERVICE-NAME,"tcp")) == NULL)
518 :     {
519 :     CfLog(cferror,"Couldn't get cfengine service","getservbyname");
520 :     exit (1);
521 :     }
522 :    
523 :     bzero(&cin,sizeof(cin));
524 :    
525 :     /* Service returns network byte order */
526 :    
527 :     sin.sin_port = (unsigned short)(server->s_port);
528 :     sin.sin_addr.s_addr = INADDR_ANY;
529 :     sin.sin_family = AF_INET;
530 :    
531 :     if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1)
532 :     {
533 :     CfLog(cferror,"Couldn't open socket","socket");
534 :     exit (1);
535 :     }
536 :    
537 :     if (setsockopt (sd, SOL_SOCKET, SO_REUSEADDR,
538 :     (char *) &yes, sizeof (int)) == -1)
539 :     {
540 :     CfLog(cferror,"Couldn't set socket options","sockopt");
541 :     exit (1);
542 :     }
543 :    
544 :    
545 :     if (bind(sd,(struct sockaddr *)&sin,sizeof(sin)) == -1)
546 :     {
547 :    
548 :     }
549 :    
550 :     /* etc */
551 :    
552 :     
553 :     File: unix.info, Node: Multithreading a server, Next: System databases, Prev: Sockets, Up: Network programming
554 :    
555 :     Multithreading a server
556 :     =======================
557 :    
558 :     All the arguments must be collected into a struct, since only one
559 :     argument pointer can be sent to the pthread functions.
560 :    
561 :    
562 :     #include <pthread.h>
563 :    
564 :    
565 :     SpawnCfGetFile(args)
566 :    
567 :     struct cfd_thread_arg *args;
568 :    
569 :     { pthread_t tid;
570 :     void *CfGetFile();
571 :    
572 :     pthread_attr_init(&PTHREADDEFAULTS);
573 :     pthread_attr_setdetachstate(&PTHREADDEFAULTS,PTHREAD_CREATE_DETACHED);
574 :    
575 :     if (pthread_create(&tid,&PTHREADDEFAULTS,CfGetFile,args) != 0)
576 :     {
577 :     CfLog(cferror,"pthread_create failed","create");
578 :     CfGetFile(args);
579 :     }
580 :    
581 :     pthread_attr_destroy(&PTHREADDEFAULTS);
582 :     }
583 :    
584 :     /***************************************************************/
585 :    
586 :     void *CfGetFile(args)
587 :    
588 :     struct cfd_thread_arg *args;
589 :    
590 :     { pthread_mutex_t mutex;
591 :    
592 :     if (pthread_mutex_lock(&mutex) != 0)
593 :     {
594 :     CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock");
595 :     free(args->replyfile); /* from strdup in each thread */
596 :     DeleteConn(args->connect);
597 :     free((char *)args);
598 :     return NULL;
599 :     }
600 :    
601 :     ACTIVE_THREADS++; /* Global variable */
602 :    
603 :     if (pthread_mutex_unlock(&mutex) != 0)
604 :     {
605 :     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
606 :     }
607 :    
608 :    
609 :     /* send data */
610 :    
611 :     if (pthread_mutex_lock(&mutex) != 0)
612 :     {
613 :     CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock");
614 :     return;
615 :     }
616 :    
617 :     ACTIVE_THREADS--;
618 :    
619 :     if (pthread_mutex_unlock(&mutex) != 0)
620 :     {
621 :     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
622 :     }
623 :    
624 :     #endif
625 :    
626 :     return NULL;
627 :     }
628 :    
629 :     
630 :     File: unix.info, Node: System databases, Next: DNS, Prev: Multithreading a server, Up: Network programming
631 :    
632 :     System databases
633 :     ================
634 :    
635 :     The C library calls which query the databases are, amongst others,
636 :     getpwnam GET PASSWORD DATA BY NAME
637 :     getpwuid GET PASSWORD DATA BY UID
638 :     getgrnam GET GROUP DATA BY NAME
639 :     gethostent GET ENTRY IN HOSTS DATABASE
640 :     getnetgrent GET ENTRY IN NETGROUPS DATABASE
641 :     getservbyname GET SERVIVE BY NAME
642 :     getservbyport GET SERVICE BY PORT
643 :     get protobyname GET PROTOCOL BY NAME
644 :    
645 :     For a complete list and how to use these, see the UNIX manual.
646 :    
647 :     The following example shows how to read the password file of the
648 :     system. The functions used here can be used regardless of whether the
649 :     network information service (NIS) is in use. The data are returned in a
650 :     structure which is defined in `/usr/include/pwd.h'.
651 :    
652 :     /******************************************************************/
653 :     /* */
654 :     /* Read the passwd file by name and sequentially */
655 :     /* */
656 :     /******************************************************************/
657 :    
658 :     #include <unistd.h>
659 :     #include <pwd.h>
660 :    
661 :     main ()
662 :    
663 :     { uid_t uid;
664 :     struct passwd *pw;
665 :    
666 :     uid = getuid();
667 :    
668 :     pw = getpwuid(uid);
669 :    
670 :     printf ("Your login name is %s\n",pw->pw_name);
671 :    
672 :     printf ("Now here comes the whole file!\n\n");
673 :    
674 :     setpwent();
675 :    
676 :     while (getpwent())
677 :     {
678 :     printf ("%s:%s:%s\n",pw->pw_name,pw->pw_gecos,pw->pw_dir);
679 :     }
680 :    
681 :     endpwent();
682 :     }
683 :    
684 :     
685 :     File: unix.info, Node: DNS, Next: C and NFS, Prev: System databases, Up: Network programming
686 :    
687 :     DNS - The Domain Name Service
688 :     =============================
689 :    
690 :     The second network database service is that which converts host and
691 :     domain names into IP numbers and vice versa. This is the domain name
692 :     service, usually implemented by the BIND (Berkeley Internet Name
693 :     Domain) software. The information here concerns version 4.9 of this
694 :     software.
695 :    
696 :     * Menu:
697 :    
698 :     * gethostbyname::
699 :    
700 :     
701 :     File: unix.info, Node: gethostbyname, Prev: DNS, Up: DNS
702 :    
703 :     gethostbyname()
704 :     ---------------
705 :    
706 :     This is perhaps the most important function form hostname lookup.
707 :     `gethostbyname()' gets its information either from files, NIS or DNS.
708 :     Its behaviour is configured by the files mentioned above, *Note DNS::.
709 :     It is used to look up the IP address of a named host (including domain
710 :     name if DNS is used). On the configurable systems described above, the
711 :     full list of servers is queried until a reply is obtained. The order
712 :     in which the different services are queried is important here since DNS
713 :     returns a _fully qualified name_ (host name plus domain name) whereas
714 :     NIS and the `/etc/hosts' file database return only a hostname.
715 :    
716 :     gethostbyname returns data in the form of a pointer to a static data
717 :     structure. The syntax is
718 :     #include <netdb.h>
719 :    
720 :     struct hostent *hp;
721 :    
722 :     hp = gethostbyname("myhost.domain.country")
723 :    
724 :     The resulting structure varies on different implementations of UNIX,
725 :     but the `old BSD standard' is of the form:
726 :    
727 :     struct hostent
728 :     {
729 :     char *h_name; /* official name of host */
730 :     char **h_aliases; /* alias list */
731 :     int h_addrtype; /* host address type */
732 :     int h_length; /* length of address */
733 :     char **h_addr_list; /* list of addresses from name server */
734 :     };
735 :    
736 :     #define h_addr h_addr_list[0] /* address, for backward compatiblity */
737 :    
738 :     The structure contains a list of addresses and or aliases from the
739 :     nameserver. The interesting quantity is usually extracted by means of
740 :     the macro `h_addr' whcih gives the first value in the address list,
741 :     though officially one should examine the whole list now.
742 :    
743 :     This value is a pointer which can be converted into a text form by
744 :     the following hideous type transformation:
745 :    
746 :     #include <sys/types.h>
747 :     #include <sys/socket.h>
748 :     #include <netinet/in.h>
749 :    
750 :     struct sockaddr_in sin;
751 :    
752 :     cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
753 :    
754 :     printf("IP address = %s\n",inet_ntoa(cin.sin_addr));
755 :    
756 :     See the client program in the first section of this chapter for an
757 :     example of its use.
758 :    
759 :     
760 :     File: unix.info, Node: C and NFS, Next: Ex 7, Prev: DNS, Up: Network programming
761 :    
762 :     C support for NFS
763 :     =================
764 :    
765 :     The support for NFS mounting in the standard C library is through
766 :     two sources. NFS is based on the Sun's RPC system, so the basic calls
767 :     are only instances of standard RPC protocols.
768 :    
769 :     The C functions in the standard input/output library can be used to
770 :     access NFS filesystems. Since NFS imitates the UNIX filesystem as
771 :     closely as possible, NFS filesystems can be mounted in exactly the same
772 :     way as ordinary filesystems. Unfortunately, the C functions which
773 :     perform the mount operation in UNIX and depressingly non-standard. They
774 :     differ on almost every implementation of UNIX.
775 :    
776 :     The basic function which mounts a filesystem, in `mount' (see `man
777 :     (2) mount'). The mount table is stored in a file _/etc/mtab_ on BSD
778 :     systems (again the name varies wildly from UNIX to UNIX, mnttab on HPUX
779 :     for instance). The file _/etc/rmtab_ on an NFS server contains a list
780 :     of remote-mounted filesystems which are mounted by remote clients. C
781 :     functions exist which can read the filesystem tables and place the
782 :     resulting data in C struct types. Alas, these struct defintions are
783 :     also quite different on different systems. See
784 :     `/usr/include/sys/mount.h', so the user wishing to write
785 :     system-independent code is confounded at the lowest level.
786 :    
787 :     
788 :     File: unix.info, Node: Ex 7, Prev: C and NFS, Up: Network programming
789 :    
790 :     Exercises
791 :     =========
792 :    
793 :     1. Use `gethostbyname()' to make a simple program like `nslookup'
794 :     which gives the internet address of a named host.
795 :    
796 :     2. Modify the client server example above to make a `remote ls'
797 :     command called `rls'. You should be able to use the syntax
798 :     rls (options) hostname:/path/to/file
799 :    
800 :     
801 :     File: unix.info, Node: Programming idioms, Next: Variable Index, Prev: Network programming, Up: Top
802 :    
803 :     Summary of programming idioms.
804 :     ******************************
805 :    
806 :     _True and false_
807 :    
808 :     # C shell
809 :    
810 :     True - non-zero/non-empty value
811 :     False - zero or null string
812 :    
813 :     # Bourne shell
814 :    
815 :     True - 0 returned by shell command
816 :     False - non-zero returned by shell command
817 :    
818 :     ( Note that "test" converts from C shell style to Bourne shell)
819 :    
820 :     # Perl
821 :    
822 :     True - non-zero/non-empty value
823 :     False - zero or null string
824 :    
825 :     /* C */
826 :    
827 :     True - non zero integer
828 :     False - zero integer
829 :    
830 :     _Input from tty_
831 :     # C shell
832 :    
833 :     $<
834 :    
835 :     # Bourne shell
836 :    
837 :     line
838 :     read
839 :    
840 :     # Perl
841 :    
842 :     <STDIN>
843 :    
844 :     /* C */
845 :    
846 :     scanf
847 :    
848 :     _Redirection of I/O_
849 :    
850 :     # C shell
851 :    
852 :     COMMAND > file
853 :     COMMAND >& file
854 :     COMMAND >> file
855 :     COMMAND1 | COMMAND2
856 :    
857 :     # Bourne shell
858 :    
859 :     COMMAND > file
860 :     COMMAND > file 2>&1
861 :     COMMAND >> file
862 :     COMMAND1 | COMMAND2
863 :    
864 :     # Perl
865 :    
866 :     open (HANDLE,">file")
867 :     open (HANDLE,">file 2>&1")
868 :     open (HANDLE,">>file")
869 :     open (HANDLE,"command1 |")
870 :     open (HANDLE,"| command2")
871 :    
872 :     /* C */
873 :    
874 :     fopen ("file","w"); printf(..)
875 :     fopen ("file","w"); printf(..); fprintf(stderr,..)
876 :     fopen ("file","a"); printf(..)
877 :     popen ("COMMAND1","r")
878 :     popen ("COMMAND2","w")
879 :    
880 :     _Loops and tests_
881 :    
882 :     /* C */ Shell
883 :    
884 :     foreach end if then else endif
885 :     while end switch case breaksw endsw
886 :     repeat
887 :    
888 :     # Bourne shell
889 :    
890 :     while do done if then else fi
891 :     until do done case in esac
892 :     for in do done
893 :    
894 :     # Perl
895 :    
896 :     while if then else
897 :     for unless else
898 :     foreach
899 :     until
900 :     do while
901 :     do until
902 :    
903 :     /* C */
904 :    
905 :     while if then else
906 :     do while switch case
907 :     for
908 :    
909 :     _Arguments from command line_
910 :     # C shell
911 :    
912 :     $argv[]
913 :     $#argv
914 :    
915 :     # Bourne Shell
916 :    
917 :     $1, $2, $3... $*
918 :     $#
919 :    
920 :     # Perl
921 :    
922 :     $ARGV[]
923 :     $#ARGV
924 :    
925 :     /* C */
926 :    
927 :     char argv[][]
928 :     int argc
929 :    
930 :     _Arithmetic_
931 :     # C shell
932 :    
933 :     a = $b + $c
934 :    
935 :     # Bourne shell
936 :    
937 :     a = `expr $b + $c`
938 :    
939 :     # Perl
940 :    
941 :     $a = $b + $c;
942 :    
943 :     /* C */
944 :    
945 :     a = b + c;
946 :    
947 :     _Numerical comparison_
948 :     # C shell
949 :    
950 :     if ( $x == $y ) then
951 :     endif
952 :    
953 :     # Bourne shell
954 :    
955 :     if [ $x -eq $y ]; then
956 :     fi
957 :    
958 :     # Perl
959 :    
960 :     if ( $x == $y )
961 :     {
962 :     }
963 :    
964 :     /* C */
965 :    
966 :     if ( x == y )
967 :     {
968 :     }
969 :    
970 :     _String comparison_
971 :    
972 :     # C shell
973 :    
974 :     if ( $x == $y ) then
975 :     endif
976 :    
977 :     # Bourne shell
978 :    
979 :     if [ $x = $y ]; then
980 :     fi
981 :    
982 :     # Perl
983 :    
984 :     if ( $x eq $y ) then
985 :     {
986 :     }
987 :    
988 :     /* C */
989 :    
990 :     if (strcmp(x,y) == 0)
991 :     {
992 :     }
993 :    
994 :     _Opening a file_
995 :    
996 :     # C shell, Bourne shell - cannot be done (pipes only)
997 :    
998 :     # Perl
999 :    
1000 :     open (READ_HANDLE,"filename");
1001 :     open (WRITE_HANDLE,"> filename");
1002 :     open (APPEND_HANDLE,">> filename");
1003 :    
1004 :     /* C */
1005 :    
1006 :     FILE *fp;
1007 :    
1008 :     fp = fopen ("file","r");
1009 :     fp = fopen ("file","w");
1010 :     fp = fopen ("file","a");
1011 :    
1012 :     _Opening a directory_
1013 :    
1014 :     # C shell
1015 :    
1016 :     foreach dir ( DIRECTORY/* )
1017 :     ...
1018 :     end
1019 :    
1020 :     # Bourne shell
1021 :    
1022 :     for dir in DIRECTORY/* ;
1023 :     do
1024 :     ...
1025 :     done
1026 :    
1027 :     # Perl
1028 :    
1029 :     opendir (HANDLE,"DIRECTORY") || die;
1030 :    
1031 :     while ($entry = readdir(HANDLE))
1032 :     {
1033 :     }
1034 :    
1035 :     closedir(HANDLE);
1036 :    
1037 :     # C
1038 :    
1039 :     #include <dirent.h>
1040 :     DIR *dirh;
1041 :     struct dirent *dirp;
1042 :    
1043 :     if ((dirh = opendir(name)) == NULL)
1044 :     {
1045 :     perror("opendir")
1046 :     exit(1);
1047 :     }
1048 :    
1049 :     for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh))
1050 :     {
1051 :     ... /* dirp->d_name points to child */
1052 :     }
1053 :    
1054 :     closedir(dirh);
1055 :    
1056 :     _Testing file types_
1057 :    
1058 :     # C shell
1059 :    
1060 :     if ( -f file ) # plain file
1061 :     if ( -d file ) # directory
1062 :    
1063 :     # Bourne shell
1064 :    
1065 :     if [ -f file ] # plain file
1066 :     if [ -d file ] # directory
1067 :    
1068 :     # Perl
1069 :    
1070 :     if ( -f file ) # plain file
1071 :     if ( -d file ) # directory
1072 :     if ( -l file ) # symbolic link
1073 :    
1074 :     /* C */
1075 :    
1076 :     #include <sys/stat.h>
1077 :    
1078 :     struct stat statvar;
1079 :    
1080 :     stat("file", &statvar);
1081 :    
1082 :     if (S_ISREG(statvar.mode)) /* plain file */
1083 :     if (S_ISDIR(statvar.mode)) /* directory */
1084 :    
1085 :     lstat("file", &statvar);
1086 :    
1087 :     if (S_ISLNK(statvar.mode)) /* symbolic link */
1088 :    
1089 :     
1090 :     File: unix.info, Node: Variable Index, Next: Concept Index, Prev: Programming idioms, Up: Top
1091 :    
1092 :     Command and Variable Index
1093 :     **************************
1094 :    
1095 :     * Menu:
1096 :    
1097 :     * ! in sh: Tests in sh.
1098 :     * ! not: Arithmetic.
1099 :     * !=: Tests and conditions.
1100 :     * != in sh: Tests in sh.
1101 :     * !~: Tests and conditions.
1102 :     * ": Single and double quotes.
1103 :     * $ in regular expressions: Regular expressions.
1104 :     * $< in make: Makefiles.
1105 :     * $? in make: Makefiles.
1106 :     * $@ in make: Makefiles.
1107 :     * &: Pipes and redirection.
1108 :     * & AND: Arithmetic.
1109 :     * ': Single and double quotes.
1110 :     * () in csh: Arrays.
1111 :     * *: Wildcards.
1112 :     * * in regular expressions: Regular expressions.
1113 :     * +: Arithmetic.
1114 :     * + in regular expressions: Regular expressions.
1115 :     * ++: Arithmetic.
1116 :     * +=: Arithmetic.
1117 :     * -: Arithmetic.
1118 :     * --: Arithmetic.
1119 :     * --help: How to use this reference guide.
1120 :     * -=: Arithmetic.
1121 :     * -a in sh: Tests in sh.
1122 :     * -d FILE: Tests and conditions.
1123 :     * -d in sh: Tests in sh.
1124 :     * -e FILE: Tests and conditions.
1125 :     * -eq in sh: Tests in sh.
1126 :     * -f FILE: Tests and conditions.
1127 :     * -f in sh: Tests in sh.
1128 :     * -g in sh: Tests in sh.
1129 :     * -ge in sh: Tests in sh.
1130 :     * -gt in sh: Tests in sh.
1131 :     * -h: How to use this reference guide.
1132 :     * -le in sh: Tests in sh.
1133 :     * -lt in sh: Tests in sh.
1134 :     * -ne in sh: Tests in sh.
1135 :     * -o in sh: Tests in sh.
1136 :     * -r FILE: Tests and conditions.
1137 :     * -r in sh: Tests in sh.
1138 :     * -s in sh: Tests in sh.
1139 :     * -u in sh: Tests in sh.
1140 :     * -w FILE: Tests and conditions.
1141 :     * -w in sh: Tests in sh.
1142 :     * -x in sh: Tests in sh.
1143 :     * -z FILE: Tests and conditions.
1144 :     * -z in perl: search and replace.
1145 :     * .: Stdin.
1146 :     * . in regular expressions: Regular expressions.
1147 :     * ..: Stdin.
1148 :     * .cshrc: .profile.
1149 :     * .profile: .profile.
1150 :     * .xsession: How to set up X windows.
1151 :     * /bin: The file hierarchy.
1152 :     * /bin/csh: Kernel and shell.
1153 :     * /bin/sh: Kernel and shell.
1154 :     * /dev: The file hierarchy.
1155 :     * /devices: The file hierarchy.
1156 :     * /etc: The file hierarchy.
1157 :     * /export: The file hierarchy.
1158 :     * /home: The file hierarchy.
1159 :     * /sbin: The file hierarchy.
1160 :     * /sys: The file hierarchy.
1161 :     * /users: The file hierarchy.
1162 :     * /usr: The file hierarchy.
1163 :     * /usr/bin: The file hierarchy.
1164 :     * /usr/local: The file hierarchy.
1165 :     * /var: The file hierarchy.
1166 :     * /var/adm: The file hierarchy.
1167 :     * /vr/spool: The file hierarchy.
1168 :     * :e: Extracting parts of a pathname.
1169 :     * :h: Extracting parts of a pathname.
1170 :     * :r: Extracting parts of a pathname.
1171 :     * :t: Extracting parts of a pathname.
1172 :     * < <1>: Tests and conditions.
1173 :     * <: Pipes and redirection.
1174 :     * < less than: Arithmetic.
1175 :     * <<: Pipes and redirection.
1176 :     * << shift: Arithmetic.
1177 :     * <=: Tests and conditions.
1178 :     * <CTRL-A>: Keys.
1179 :     * <CTRL-C>: Keys.
1180 :     * <CTRL-D>: Keys.
1181 :     * <CTRL-E>: Keys.
1182 :     * <CTRL-L>: Keys.
1183 :     * <CTRL-Z>: Keys.
1184 :     * = assignment: Arithmetic.
1185 :     * = in sh: Tests in sh.
1186 :     * == <1>: Tests and conditions.
1187 :     * ==: Scalar variables.
1188 :     * == equal to (compare): Arithmetic.
1189 :     * =~: Tests and conditions.
1190 :     * > <1>: Pipes and redirection.
1191 :     * >: Tests and conditions.
1192 :     * > greater than: Arithmetic.
1193 :     * >=: Tests and conditions.
1194 :     * >>: Pipes and redirection.
1195 :     * >> shift: Arithmetic.
1196 :     * ?: Wildcards.
1197 :     * ? in regular expressions: Regular expressions.
1198 :     * []: Wildcards.
1199 :     * [] in regular expressions: Regular expressions.
1200 :     * ^ in regular expressions: Regular expressions.
1201 :     * ^ XOR: Arithmetic.
1202 :     * `: Single and double quotes.
1203 :     * `...`: Nested shells and reverse apostrophes.
1204 :     * `` shell construction: Nested shells and reverse apostrophes.
1205 :     * apropos: How to use this reference guide.
1206 :     * ar: Compilers.
1207 :     * archie: Internet resources.
1208 :     * argc in C: argv argc envp.
1209 :     * argv in C: argv argc envp.
1210 :     * awk: Extracting from files.
1211 :     * breaksw: Input from the user.
1212 :     * cat: File handling.
1213 :     * cc: Compilers.
1214 :     * CC: Compilers.
1215 :     * chgrp: Access control.
1216 :     * chmod: Access control.
1217 :     * chown: Access control.
1218 :     * cmdtool: terminal emulators.
1219 :     * continue: Loops in csh.
1220 :     * cp: File handling.
1221 :     * crypt(): Passwd example program.
1222 :     * cut: Extracting from files.
1223 :     * date: Miscellaneous.
1224 :     * dbx: Compilers.
1225 :     * dc: Miscellaneous.
1226 :     * ddd: Compilers.
1227 :     * df: Disk usage.
1228 :     * DISPLAY: Environment and shell variables.
1229 :     * domainname: System identity.
1230 :     * du: Disk usage.
1231 :     * dvips: Text/postscript.
1232 :     * ed: Text editors.
1233 :     * elm: Mail.
1234 :     * emacs: Text editors.
1235 :     * env: Environment and shell variables.
1236 :     * eq: Scalar variables.
1237 :     * find: Locating files.
1238 :     * finger: Other users.
1239 :     * fmgr: Access control.
1240 :     * fnews: Internet resources.
1241 :     * foreach: Loops in csh.
1242 :     * fork(): Fork example.
1243 :     * ftp: File transfer.
1244 :     * g++: Compilers.
1245 :     * gcc: Compilers.
1246 :     * gdb: Compilers.
1247 :     * getenv(): Environment variables in C.
1248 :     * ghostscript: Text/postscript.
1249 :     * ghostview: Text/postscript.
1250 :     * HOME: Environment and shell variables.
1251 :     * HOST: Environment and shell variables.
1252 :     * hostname: System identity.
1253 :     * ioctl(): ioctl.
1254 :     * irc: Contacting users.
1255 :     * ispell: Miscellaneous.
1256 :     * keys: Iterating over elements in arrays.
1257 :     * latex: Text/postscript.
1258 :     * ld: Compilers.
1259 :     * LD_LIBRARY_PATH <1>: Libraries and LD_LIBRARY_PATH.
1260 :     * LD_LIBRARY_PATH: Environment and shell variables.
1261 :     * less: File browsers.
1262 :     * ln: Hard links.
1263 :     * ln -s: Symbolic links.
1264 :     * locate: Locating files.
1265 :     * lp: File handling.
1266 :     * lpq: File handling.
1267 :     * lpstat: File handling.
1268 :     * ls: File handling.
1269 :     * man -k: How to use this reference guide.
1270 :     * mesg: Contacting users.
1271 :     * mkdir <1>: File handling.
1272 :     * mkdir: How to use this reference guide.
1273 :     * more: File browsers.
1274 :     * mv: File handling.
1275 :     * ncftp: File transfer.
1276 :     * netstat: System statistics.
1277 :     * nslookup: System identity.
1278 :     * paste: Extracting from files.
1279 :     * PATH: Environment and shell variables.
1280 :     * pico: Text editors.
1281 :     * pine: Mail.
1282 :     * ping: Miscellaneous.
1283 :     * PRINTER <1>: File handling.
1284 :     * PRINTER: Environment and shell variables.
1285 :     * ps: System statistics.
1286 :     * rand(): Passwd example program.
1287 :     * rcpinfo: System statistics.
1288 :     * rename in perl: search and replace.
1289 :     * repeat: Loops in csh.
1290 :     * rlogin: Remote login.
1291 :     * rmail: Mail.
1292 :     * rmdir: File handling.
1293 :     * rsh: Remote login.
1294 :     * screen: terminal emulators.
1295 :     * sed: Extracting from files.
1296 :     * set: Defining variables with set and setenv.
1297 :     * setroot: Pictures/graphics.
1298 :     * shelltool: terminal emulators.
1299 :     * showmount: System statistics.
1300 :     * stderr: Stdin.
1301 :     * stdin: Stdin.
1302 :     * stdout: Stdin.
1303 :     * talk: Contacting users.
1304 :     * tcl: Interpreted languages.
1305 :     * telnet: Remote login.
1306 :     * TERM: Environment and shell variables.
1307 :     * tex: Text/postscript.
1308 :     * texinfo: Text/postscript.
1309 :     * textedit: Text editors.
1310 :     * touch: File handling.
1311 :     * uname: System identity.
1312 :     * unlink: File handling.
1313 :     * unset: Defining variables with set and setenv.
1314 :     * users: Other users.
1315 :     * vi: Text editors.
1316 :     * vmstat: System statistics.
1317 :     * vmunix: The file hierarchy.
1318 :     * w: Other users.
1319 :     * whereis: Locating files.
1320 :     * which: Shell commands generally.
1321 :     * while: Loops in csh.
1322 :     * who: Other users.
1323 :     * write: Contacting users.
1324 :     * xarchie: Internet resources.
1325 :     * xcalc: Miscellaneous.
1326 :     * xdvi: Text/postscript.
1327 :     * xedit: Text editors.
1328 :     * xemacs: Text editors.
1329 :     * xfig: Pictures/graphics.
1330 :     * xmosaic: Internet resources.
1331 :     * xpaint: Pictures/graphics.
1332 :     * xrn: Internet resources.
1333 :     * xterm: terminal emulators.
1334 :     * xv: Pictures/graphics.
1335 :     * xxgdb: Compilers.
1336 :     * zmail: Mail.
1337 :     * |: Pipes and redirection.
1338 :     * | OR: Arithmetic.
1339 :     * || logical OR: Arithmetic.
1340 :    

Administrator
ViewVC Help
Powered by ViewVC 1.0.3