Linux-Development-Apps Digest #557, Volume #6    Tue, 25 Apr 00 15:13:17 EDT

Contents:
  deltree for linux (LiNuX_MaN)
  Re: Any validating XML Parsers? ([EMAIL PROTECTED])
  Re: Automatic package installer? ([EMAIL PROTECTED])
  Re: Writing to /dev/dsp (David Steuber)
  Re: deltree for linux ([EMAIL PROTECTED])
  Types of threads ("Paul Richards (Pauldoo)")
  Copying to the cut buffer (Mike Clark)
  Re: web compatible database (Kinkie)
  Database Postgres ("María Dolores Bravo")
  Re: timezone macro for autoconf? (Paul Eggert)
  Please help me with my sockets problem ("Malc")

----------------------------------------------------------------------------

Subject: deltree for linux
From: LiNuX_MaN <[EMAIL PROTECTED]>
Date: Tue, 25 Apr 2000 08:55:22 -0700

I am writing a function similar to deltree of MS-DOS. But when I
compile this, the result isn't right. Can anybody help me?

#include <dirent.h>                     
#include <sys/stat.h>           
#include <sys/types.h>                  
#include <stdio.h>              
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

main()
{
  ApagarDirTemp();
}


ApagarDirTemp(void)
{
  DIR *Pont_Dir;
  struct dirent *Entradas_Dir;
  struct stat tipo_arq;         
  char *DirsVisits, *DirCorr, *DirsExist, *Caminho_Comp, *Posic,
*Executar, *ArqCorrente;
  int Tipo, PossuiDir=0;  /*PossuiDir - ver se o dir tem
ocorrência de diretórios*/

  DirsExist = malloc( sizeof(DirsExist) * 1000 );
  DirsVisits = malloc( sizeof(DirsVisits) * 1000 );
  Executar = malloc( sizeof(Executar) * 80 );
  ArqCorrente = malloc( sizeof(ArqCorrente) * 50 );
  DirCorr = malloc( sizeof(DirCorr) * 40 );
  Caminho_Comp = malloc( sizeof(Caminho_Comp) * 80 );
  Posic = malloc( sizeof(Posic) * 10 );

  Caminho_Comp = (char *) get_current_dir_name();  /*Receber o
caminho completo*/

  strcpy(DirCorr, Caminho_Comp);
  strcat(DirCorr, "/temp");       /*Iniciar dentro do diretório
temporário*/
  chdir(DirCorr);

Repetir:
                                
  Pont_Dir = opendir(".");

  do
   {
     Entradas_Dir = readdir(Pont_Dir);
         ArqCorrente = Entradas_Dir->d_name;
                 Tipo = stat(ArqCorrente, &tipo_arq);

     Caminho_Comp = (char *) get_current_dir_name();  /*Receber o
caminho completo*/
                                
                 if ( ( S_ISDIR(tipo_arq.st_mode) == 1 ) && ( strcmp(
ArqCorrente, "." ) != 0 ) && ( strcmp(ArqCorrente, "..") != 0 )
)  /*se for Diretório*/
                  {
                    strcpy(DirCorr, ArqCorrente); /*Este nome é um diretório*/
                
        if ( strstr(DirsExist, DirCorr) == NULL ) /*Verificar se
o dir já foi registrado*/
          {
            if ( strcmp(DirsExist, NULL) == 0 )  /*Caso a var não
tenha sido utilizada*/
              {
                strcpy(DirsExist, Caminho_Comp);
                strcat(DirsExist, "/");
                strcat(DirsExist, DirCorr);
                PossuiDir = 1;  /*Houve ocorrência de
diretórios*/
              }
            else   /*E se ela já foi utilizada*/
              {
                strcat(DirsExist, ", ");
                strcat(DirsExist, Caminho_Comp);
                strcat(DirsExist, "/");
                strcat(DirsExist, DirCorr);
                PossuiDir = 1;  /*Houve ocorrência de
diretórios*/
              }
          }
      }
   } while ( Entradas_Dir != NULL );   /*Listar o conteúdo e
separar os diretórios*/


     if (PossuiDir == 1) /*Houve diretórios, guardá-lo na lista
de dirs visitados*/
      {
        Posic = strchr(DirsExist, ',');   /*Localizar a vírgula
na var dos diretórios a serem visitados*/
        strncpy( DirCorr, DirsExist, (Posic - DirsExist) - 1 );
/*Guardar o dir corrente para entrarmos nele*/
        strcpy( DirsExist, DirsExist + ( strlen(DirCorr) + 2 ) );
/*Apagar este diretório da var dirs a serem visitados*/

        if ( strcmp(DirsVisits, NULL) == 0 ) /*Caso a var não
tenha sido utilizada*/
          {
            strcpy(DirsVisits, DirCorr);
          }
        else         /*E se ela já foi utilizada*/
          {
            strcat(DirsVisits, ", ");
            strcat(DirsVisits, DirCorr); /*Guardar na lista dos
dirs já visitados*/
          }

        closedir(Pont_Dir);
        PossuiDir = 0;
        chdir(DirCorr); /*Mudar p/ o próximo dir*/
        goto Repetir;
      }
   else  /*Ñ tem dirs nesta pasta*/
      {
        chdir("..");  /*Descer um nível e ...*/

        Posic = strstr(DirsExist, DirCorr); /*Localizar na var de
dirs a serem visitados o diretório corrente*/
        strcpy( DirsExist + ( (int) Posic - 2 ), DirsExist + (
strlen(DirCorr) + (int) Posic + 2 ) ); /*Apagar este diretório da
var dirs a serem visitados*/

        if ( strstr(DirsVisits, DirCorr) == NULL ) /*Verif c o
dir já não foi visitado*/
          {
            strcat(DirsVisits, ", "); /*Guardar na lista dos dirs
já visitados*/
            strcat(DirsVisits, Caminho_Comp);
            strcat(DirsVisits, "/");
            strcat(DirsVisits, DirCorr);
          }

        strcpy(Executar, "rmdir --ignore-fail-on-non-empty \"");
        strcat(Executar, DirCorr);
        strcat(Executar, "\"");
        system(Executar);
        PossuiDir = 0;

        if ( strstr(DirCorr, "/temp") )  /*Se por acaso não
existir diretórios dentro do dir tempo, acabamos*/
          return;

        goto Repetir;
      }
}

