Webduino Help

I can’t figure out how to get this sketch working and I get a ton of errors. Any Help is much appreciated .

#ifndef WEBDUINO_H_
#define WEBDUINO_H_

#include <string.h>
#include <stdlib.h>

/********************************************************************
 * CONFIGURATION
 ********************************************************************/

#define WEBDUINO_VERSION 1004
#define WEBDUINO_VERSION_STRING "1.4"

#if WEBDUINO_SUPRESS_SERVER_HEADER
#define WEBDUINO_SERVER_HEADER ""
#else
#define WEBDUINO_SERVER_HEADER "Server: Webduino/" WEBDUINO_VERSION_STRING CRLF
#endif

// standard END-OF-LINE marker in HTTP
#define CRLF "\r\n"

// If processConnection is called without a buffer, it allocates one
// of 32 bytes
#define WEBDUINO_DEFAULT_REQUEST_LENGTH 200

// How long to wait before considering a connection as dead when
// reading the HTTP request.  Used to avoid DOS attacks.
#ifndef WEBDUINO_READ_TIMEOUT_IN_MS
#define WEBDUINO_READ_TIMEOUT_IN_MS 10000
#endif

#ifndef WEBDUINO_FAIL_MESSAGE
#define WEBDUINO_FAIL_MESSAGE "<h1>EPIC FAIL</h1>"
#endif

// add "#define WEBDUINO_SERIAL_DEBUGGING 1" to your application
// before including WebServer.h to have incoming requests logged to
// the serial port.
#ifndef WEBDUINO_SERIAL_DEBUGGING
#define WEBDUINO_SERIAL_DEBUGGING 0
#endif
#if WEBDUINO_SERIAL_DEBUGGING
#include <HardwareSerial.h>
#endif

// declared in wiring.h
extern "C" unsigned long millis(void);

// declare a static string
#define P(name)   static const prog_uchar name[] PROGMEM

// returns the number of elements in the array
#define SIZE(array) (sizeof(array) / sizeof(*array))

/********************************************************************
 * DECLARATIONS
 ********************************************************************/

/* Return codes from nextURLparam.  NOTE: URLPARAM_EOS is returned
 * when you call nextURLparam AFTER the last parameter is read.  The
 * last actual parameter gets an "OK" return code. */

typedef enum URLPARAM_RESULT { URLPARAM_OK,
                               URLPARAM_NAME_OFLO,
                               URLPARAM_VALUE_OFLO,
                               URLPARAM_BOTH_OFLO,
                               URLPARAM_EOS         // No params left
};

class WebServer: public Print
{
public:
  // passed to a command to indicate what kind of request was received
  enum ConnectionType { INVALID, GET, HEAD, POST ,POSTMULTI};

  // any commands registered with the web server have to follow
  // this prototype.
  // url_tail contains the part of the URL that wasn't matched against
  //          the registered command table.
  // tail_complete is true if the complete URL fit in url_tail,  false if
  //          part of it was lost because the buffer was too small.
  typedef void Command(WebServer &server, ConnectionType type,
                       char *url_tail, bool tail_complete);

  // constructor for webserver object
  WebServer(const char *urlPrefix = "/", int port = 80);

  // start listening for connections
  void begin();

  // check for an incoming connection, and if it exists, process it
  // by reading its request and calling the appropriate command
  // handler.  This version is for compatibility with apps written for
  // version 1.1,  and allocates the URL "tail" buffer internally.
  void processConnection();

  // check for an incoming connection, and if it exists, process it
  // by reading its request and calling the appropriate command
  // handler.  This version saves the "tail" of the URL in buff.
  void processConnection(char *buff, int *bufflen);

  // set command that's run when you access the root of the server
  void setDefaultCommand(Command *cmd);

  // set command run for undefined pages
  void setFailureCommand(Command *cmd);

  // add a new command to be run at the URL specified by verb
  void addCommand(const char *verb, Command *cmd);

  // utility function to output CRLF pair
  void printCRLF();

  // output a string stored in program memory, usually one defined
  // with the P macro
  void printP(const prog_uchar, *str);

  // output raw data stored in program memory
  void writeP(const prog_uchar *data, size_t length);

  // output HTML for a radio button

  // returns next character or -1 if we're at end-of-stream
  int read();

  // put a character that's been read back into the input pool
  void push(int ch);

  // returns true if the string is next in the stream.  Doesn't
  // consume any character if false, so can be used to try out
  // different expected values.
  bool expect(const char *expectedStr);

