4) category: UNIX Basics |
Language:English, article number: 2004-07-10:4 |
cd writing in linux
by Avinash Tiwari , homepage: http://www.geocities.com/avitiw
Steps to burn multi-session CD in LINUX as root :
Step 1: Make ISO images
$mkisofs -r -o cdimage.raw files
Step 2: Burn Cd with cdrecord
$cdrecord -v -multi speed=4 dev=0,0,0 -data cdimage.raw
Step 3: Make ISO images to further add data to multi-session CD
$ mkisofs -r -o cdimage.raw -C a,b -M /dev/cdrom files
where a,b is the number the following command
gives
$ cdrecord -msinfo dev=0,0,0
Step 4: Further Burning(Multi session) the CD
$cdrecord -v -multi speed=4 dev=0,0,0 -data cdimage.raw
Note: The value 0,0,0 can be different for you. This
identifies your cd-writer. To get the number execute
following command as root
$cdrecord -scanbus
Also the value a,b in Step 3 will be different for
different sessions. The value for speed will depend upon
your CD-writer
|
|
5) category: Software Development |
Language:English, article number: 2004-06-16:1 |
Multithreaded HTTP Server for Linux
by Boris Derzhavets [derzhavets[at]hotmail.com]
Multithreaded HTTP Server for Linux built up by the pool of threads
utilizing select() system call.
Developing code bellow we follow general guidelines from [1] chapter 11.
The only one source file has been modified is server.c.
Instead of fork new process to handle each incoming client's connection,
as procedure server_run ( ) does in [1], we start pool of 1024 threads
accepting as parameter descriptor of passive socket.
The procedure run by each thread is asynchronous BSD socket's server utilizing
select() system call (see for example [2],chapter 13(5)) to switch between handling
incoming client's requests by accept() system call and receiving "http" requests
from clients already connected to server utilizing procedures
handle_request() and handle_get() from [1],chapter 11.
References
1.Mark Mitchel,Jeffrey Oldham,Alex Samuel. Advanced Linux Programming.
New Riders Publishing , 2001. www.advancedlinuxprogramming.com
2.Douglas E. Comer,David L. Stevens Internet Working with TCP/IP ,vol 3
Client-Server Programming and application Linux/Posix Socket Version,
Prentice Hall,Inc. 2001
/*
* server.c module :- multithreaded version, starting pool of threads,
* multiplexing select( ) call, to serve new connections
* utilizing accept() system call and "http" responds for clients
* already connected to server simultaneously.
*/
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>
#include "server.h"
#define NUM_THREADS 1024
pthread_mutex_t get_mutex=PTHREAD_MUTEX_INITIALIZER;
static char* not_found_response_template =
"HTTP/1.0 404 Not Found\n"
"Content-type: text/html\n"
"\n"
"<html>\n"
" <body>\n"
" <h1>Not Found</h1>\n"
" <p>The requested URL %s was not found on this server.</p>\n"
" </body>\n"
"</html>\n";
static char* bad_method_response_template =
"HTTP/1.0 501 Method Not Implemented\n"
"Content-type: text/html\n"
"\n"
"<html>\n"
" <body>\n"
" <h1>Method Not Implemented</h1>\n"
" <p>The method %s is not implemented by this server.</p>\n"
" </body>\n"
"</html>\n";
static char* ok_response =
"HTTP/1.0 200 OK\n"
"Content-type: text/html\n"
"\n";
static char* bad_request_response =
"HTTP/1.0 400 Bad Request\n"
"Content-type: text/html\n"
"\n"
"<html>\n"
" <body>\n"
" <h1>Bad Request</h1>\n"
" <p>This server did not understand your request.</p>\n"
" </body>\n"
"</html>\n";
void
die(const char *func, int err)
{
fprintf(stderr,"%s: %s\n",func,strerror(err));
abort();
}
static void handle_get (int connection_fd, const char* page)
{
struct server_module* module = NULL;
if (*page == '/' && strchr (page + 1, '/') == NULL) {
char module_file_name[64];
snprintf (module_file_name, sizeof (module_file_name),
"%s.so", page + 1);
module = module_open (module_file_name);
}
if (module == NULL) {
char response[1024];
snprintf (response, sizeof (response), not_found_response_template, page);
write (connection_fd, response, strlen (response));
}
else {
write (connection_fd, ok_response, strlen (ok_response));
(*module->generate_function) (connection_fd);
module_close (module);
}
}
static void *
handle_connection (int fdSock)
{
int connection_fd = fdSock;
char buffer[256];
ssize_t bytes_read;
bytes_read = read (connection_fd, buffer, sizeof (buffer) - 1);
if (bytes_read > 0) {
char method[sizeof (buffer)];
char url[sizeof (buffer)];
char protocol[sizeof (buffer)];
buffer[bytes_read] = '\0';
sscanf (buffer, "%s %s %s", method, url, protocol);
while (strstr (buffer, "\r\n\r\n") == NULL)
bytes_read = read (connection_fd, buffer, sizeof (buffer));
if (bytes_read == -1) {
close (connection_fd);
return;
}
if (strcmp (protocol, "HTTP/1.0") && strcmp (protocol, "HTTP/1.1")) {
write (connection_fd, bad_request_response,
sizeof (bad_request_response));
}
else if (strcmp (method, "GET")) {
char response[1024];
snprintf (response, sizeof (response),
bad_method_response_template, method);
write (connection_fd, response, strlen (response));
}
else
handle_get (connection_fd, url);
}
else if (bytes_read == 0)
;
else {
system_error ("read");
}
close(connection_fd);
}
void *
serv_request(void *insock)
{
int msock = (int)insock;
struct sockaddr_in fsin;
fd_set rfds;
fd_set afds;
unsigned int alen;
int fd,nfds;
int rval;
socklen_t address_length;
struct sockaddr_in socket_address;
nfds=getdtablesize();
FD_ZERO(&afds);
FD_SET(msock,&afds);
while(1) {
memcpy(&rfds,&afds,sizeof(rfds));
if (select(nfds,&rfds,(fd_set *)0,(fd_set *)0,(struct timeval *)0) < 0)
die("select()",errno);
if (FD_ISSET(msock,&rfds)) {
int ssock;
alen=sizeof(fsin);
/*
Serving new incoming client's connection
*/
pthread_mutex_lock(&get_mutex);
ssock=accept(msock,(struct sockaddr *)&fsin,&alen);
pthread_mutex_unlock(&get_mutex);
if (ssock < 0)
die ("accept()",errno);
if (verbose) {
socklen_t address_length;
address_length = sizeof (socket_address);
rval = getpeername (ssock, &socket_address, &address_length);
assert (rval == 0);
printf ("Thread '%d' accepted connection from %s\n",
pthread_self(),inet_ntoa (socket_address.sin_addr));
}
FD_SET(ssock,&afds);
}
for (fd=0;fd < nfds; ++fd)
if (fd != msock && FD_ISSET(fd,&rfds)) {
printf("Thread '%d' responding request...\n",pthread_self());
/*
Serving client had been already connected to server
*/
handle_connection(fd);
FD_CLR(fd,&afds);
}
}
}
void
server_run(struct in_addr local_address,uint16_t port)
{
struct sockaddr_in socket_address;
int rval;
int server_socket;
int k;
/*
Getting socket's descriptor to be passed to
each thread in the pool
*/
server_socket = socket (PF_INET, SOCK_STREAM, 0);
if (server_socket == -1)
system_error ("socket");
memset (&socket_address, 0, sizeof (socket_address));
socket_address.sin_family = AF_INET;
socket_address.sin_port = port;
socket_address.sin_addr = local_address;
rval = bind (server_socket, &socket_address, sizeof (socket_address));
if (rval != 0)
system_error ("bind");
rval = listen (server_socket, 10);
if (rval != 0)
system_error ("listen");
if (verbose) {
socklen_t address_length;
address_length = sizeof (socket_address);
rval = getsockname (server_socket, &socket_address, &address_length);
assert (rval == 0);
printf ("server listening on %s:%d\n",
inet_ntoa (socket_address.sin_addr),
(int) ntohs (socket_address.sin_port));
}
/*
Starting pool of threads building up HTTP server
*/
size_t stacksize;
pthread_t p_thread[NUM_THREADS];
pthread_attr_t attr;
pthread_attr_init(&attr);
stacksize = 500000;
pthread_attr_setstacksize (&attr, stacksize);
pthread_attr_getstacksize (&attr, &stacksize);
for(k=0; k<NUM_THREADS; k++) {
pthread_create(&p_thread[k],&attr,serv_request,(void*)server_socket);
}
pthread_attr_destroy(&attr);
for(k=0;k<NUM_THREADS;k++) {
pthread_join(p_thread[k], NULL);
printf("Completed join with thread %d\n",k);
}
}
|
|
6) category: Software Development |
Language:English, article number: 2004-05-16:5 |
Implementation of a multithreaded RPC Server for Linux
by Boris A. Derzhavets [derzhavets[at]hotmail.com]
Consider as an example (see. [1] chapter "Sun RPC")
square_svc.c for file square.x to build multithreaded
RPC Server for Linux.
File square.x as in [1] Chapter "Sun RPC" follows bellow :
struct square_in {
long arg1;
};
struct square_out {
long res1;
};
program SQUARE_PROG {
version SQUARE_VERS {
square_out SQUAREPROC(square_in) = 1;
} = 2 ;
} = 0x31230000;
Call rpcgen to generate server's , client's stubs,header file square.h
and square_xdr.c (remind key -A is not supported under Linux):
$ rpcgen -a -M square.x
Server's side procedures code:
/*
* ServerSideProc.c
*/
#include "square.h"
#include "stdio.h"
#include "stdlib.h"
#include "rpc/pmap_clnt.h"
#include "string.h"
#include "memory.h"
#include "sys/socket.h"
#include "netinet/in.h"
int request=0;
bool_t
squareproc_2_svc(square_in *inp,square_out *outp,struct svc_req *rqstp)
{
printf("Thread id = '%ld' started, arg = %d\n",pthread_self(),inp->arg1);
sleep(5);
outp->res1=inp->arg1*inp->arg1;
printf("Thread id = '%ld' is done %d \n",pthread_self(),outp->res1);
return(TRUE);
}
int
square_prog_2_freeresult(SVCXPRT *transp,xdrproc_t xdr_result,
caddr_t result)
{
xdr_free(xdr_result,result);
return(1);
}
Modified code square_svc.c:
/* square_svc.c
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "square.h"
#include "stdio.h"
#include "stdlib.h"
#include "rpc/pmap_clnt.h"
#include "string.h"
#include "memory.h"
#include "sys/socket.h"
#include "netinet/in.h"
#ifndef SIG_PF
#define SIG_PF void(*)(int)
#endif
pthread_t p_thread;
pthread_attr_t attr;
/* Procedure to be run by thread */
void *
serv_request(void *data)
{
struct thr_data
{
struct svc_req *rqstp;
SVCXPRT *transp;
} *ptr_data;
{
union {
square_in squareproc_2_arg;
} argument;
union {
square_out squareproc_2_res;
} result;
bool_t retval;
xdrproc_t _xdr_argument, _xdr_result;
bool_t (*local)(char *, void *, struct svc_req *);
/*
Unpack data from structure
*/
ptr_data = (struct thr_data *)data;
struct svc_req *rqstp = ptr_data->rqstp;
register SVCXPRT *transp = ptr_data->transp;
switch (rqstp-"rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);
return;
case SQUAREPROC:
_xdr_argument = (xdrproc_t) xdr_square_in;
_xdr_result = (xdrproc_t) xdr_square_out;
local = (bool_t (*) (char *, void *, struct svc_req *))squareproc_2_svc;
break;
default:
svcerr_noproc (transp);
return;
}
memset ((char *)&argument, 0, sizeof (argument));
if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
svcerr_decode (transp);
return;
}
/*
Data are already prepared.
*/
retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp);
if (retval " 0 && !svc_sendreply(transp, (xdrproc_t) _xdr_result, (char *)&result))
{
svcerr_systemerr (transp);
}
if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "%s", "unable to free arguments");
exit (1);
}
if (!square_prog_2_freeresult (transp, _xdr_result, (caddr_t) &result))
fprintf (stderr, "%s", "unable to free results");
return;
}
}
/*
New code for square_prog_2
*/
static void
square_prog_2(struct svc_req *rqstp, register SVCXPRT *transp)
{
struct data_str
{
struct svc_req *rqstp;
SVCXPRT *transp;
} *data_ptr=(struct data_str*)malloc(sizeof(struct data_str));
{
/*
Paking data into structure in order to pass pointer to structure
to pthread_create( ). Starting thread as detached
*/
data_ptr->rqstp = rqstp;
data_ptr->transp = transp;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&p_thread,&attr,serv_request,(void *)data_ptr);
}
}
int
main (int argc, char **argv)
{
register SVCXPRT *transp;
pmap_unset (SQUARE_PROG, SQUARE_VERS);
transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create udp service.");
exit(1);
}
if (!svc_register(transp, SQUARE_PROG, SQUARE_VERS, square_prog_2, IPPROTO_UDP)) {
fprintf (stderr, "%s", "unable to register (SQUARE_PROG, SQUARE_VERS, udp).");
exit(1);
}
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL) {
fprintf (stderr, "%s", "cannot create tcp service.");
exit(1);
}
if (!svc_register(transp, SQUARE_PROG, SQUARE_VERS, square_prog_2, IPPROTO_TCP)) {
fprintf (stderr, "%s", "unable to register (SQUARE_PROG, SQUARE_VERS, tcp).");
exit(1);
}
svc_run ();
fprintf (stderr, "%s", "svc_run returned");
exit (1);
/* NOTREACHED */
}
Compile ServerSQUARE:
$ gcc -o ServerSQUARE ServerSideProc.c square_svc.c square_xdr.c \
-lprthread -lnsl
Client's side code:
/*
* ClientSideProc.c
*/
#include "memory.h" /* for memset */
#include "square.h"
#include "stdio.h"
#include "stdlib.h"
#include "rpc/pmap_clnt.h"
#include "string.h"
#include "memory.h"
#include "sys/socket.h"
#include "netinet/in.h"
int
main (int argc,char **argv)
{
CLIENT *cl;
square_in in;
square_out out;
if (argc != 3 )
{ printf ("Usage : client "hostname" "integer_valus=e"\n");
exit(1);
}
cl = clnt_create(argv[1],SQUARE_PROG,SQUARE_VERS,"tcp");
if (cl == NULL) {
clnt_perror (cl, "call failed");
exit (1);
}
in.arg1 = atol(argv[2]);
if (squareproc_2(&in,&out,cl) != RPC_SUCCESS)
{
printf ("%s\n" , clnt_perror (cl,argv[1] ));
exit(1);
}
printf("result: %ld\n",out.res1);
exit(0);
}
Compile ClientSQUARE:
$ gcc -o ClientSQUARE ClientSideProc.c square_clnt.c square_xdr.c \
-lprthread -lnsl
Testing (see [1] ,chapter "SUN RPC"):
[root@dell4500 SQWMT]# cat square.bsh
./ClientSQUARE dell4500.redhat 10 & ./ClientSQUARE dell4500.redhat 11 & \
./ClientSQUARE dell4500.redhat 12 & ./ClientSQUARE dell4500.redhat 21 & \
./ClientSQUARE dell4500.redhat 13 & ./ClientSQUARE dell4500.redhat 14 & \
./ClientSQUARE dell4500.redhat 15 & ./ClientSQUARE dell4500.redhat 16 & \
./ClientSQUARE dell4500.redhat 17 & ./ClientSQUARE dell4500.redhat 18 & \
./ClientSQUARE dell4500.redhat 19 & ./ClientSQUARE dell4500.redhat 20 &
Output on client's side:
[root@dell4500 SQWMT]# ./square.bsh
[root@dell4500 SQWMT]# result: 196
result: 225
result: 256
result: 289
result: 121
result: 144
result: 441
result: 169
result: 100
result: 324
result: 361
result: 400
Output on Server's side:
[root@dell4501 SQWMT]# ./ServerSQUARE
Thread id = '1082453184' started, arg = 14
Thread id = '1090841664' started, arg = 15
Thread id = '1099230144' started, arg = 16
Thread id = '1116941120' started, arg = 17
Thread id = '1125329600' started, arg = 11
Thread id = '1133718080' started, arg = 12
Thread id = '1142106560' started, arg = 21
Thread id = '1150495040' started, arg = 13
Thread id = '1158883520' started, arg = 10
Thread id = '1167272000' started, arg = 18
Thread id = '1175660480' started, arg = 19
Thread id = '1184048960' started, arg = 20
Thread id = '1082453184' is done 196
Thread id = '1090841664' is done 225
Thread id = '1099230144' is done 256
Thread id = '1116941120' is done 289
Thread id = '1125329600' is done 121
Thread id = '1133718080' is done 144
Thread id = '1142106560' is done 441
Thread id = '1150495040' is done 169
Thread id = '1158883520' is done 100
Thread id = '1167272000' is done 324
Thread id = '1175660480' is done 361
Thread id = '1184048960' is done 400
References:
1.W.Richard Stevens.UNIX: Network Programming v 2.Interprocess communications.
Prentice Hall,1999
|
|
7) category: UNIX Basics |
Language:English, article number: 2004-02-25:2 |
using rpm2cpio to extract files from rpm package without install it
by slimzhao
rpm use cpio's archive format internally.
rpm itself can't extract single or bundle of files from a package.
rpm-XXXX.rpm provide a tool called rpm2cpio
that's it:
rpm2cpio your_package.rpm | cpio -di '*.doc'
this command extract all files match the pattern '*.doc', it's necessary to use single-quote to protect *. from globbing by shell
- the pattern to use is for the full path string, not only the real file name, given a file
'./usr/share/pfaedit/pfaedit-es.ui'
'*share/pfa*' will match it
- never just use 'rpm2cpio your_package.rpm' to see what happen, rpm2cpio write the result to stdin, not a file with the same file name and .cpio as suffix, which probably most of you would expect.
- always using -d parameter, or it's equivalent: --make-directories
|
|
|