* Sent from RemarQ http://www.remarq.com The Internet's Discussion Network *
The fastest and easiest way to search and participate in Usenet - Free!


------------------------------

From: [EMAIL PROTECTED]
Subject: Re: Any validating XML Parsers?
Crossposted-To: comp.os.linux.development.system
Date: Tue, 25 Apr 2000 16:08:11 GMT

In comp.os.linux.development.apps M Sweger <[EMAIL PROTECTED]> wrote:
> Will this tool validate the xml tree structure to insure that the tags appear
> in the order expected? Most validating parsers seem to make sure that:
> 1) there is a begin and end tag, 2) that the nested tags are ok i.e. has
> and end tag. But they don't make sure that  tags appear in a certain order.
> So if I have

No, a _validating_ parser insures that your document is a valid
instance of a DTD. End tag ommisions and tag order are only errors if
they're not allowed by the DTD. What you're discussing here is a
normalising, not validating. There's also a program with SP to do
that, but it's not what you asked for.

> What I'm trying to figure out is how they do the tree structure validation.
> SAX doesn't create a tree ( it is event based). Thus, one must create the
> tree which must be validated for structure. 

If you really want to know how it works, you should download SP and
read the developer's documentation with the library. You should also
consider ponying up some cash for a couple good books. In all honesty
though, I'm not sure you want to get that deep into it for various
reasons.

1. nsgmls is already an excellent validating parser. Probably quite a
bit more than anything you're likely to cook up yourself without
investing a couple years in the project.

2. The SP library that ships with nsgmls is a ready made api for
handling SGML. So if you want to write a library, it's again already
done.