  // returns true if a number, with possible whitespace in front, was
  // read from the server stream.  number will be set with the new
  // value or 0 if nothing was read.
  bool readInt(long &number);

  // Read the next keyword parameter from the socket.  Assumes that other
  // code has already skipped over the headers,  and the next thing to
  // be read will be the start of a keyword.
  //
  // returns true if we're not at end-of-stream
  bool readPOSTparam(char *name, int nameLen, char *value, int valueLen);
  int readNextFormPart(int action);
  // Read the next keyword parameter from the buffer filled by getRequest.
  //
  // returns 0 if everything weent okay,  non-zero if not
  // (see the typedef for codes)
  URLPARAM_RESULT nextURLparam(char **tail, char *name, int nameLen,
                               char *value, int valueLen);

  // output headers and a message indicating a server error
  void httpFail();

  // output standard headers indicating "200 Success".  You can change the
  // type of the data you're outputting or also add extra headers like
  // "Refresh: 1".  Extra headers should each be terminated with CRLF.
  void httpSuccess(const char *contentType = "text/html; charset=utf-8",
                   const char *extraHeaders = NULL);

  // used with POST to output a redirect to another URL.  This is
  // preferable to outputting HTML from a post because you can then
  // refresh the page without getting a "resubmit form" dialog.
  void httpSeeOther(const char *otherURL);
  void httpContinue();

  // implementation of write used to implement Print interface
  virtual void write(uint8_t);
  virtual void write(const char *str);
  virtual void write(const uint8_t *buffer, size_t size);
  void write(const char *data, size_t length);
  char m_filename[20];
  int bounlength;

//private:
protected:
  Server m_server;
  Client m_client;
  const char *m_urlPrefix;

  int m_pushback[100];
  int m_pushbackDepth;

  long m_contentLength;
  bool m_readingContent;
  int conttype;
  char m_boundary[90];


  Command *m_failureCmd;
  Command *m_defaultCmd;
  struct CommandMap
  {
    const char *verb;
    Command *cmd;
  } m_commands[8];
  char m_cmdCount;

  void reset();
  void getRequest(WebServer::ConnectionType &type, char *request, int *length);
  bool dispatchCommand(ConnectionType requestType, char *verb,
                       bool tail_complete);
  void processHeaders();

  static void defaultFailCmd(WebServer &server, ConnectionType type,
                             char *url_tail, bool tail_complete);
  void noRobots(ConnectionType type);
};

/********************************************************************
 * IMPLEMENTATION
 ********************************************************************/

WebServer::WebServer(const char *urlPrefix, int port) :
  m_server(port),
  m_client(255),
  m_urlPrefix(urlPrefix),
  m_pushbackDepth(0),
  m_cmdCount(0),
  m_contentLength(0),
  m_failureCmd(&defaultFailCmd),
  m_defaultCmd(&defaultFailCmd)
{
}

void WebServer::begin()
{
  m_server.begin();
}

void WebServer::setDefaultCommand(Command *cmd)
{
  m_defaultCmd = cmd;
}

void WebServer::setFailureCommand(Command *cmd)
{
  m_failureCmd = cmd;
}

void WebServer::addCommand(const char *verb, Command *cmd)
{
  if (m_cmdCount < SIZE(m_commands))
  {
    m_commands[m_cmdCount].verb = verb;
    m_commands[m_cmdCount++].cmd = cmd;
  }
}

void WebServer::write(uint8_t ch)
{
  m_client.write(ch);
}

void WebServer::write(const char *str)
{
  m_client.write(str);
}

void WebServer::write(const uint8_t *buffer, size_t size)
{
  m_client.write(buffer, size);
}

void WebServer::write(const char *buffer, size_t length)
{
  m_client.write((const uint8_t *)buffer, length);
}

void WebServer::writeP(const prog_uchar *data, size_t length)
{
  // copy data out of program memory into local storage, write out in
  // chunks of 32 bytes to avoid extra short TCP/IP packets
  uint8_t buffer[32];
  size_t bufferEnd = 0;

  while (length--)
  {
    if (bufferEnd == 32)
    {
      m_client.write(buffer, 32);
      bufferEnd = 0;
    }

    buffer[bufferEnd++] = pgm_read_byte(data++);
  }

  if (bufferEnd > 0)
    m_client.write(buffer, bufferEnd);
}

void WebServer::printP(const prog_uchar *str)
{
  // copy data out of program memory into local storage, write out in
  // chunks of 32 bytes to avoid extra short TCP/IP packets
  uint8_t buffer[32];
  size_t bufferEnd = 0;
  
  while (buffer[bufferEnd++] = pgm_read_byte(str++))
  {
    if (bufferEnd == 32)
    {
      m_client.write(buffer, 32);
      bufferEnd = 0;
    }
  }

  // write out everything left but trailing NUL
  if (bufferEnd > 1)
    m_client.write(buffer, bufferEnd - 1);
}