3. nsgmls and friends all contain the standard options for outputting
in a machine-parsable representation. So, if you want to write perl
scripts like dtdtree.pl, the hard part is once again already done. ;)

That's not to say this isn't an area that needs alot of work in the
free sector. Just that alot of the gory low-level stuff is done. 

-- 
Matt Gauthier <[EMAIL PROTECTED]>

------------------------------

From: [EMAIL PROTECTED]
Subject: Re: Automatic package installer?
Date: Tue, 25 Apr 2000 16:14:05 GMT

Christopher Browne <[EMAIL PROTECTED]> wrote:
> Ah, but rpm _doesn't_ go off and seek to satisfy the unsatisfied
> dependencies.

That's true, I'm not entirely convinced that's a bad thing,
though. Frankly, a package manager that runs off and
downloads/installs things for me scares the bejesus out of me.

> dpkg corresponds roughly to rpm; the nearest equivalent in the "RPM world"
> to apt-get would be autorpm, but whilst apt-get is _quite_ mature,
> autorpm isn't quite there yet, and people using RPM-based distributions
> cannot assume they have autorpm the way Debian-based distributions can
> for apt-get.

I honestly have never even looked at any rpm wrappers except for using
gnorpm twice to install a couple packages. I just find the normal rpm
command flexible enough for me.

-- 
Matt Gauthier <[EMAIL PROTECTED]>

------------------------------

Subject: Re: Writing to /dev/dsp
From: David Steuber <[EMAIL PROTECTED]>
Date: Tue, 25 Apr 2000 16:59:58 GMT

[EMAIL PROTECTED] (David T. Blake) writes:

' > Is there a better way to make noise?
' 
' Have fun. Generally, 44100 sampling rate 16 bits per
' channel interleaved, short ints in i386 linux.
' But, that can be changed with a few calls to ioctl.

Thanks for the code example!

Now for the $6.40 question.  Will this work under *BSD as well, or is
this strictly Linux?  How portable is sound?

-- 
David Steuber   |   Hi!  My name is David Steuber, and I am
NRA Member      |   a hoploholic.

http://www.packetphone.org/

The first myth of management is that it exists.  The second myth of
management is that success equals skill.
                -- Robert Heller

------------------------------

From: [EMAIL PROTECTED]
Subject: Re: deltree for linux
Date: Tue, 25 Apr 2000 17:12:48 GMT

LiNuX_MaN <[EMAIL PROTECTED]> wrote:
> I am writing a function similar to deltree of MS-DOS. But when I
> compile this, the result isn't right. Can anybody help me?

If all you want is to have a deltree command, rm -rf <treename> will
do nicely. If not, read on.

This is a two-liner in C, man 3 ftw.

You'll probably find nftw easier though, as it will do a depth-first
search.

Alternatly, you _might_ want to look into fts which is newer, somewhat
nicer, and appears on both BSD and Linux (two platforms for the price
of one!). Unfortunatly, the man pages are on BSD but not Linux.

As a shameless plug, look into http://srm.sourceforge.net, which is
written to be easy to read. The tree_walker.c and main.c modules
should send you well on your way to using fts.

After a cursory reveiw of your code, I notice:

1. This function leaks a bit of memory, as you never free anything you
malloc.

2. You're using system(command) when the easy way is unlink() and
rmdir().

3. There's a couple gotos that could be better replaced with other
flow-control statements.

4. You're mallocing strings based on the size of pointers, not
characters, which aren't guaranteed to be the same size.

5. get_current_dir_name() returns a malloced string which you leak, in
addition to the one you malloc yourself, which also leaks. 

I'm sure there's a mistake deep down in the loop, which replacing with
one of the prepackaged tree walkers would help. To be perfectly
honest, I have a hard time reading code that's over-commented.

-- 
Matt Gauthier <[EMAIL PROTECTED]>

------------------------------

From: "Paul Richards (Pauldoo)" <[EMAIL PROTECTED]>
Subject: Types of threads
Date: Tue, 25 Apr 2000 17:17:45 +0000

Hi,
What's the difference between a thread created with pthread_create() and
fork()?  I need my threads to have read write access to the parent's
memory space stuff if this is possible..

I'd like this kinda thing to work:
{
 int c=0;
 pid_t pid=fork();

 if (pid>(pid_t)0)
 {
  //Parent
  for (;;)
  {
   cout << "\r" << c;
   cout.flush();
  }
  
 } else
 {
  //Child
  for (;;)
  {
   c++;
  }
 }
}

As you can probably guess - it doesn't work at all.  :)
-- 
Paul Richards (Pauldoo) - http://www.pauldoo.co.uk

I've not run any Microsoft code for 149 days.
    How about you?

------------------------------

From: Mike Clark <[EMAIL PROTECTED]>
Subject: Copying to the cut buffer
Date: Tue, 25 Apr 2000 13:23:18 -0500

Does anyone know how to copy a string to the X cut buffer
(Like the netscape "Copy Link Location" feature)?
I have tried XStoreBuffer, but that has not worked for me, or 
maybe I just wasn't doing it right. This is a gtk+ app if that
helps at all.

Thanks,
emel



------------------------------

From: Kinkie <[EMAIL PROTECTED]>
Subject: Re: web compatible database
Date: 25 Apr 2000 18:36:33 +0200
Reply-To: [EMAIL PROTECTED]

[EMAIL PROTECTED] (Christopher Browne) writes:

> A third possibility is that the performance of MySQL is faster _when
> you use it in an effectively nonrelational way_.

Could be. Or, more likely, MySQL is faster for what it's able to do. But
when you go for complex stuff, you have to emulate at the app.level and
thus it's way slower.


-- 
  /Kinkie

Se sulla scatola c'e` scritto "Per windows 95 e superiori", dovrebbe
funzionare sotto Linux, vero?

------------------------------

From: "María Dolores Bravo" <[EMAIL PROTECTED]>
Subject: Database Postgres
Date: Tue, 25 Apr 2000 20:18:10 +0200



I'm using ADO AND VB6 and I need to open a recordset that selects all the
records
from a table, in a similar way to OpenTable method in DAO, so that I can use
Move
and Find methods. The key field is properly indexed, and the way I open the
recordset is:


strCnnE = "ODBC;DATABASE=empresa;UID=antonio;PWD=;DSN=empresa"
   Set ConectEmp = New ADODB.Connection
   ConectEmp.Open strCnnE
   ConectEmp.CursorLocation = adUseClient
   Set rsAlumnos = New ADODB.Recordset
   rsAlumnos.Open "alumnos", ConectEmp, adOpenDynamic, adLockPessimistic,
adCmdTable


This takes about 2 minutes to open with 5000 records, and gets locked with
50000. How should I open it so that it doesn't take so long?

Thanks.




------------------------------

From: [EMAIL PROTECTED] (Paul Eggert)
Crossposted-To: comp.unix.programmer,gnu.utils.help
Subject: Re: timezone macro for autoconf?
Date: 25 Apr 2000 10:51:05 -0700

Russ Allbery <[EMAIL PROTECTED]> writes:

>So what you're saying is that code based
>on timezone will fail if the definition (in terms of UTC offset) of the
>local timezone has changed since the point at which the daemon was
>started?

No, that's another bug entirely (one that few daemons have fixed).

I was referring to the problem that different time stamps correspond to
different UTC offsets.  E.g. the value for 'timezone' for Portugal
today is 0, since Portugal's standard time is now the same as
Greenwich.  But from 1992 to 1996 Portugal had a standard time one hour
ahead of Greenwich.  So if 'timezone' contains the value zero (which is
correct for Portuguese time stamps today), time_t values between 1992
and 1996 won't be handled correctly in a Portuguese locale.

This problem doesn't occur when comparing the outputs of localtime and
gmtime, since their outputs can (and, in good implementations, do)
use standard-time UTC offsets that depend on the time stamp in question.

>I'm rather unsatisfied with how time is currently handled in INN primarily
>because INN uses its own weird time structure internally rather than
>either just time_t or a struct timeval.