void WebServer::printCRLF()
{
  m_client.write((const uint8_t *)"\r\n", 2);
}

bool WebServer::dispatchCommand(ConnectionType requestType, char *verb,
        bool tail_complete)
{
  if ((verb[0] == 0) || ((verb[0

and I get a ton of errors. I have to say that I'm not surprised

What was that code written for? Where's the rest of it? And what errors do you get.

It was written for a filemanager for the ethernet shield. http://code.google.com/p/webduino/issues/detail?id=10
I get "expected identifier before ‘*’ token " I cant figure out how to state the string.
heres the other part of the code:

#define DEBUGON

// the next lines are usefull for debugging.  If you're finished debugging, remove the line above
#ifdef DEBUGON
  #define DEBUG_INIT         Serial.begin(115200)
  #define DEBUG_PRINTLN(x)    Serial.println (x)
  #define DEBUG(x)           Serial << x
#else
  #define DEBUG_INIT  
  #define DEBUG_PRINTLN(x)
  #define DEBUG(x)           
#endif  

#include <Ethernet.h>
#include <PString.h>     // http://arduiniana.org/libraries/pstring/
#include <Streaming.h>  // http://arduiniana.org/libraries/streaming/
#include <ctype.h>
#include <SdFat.h>   // http://code.google.com/p/sdfatlib/
#include "webduino.h"   // this version was heavily modified. 
#include "SPI.h"

#define SD_SELECT 40     // PIN that selects SD card for SPI.  = PIN4 ? on arduino Ethernet board 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEA };
byte ip[] = { 192, 168, 2, 65 };

WebServer webserver("", 80);

// I use these buffers for various pieces, they can easily be replaced by something else
char shortbuffer[400];
PString tstring(shortbuffer,sizeof(shortbuffer));
char smallbuffer[20];
PString Psmallbuffer(smallbuffer,sizeof(smallbuffer));


Sd2Card card;      
SdVolume volume;
SdFile filemgrdir;
bool SDCardOK=false;

//=============================================================================================================================
void card_init(){
  // initializes card.  SPI_FULL_SPEED can also be used, but could cause problems.
  if (!card.init(SPI_HALF_SPEED,SD_SELECT))     DEBUG("card.init failed!"<<endl<<"CODE"<<card.errorCode()<<","<<card.errorData()<<endl);
  if (!volume.init(&card))                      DEBUG("volume.init failed!"<<endl<<"CODE"<<card.errorCode()<<","<<card.errorData()<<endl);
  if (!(SDCardOK=filemgrdir.openRoot(&volume))) {
       DEBUG("open root failed!"<<endl<<"CODE"<<card.errorCode()<<","<<card.errorData()<<endl);
     }
     else {     // list file in root with date and size
        DEBUG_PRINTLN("Files found in root:");
        filemgrdir.ls(LS_DATE | LS_SIZE);         // Recursive list of all directories
        DEBUG_PRINTLN("Files found in all dirs:");
        filemgrdir.ls(LS_R);      
     }
}
//=============================================================================================================================
SdFile OpenFile(char* longfilename){ // opeens filename starting from root; e.g "/folder/testfiles/file1.txt"
  SdFile file1;
  file1.openRoot(&volume);  
  if(strcmp(longfilename,"/")!=0){
      SdFile file2;
      char *fn =strtok(longfilename,"\\/");
      int openok=file2.open(&file1,fn,O_READ);
      file1.close();
      while ((fn!= NULL)&&(openok==1)) {
        fn =strtok(NULL,"\\/");
        if (fn!=NULL) {
           int openok=file1.open(&file2,fn,O_READ);
           if (openok==1) {file2.close();file2=file1;}
            }    
        }
       file1.close();file1=file2; 
      }
  return file1;
}
//=============================================================================================================================
// utilities for mime types, in order to provide correct file type info to web browser
char* mime_types=
  "HTM*text/html|"
  "TXT*text/plain|"
  "CSS*text/css|"
  "XML*text/xml|"
  "GIF*image/gif|"
  "JPG*image/jpeg|"
  "PNG*image/png|"
  "ICO*image/vnd.microsoft.icon|"
  "MP3*audio/mpeg|";

static const uint16_t text_html_content_type = 4;  // index of standard HTM type.
// =============================================================================// =============================================================================
uint16_t get_mime_type_from_filename(const char* filename) {
  uint16_t r = text_html_content_type;
  if (!filename) {
    return r;
  }
  char* ext = strrchr(filename, '.');
  if (ext) {     // We found an extension. Skip past the '.'
    ext++;
    char ch;
    int i = 0;
    while (i < sizeof(mime_types)) {
      // Compare the extension
      char* p = ext;
      ch = mime_types[i];
      while (*p && ch != '*' && toupper(*p) == ch) {
      p++; i++;
      ch = mime_types[i];
      }
      if (!*p && ch == '*') {       // We reached the end of the extension while checking
      r = ++i;   // equality with a MIME type: we have a match. Increment i
      break;          // to reach past the '*' char, and assign it to `mime_type'.
      } else {       // Skip past the the '|' character indicating the end of a MIME type.
      while (mime_types[i++] != '|')
          ;
      }
    }
  }
//  free(ext);
  return r;
}
// =============================================================================// =============================================================================
void Upload(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  long nbytes;
  boolean success=false;
  if (SDCardOK) {
  if (type == WebServer::POSTMULTI) // this is what is expected: a multipart form
  {
    bool repeat;
    int act=-1; char ch;
    while ((act=server.readNextFormPart(act))!=-4){  // if readnextformpart returns -4, either an error occurred or end of forms was reached.
        if(strlen(server.m_filename)>0){             // filename is not empty: a file has been submitted.  filename is read in readnextformpart.
                    int buffer[5];                    // a simple FIFO buffer is used to make sure the last two bytes are not written to file.   A better way could(should) be used.  for now, this works
                    int b_read=0; int b_write=0;int diff=0;  // buffer read/write indexes, and the number of bytes the read buffer is behind
                    SdFile filetoload;                       
                    filetoload.writeError=false;
                    if(filetoload.open(filemgrdir,server.m_filename,O_CREAT | O_WRITE |  O_TRUNC)) {  // returns true if file was opened succesfully
                    nbytes=0; // number of bytes read
                          success=true;
                          while ((act=server.readNextFormPart(-3))>=0) {  // as long as a valid byte is read. (-3) as input means it is returning reading bytes  and exiting if a boundary was found.    
                                nbytes++;
                              buffer[b_write]=act;                          // put data in buffer
                              b_write=(b_write+1)%5;                        //updat buffer index
                              diff++;
                              if (diff>2) {                                 // start writing after  a 2-byte delay
                                nbytes++;
                                ch=buffer[b_read];
                                filetoload.write(buffer[b_read]);           //write data to files
                                if(filetoload.writeError){ break;}
                                b_read=(b_read+1)%5;
                                diff--;
                              }    
                     }
//                     free(buffer);
                     // this previous section needs some cleaning up.  writing to a much larger buffer and writing the buffer in a single step to the file would probably be much faster.
                      if(filetoload.writeError) {
                            success=false;
                            DEBUG("write error!!"<<endl);
                       }
                       filetoload.close();
                    }
                    else {
                      DEBUG("Failed to open file!!"<<endl);
                    }
        }        
    } 
   }  // end if POSTMULTI
   }
   server.httpSuccess();    
   if (success) {
     server << "<html><body><h1>File uploaded.</h1><p> Filename: "<<server.m_filename<<", Bytes: "<<nbytes<<"</p></body></html>";
   }
   else {
     server << "<html><body><h1>Problems occurred. File may not have uploaded correctly</h1></body></html>";
   }   
}
//===========================================================================================================
void failureCmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete) {
   // this checks if the requested url is perhaps a file that needs to be served   
   tstring.begin();
   SdFile filetosend; 
   char* filename=url_tail;  // 
    DEBUG("requesting file: "<<filename<<endl);
    filetosend=OpenFile(filename);
    if (filetosend.isFile()) {  // if not, file is not found, corrupt or else. 
                DEBUG("Serving file: "<<filename<<endl);
                int16_t n;  
                uint8_t buf[1000];// 
                uint16_t mimetype=get_mime_type_from_filename(filename);
                //send_error_code(server,mimetype, 200);
                tstring<<"HTTP/1.0 200 OK"<<endl<<"Content-Type:";
                // next part writes the content type (mime types)
                char ch;                
                int i = mimetype;
                while ((ch = mime_types[i++]) != '|') {
                  tstring.print(ch);
                }
                tstring << endl << endl;
                server <<tstring;
                // finished writing mimetypes, now write the file 
                while ((n = filetosend.read(buf, sizeof(buf))) > 0) {