No standard time structure will do.  Neither struct tm nor struct
timeval is guaranteed to contain a time zone.  And when the code was
written, struct timeval wasn't standardized (and it's still absent from
some hosts); time_t plus some other stuff was the only portable way to go.

These days the most "standard" way to write it would be to use struct
timespec, as it's standardized by POSIX.1 (struct timeval is not).
However, the standards are still mutating in this area -- the next C
standard after C99 might well have a new time type -- so personally I'd
just leave INN alone for now.

Your other points are well taken.

------------------------------

From: "Malc" <[EMAIL PROTECTED]>
Crossposted-To: comp.lang.c,comp.unix.programmer
Subject: Please help me with my sockets problem
Date: Tue, 25 Apr 2000 14:28:27 +0100

Hello,
    I am writing a chat program using sockets.  I am having a few problems
1. When I send a message I receive part of the previous message so I have
tried to clear the buff(which is used to send the message to the server to
client).  This though doesn't seem to work.
2. I tried to use a switch so that a user could log in and then join the
chat program.  But I don't know how to store the users login name and
associate it with the socket so that I can send messages to a specific user
or to a specific user.  Other people have told me to have an array of socket
descriptors for each client thats connected. And when I want to send a
message to a particular user then write to that descriptor and if I want to
send a message to all users then loop through the sockets writing to each.
This is all well and good but I haven't got a clue how to program this.

I have included the code below.
Client code:-
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

char * host_name = "127.0.0.1"; // local host
int port = 5005;

void main(int argc, char *argv[]) {
  char buf[8192];
  char message[256];
  int socket_descriptor;
  struct sockaddr_in pin;
  struct hostent *server_host_name;
  char *loc;
  char string[5] = "QUIT";
  int i;
  int reply;

 char username[20];

  if ((server_host_name = gethostbyname(host_name)) == 0) {
    perror("Error resolving local host\n");
    exit(1);
  }

  bzero(&pin, sizeof(pin));
  pin.sin_family = AF_INET;
  pin.sin_addr.s_addr = htonl(INADDR_ANY);
  pin.sin_addr.s_addr = ((struct in_addr
*)(server_host_name->h_addr))->s_addr;
  pin.sin_port = htons(port);

  /*printf("\n\t\t\t1. Logon to the system\n");
  printf("\t\t\t2. Enter the system\n\n");
  scanf("%d",&reply);
  fflush(stdin);
  switch(reply)
  {
   case 1:
   {
    printf("\t\t\t\nPlease enter a username:-  ");
    scanf("%s",username);
    printf("\n\t\t\t1. Logon to the system\n");
    printf("\t\t\t2. Enter the system\n\n");
   }
   case 2:
   {*/

while(1)
 {
  if ((socket_descriptor = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Error opening socket\n");
    exit(1);
  }

  if (connect(socket_descriptor, (void *)&pin, sizeof(pin)) == -1) {
    perror("Error connecting to socket\n");
    exit(1);
  }

  printf("Please enter a message: ");
  gets(message);
  loc = strstr(message,string);
  if (loc != NULL)
      exit(1);

  printf("Sending message %s to server...\n", message);

  if (send(socket_descriptor, message, strlen(message), 0) == -1) {
    perror("Error in send\n");
    exit(1);
  }

  printf("..sent message.. wait for response...\n");

  if (recv(socket_descriptor, buf, 8192, 0) == -1) {
    perror("Error in receiving response from server\n");
    exit(1);
  }

  printf("\nResponse from server:\n\n%s\n", buf);
  }
  /*}*//*End of case 2*/
  /*default:
   printf("\n\t\t\tINVALID choice please try again\n");
  }*/
  close(socket_descriptor);

}
Server code:-
#include <errno.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define SPACE 32

int port = 5005;

void main() {
  struct sockaddr_in myname;
   struct sockaddr    addr;    /* generic socket name */
  struct sockaddr_in pin;
  struct hostent *hp, *gethostbyaddr();
  int sock_descriptor;
  int temp_sock_descriptor;
  int address_size;
  char buf[16384];
  int i, len,t,len2;
  int rc,            /* system call return code */
  new_sd, sock,  /* server/listen socket descriptors */
  adrlen,        /* sockaddr length */
  cnt;           /* number of bytes I/O */


  sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
  if (sock_descriptor == -1) {
    perror("call to socket");
    exit(1);
  }

  bzero(&myname, sizeof(myname));
  myname.sin_family = AF_INET;  /* Internet address */
  myname.sin_port = htons(port);
  myname.sin_addr.s_addr = INADDR_ANY;  /* "Wildcard" */


   /* Identify the server process. */

   printf("\nThis is the network server");

  if (bind(sock_descriptor, &myname, sizeof(myname)) <0) {
    close(sock_descriptor);  /* defensive programming  */
    printf("network server bind failure %d\n", errno);
    perror("network server");
    exit(2);
  }

   adrlen = sizeof(addr); /* need int for return value */
   if ( ( rc = getsockname( sock_descriptor, &addr, &adrlen ) ) < 0 )
   {
      printf("setwork server getsockname failure %d\n",
    errno);
      perror("network server");
      close (sock);
      exit(3);
   }


  if (listen(sock_descriptor, 20) == -1) {
    perror("call to listen");
    exit(1);
  }

  printf("Accepting connections ...\n");


  while(1) {
  /*len2 = sizeof sin;*/
    temp_sock_descriptor =accept(sock_descriptor, (struct sockaddr *)&pin,
      &address_size);
    if (temp_sock_descriptor == -1) {
      perror("call to accept");
      exit(1);
    }


  /* Fork child process to handle client service request */

      if ( ( fork() ) == 0 ) {    /* Child process */

         int pid;

         pid = getpid();   /* PID of child process */
         close (sock_descriptor); /* Do not need listen socket in child. */

         /* Find out who the client is.  Note the use of the
            generic address structure addr to hold information
            about the (connected) client.                    */

        if ((rc = getpeername( temp_sock_descriptor, &addr, &adrlen )) < 0)
{
            printf("network server %d getpeername failure %d\n",
                 pid, errno);
            perror("network server");
            close(temp_sock_descriptor);
            exit(6);
         }



   /*if(getpeername(sock_descriptor,(struct sockaddr *) &sin, &len2) < 0)
    perror("getpeername");
   else {
    if ((host = gethostbyaddr((char*) &sin.sin_addr,
          sizeof sin.sin_addr,
          AF_INET)) == NULL)
     perror("gethostbyaddr");
    else printf("remote host is '%s'\n",host->h_name);
   }*/

    if (recv(temp_sock_descriptor, buf, 16384, 0) == -1)
    {
      perror("call to recv");
      exit(1);
    }

    printf("received from client:%s\n", buf);

    // for this server example, we just convert the
    // characters to upper case:

    len = strlen(buf);
    for (i=0; i<len; i++) buf[i] = toupper(buf[i]);

    if (send(temp_sock_descriptor, buf, len, 0) == -1) {
      perror("call to send");
      exit(1);
    }
    /*printf("address IS %s\n",(struct sockaddr *pin);*/
    len = 0;
    for(i=0;i<strlen(buf);i++)
      {printf("\n1\n",buf[i]);
          buf[i]= ' ';
       printf("2\n",buf[i]);
       }
      exit(0);  /* Exit child process */
   }/* End of if-child-process true condition */

      else      /* Not child process; must be parent process */


   close(temp_sock_descriptor);/* Parent doesn't need work socket. */


  }
}






------------------------------


** FOR YOUR REFERENCE **

The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:

    Internet: [EMAIL PROTECTED]

You can send mail to the entire list (and comp.os.linux.development.apps) via:

    Internet: [EMAIL PROTECTED]

Linux may be obtained via one of these FTP sites:
    ftp.funet.fi                                pub/Linux
    tsx-11.mit.edu                              pub/linux
    sunsite.unc.edu                             pub/Linux

End of Linux-Development-Apps Digest
******************************

Reply via email to