home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* hsh version 0.02 by Arny - cs6171@scitsc.wlv.ac.uk */
- /* This really isnt completely ready yet, but it should compile with */
- /* ansi compatible compilers (such as gcc) under Linux and SunOS. */
- /* This version now has a password option, a command to get zombies, */
- /* and the displayfile function has been changed so that it works under */
- /* more circumstances, although it is still very badly written. I also */
- /* noticed that version 0.01 wasn't *very* good when run from a "rsh */
- /* host 'sh -i'" session, so fflush(3)'ing is always done now. Keep an */
- /* eye out for newer versions - there is still much to be done. */
- /* (c) 1994/95 Arny - I accept no responsiblity for anything this does. */
- /************************************************************************/
-
- #include<stdio.h>
- #include<unistd.h>
- #include<fcntl.h>
- #include<limits.h>
- #include<pwd.h>
- #include<sys/types.h>
- #include<sys/wait.h>
- #include<sys/socket.h>
- #include<netdb.h>
- #include<netinet/in.h>
- #include<arpa/inet.h>
-
- #define MAXCOMLEN 1024 /* length of the command line */
- #define MAXARGS 512 /* number of arguments in the command line */
- #define MAXWIDTH 80 /* screen width, used for the 'more' command */
- #define MAXLINES 23 /* screen length */
- #define PROMPT "hsh$ "
-
-
- /* if you want I/O to a socket #define PORTNUM to the port number, */
- /* if you dont, dont. */
-
- /* #define PORTNUM 7890 */
-
-
- /* if you want to be asked for a passwd, define PASSWD to the encrypted */
- /* passwd (as produced by passwd(1) or crypt(3) ) with double quotes */
-
- /* #define PASSWD "RAMdLCxgo2EFU" */
-
-
- /* if you are compiling for linux and you *really* want 'more' to go */
- /* backwards and forwards on single keystrokes #define TTYMANIP, but */
- /* for the sake of reliability and portability I wouldn't recommend it. */
-
- /* #define TTYMANIP */
-
- #ifdef TTYMANIP
- #include<sys/termio.h>
- #endif
-
-
- /* end of comments (I dont like them), you're on your own now..... */
-
-
-
- #ifdef PORTNUM
- void bulk();
- #endif
-
- void help();
- int commandlinetoagg(char**,char*);
- char *procom(char*);
- int getargc(char**);
- void arnwaitpid(char**);
- void arnsetid(char**);
- void arnsetgid(char**);
- void arnsetpgid(char**);
- void arnspawn(char**);
- void aswait(char**);
- void asbg(char**);
- void arnexec(char**);
- void cutarg(int,char**);
- void displaypinfo();
- void displayids();
- void displaygids();
- void displaypids();
- void pwdatanam(char**);
- void pwdatauid(char**);
- void displayhostinfo(char**);
- void dispinetaddr(char*,int);
-
- char inbuf[MAXCOMLEN+1];
-
- #ifdef PORTNUM
- main()
- {
- int sd,cd,n;
- int coninflen=sizeof(struct sockaddr_in);
- struct sockaddr_in sa;
- struct sockaddr_in coninf;
-
- sa.sin_family=AF_INET;
- sa.sin_port=htons(PORTNUM);
- sa.sin_addr.s_addr=htonl(INADDR_ANY);
-
- if((sd=socket(AF_INET,SOCK_STREAM,0))==-1)
- {
- perror("cant create socket");
- exit(1);
- };
- if(bind(sd,(struct sockaddr*)&sa,sizeof(sa)))
- {
- perror("cant bind to address");
- exit(1);
- };
- if(listen(sd,2))
- {
- perror("error with listen");
- exit(1);
- };
- if((cd=accept(sd,(struct sockaddr*)&coninf,&coninflen))<0)
- {
- perror("error with accept");
- exit(1);
- };
- close(STDIN_FILENO);
- dup(cd);
- close(STDOUT_FILENO);
- dup(cd);
- close(STDERR_FILENO);
- dup(cd);
- close(cd);
- bulk();
- close(sd);
- }
-
- void bulk()
-
- #else
-
- main()
-
- #endif
-
- {
- char *argv[MAXARGS+1];
- #ifdef PASSWD
- while(1)
- {
- printf("password: ");
- fflush(stdout);
- if(fgets(inbuf,MAXCOMLEN,stdin)==NULL) exit(0);
- if(!strcmp(crypt(procom(inbuf),PASSWD),PASSWD)) break;
- sleep(1);
- };
- #endif
- while(1)
- {
- printf(PROMPT);
- fflush(stdout);
- if(fgets(inbuf,MAXCOMLEN,stdin)==NULL) break;
- if(*procom(inbuf)=='\0') continue;
- printf("\"%s\"\n",inbuf);
- fflush(stdout);
- if(commandlinetoagg(argv,inbuf)) continue;
- if (!strcmp(*argv,"exit")) break;
- else
- if (!strcmp(*argv,"ihelp")) help();
- else
- if (!strcmp(*argv,"imore")) displayfile(argv[1]);
- else
- if (!strcmp(*argv,"cd")) changedir(argv);
- else
- if (!strcmp(*argv,"imkdir")) makedir(argv[1]);
- else
- if (!strcmp(*argv,"ird")) removedir(argv[1]);
- else
- if (!strcmp(*argv,"pwd")) pcwd();
- else
- if (!strcmp(*argv,"ils")) directory(argv);
- else
- if (!strcmp(*argv,"waitpid")) arnwaitpid(argv);
- else
- if (!strcmp(*argv,"setid")) arnsetid(argv);
- else
- if (!strcmp(*argv,"setgid")) arnsetgid(argv);
- else
- if (!strcmp(*argv,"setpgid")) arnsetpgid(argv);
- else
- if (!strcmp(*argv,"pinfo")) displaypinfo();
- else
- if (!strcmp(*argv,"pwdata")) pwdatanam(argv);
- else
- if (!strcmp(*argv,"pwdatauid")) pwdatauid(argv);
- else
- if (!strcmp(*argv,"hinfo")) displayhostinfo(argv);
- else
- if (*argv==NULL);
- else
- arnspawn(argv);
- };
- }
-
- void help()
- {
- printf("\ninternal commands recognised are:\n");
- printf("\texit, ihelp, imore, cd, imkdir, ird, pwd, ils,\n");
- printf("\twaitpid,\n");
- printf("\tsetid, setgid, setpgid, pinfo,\n");
- printf("\tpwdata, pwdatauid, hinfo.\n\n");
- }
-
- int commandlinetoagg(char **argv,char *cmdline)
- {
- int i,argnumber=0,inword=0;
- for(i=0;cmdline[i]!='\0';i++)
- {
- if ((cmdline[i]!=' ')&&(!inword))
- {
- argv[argnumber]=(cmdline+i);
- if((++argnumber)>=MAXARGS)
- {
- printf("too many arguments\n");
- *argv=NULL;
- return(1);
- };
- inword=1;
- };
- if (cmdline[i]==' ')
- {
- cmdline[i]='\0';
- inword=0;
- };
- };
- argv[argnumber]=NULL;
- return(0);
- }
-
- char *procom(char *astring)
- {
- int i;
- for(i=0;astring[i]!='\0';i++)
- {
- if(astring[i]=='\r') astring[i]='\0';
- if(astring[i]=='\n') astring[i]='\0';
- };
- return(astring);
- }
-
- changedir(char **argv)
- {
- if (getargc(argv)!=2)
- {
- printf("usage: %s path\n",*argv);
- return(1);
- };
- if (chdir(argv[1]))
- {
- perror("error when trying to change directory ");
- return(1);
- };
- return(0);
- }
-
- makedir(char *dirname)
- {
- printf("sorry, function not written yet....\n");
- return(1);
- }
-
- removedir(char *dirname)
- {
- printf("sorry, function not written yet....\n");
- return(1);
- }
-
- pcwd()
- {
- char *achpoint;
- achpoint=(char*)getcwd(NULL,800);
- printf("%s\n",achpoint);
- free(achpoint);
- return(0);
- }
-
- directory(char **argv)
- {
- printf("sorry, function not written yet....\n");
- return(1);
- }
-
- displayfile(char *filename)
- {
- char tempch,lines,horizpos;
- unsigned char pages;
- int tempint;
- char keybuf[32];
- long pagetable[UCHAR_MAX+1];
- FILE *afilepoint;
- #ifdef TTYMANIP
- struct termio old,new;
- if(!isatty(STDIN_FILENO))
- {
- printf("input is not a tty\n");
- return(1);
- };
- #endif
- if ((afilepoint=fopen(filename,"r"))==NULL)
- {
- printf("error opening file\n");
- return(1);
- };
- #ifdef TTYMANIP
- if(ioctl(STDIN_FILENO,TCGETA,&old))
- {
- printf("error getting terminal status, too risky to try to change\n");
- return(1);
- };
- new=old;
- new.c_lflag&=~(ICANON|ECHO);
- ioctl(STDIN_FILENO,TCSETA,&new);
- #endif
- for (tempint=0;tempint<=UCHAR_MAX;tempint++) pagetable[tempint]=0;
- pages=0;
- lines=0;
- horizpos=0;
- while ((tempch=getc(afilepoint))!=EOF)
- {
- switch(tempch)
- {
- case 9 : putchar(9);
- horizpos+=((horizpos+7)%8)+1;
- break;
- case 10: printf("\n");
- horizpos=0;
- lines++;
- break;
- default: if ((tempch>31)&&(tempch<127))
- {
- putchar(tempch);
- horizpos++;
- };
- };
- if (horizpos>=MAXWIDTH)
- {
- horizpos-=MAXWIDTH;
- lines++;
- };
- if (lines>=MAXLINES)
- {
- pages++;
- fflush(stdout);
- #ifdef TTYMANIP
- if(read(STDIN_FILENO,keybuf,24)==0) break;
- switch (*keybuf)
- {
- case 'q': ioctl(STDIN_FILENO,TCSETA,&old);
- fclose(afilepoint);
- return(1);
- case 'c': ioctl(STDIN_FILENO,TCSETA,&old);
- fclose(afilepoint);
- return(1);
- case 'b': printf("\n\n\n");
- horizpos=0;
- pages-=2;
- fseek(afilepoint,pagetable[pages],SEEK_SET);
- break;
- };
- #else
- if(fgets(keybuf,24,stdin)==NULL) break;
- if(*keybuf=='q') break;
- if(*keybuf=='c') break;
- if(*keybuf=='b')
- {
- printf("\n\n\n");
- horizpos=0;
- pages-=2;
- fseek(afilepoint,pagetable[pages],SEEK_SET);
- };
- #endif
- pagetable[pages]=ftell(afilepoint);
- lines=0;
- };
- };
- #ifdef TTYMANIP
- ioctl(STDIN_FILENO,TCSETA,&old);
- #endif
- fclose(afilepoint);
- return(0);
- }
-
- int getargc(char **argv)
- {
- int count;
- for(count=0;argv[count]!=NULL;count++);
- return(count);
- }
-
- void arnwaitpid(char **argv)
- {
- int status;
- if(getargc(argv)!=2)
- {
- printf("usage: %s pid\n",*argv);
- return;
- };
- printf("return value of waitpid=%d\n",waitpid(atoi(argv[1]),&status,WNOHANG));
- printf("status=%d\n",status);
- }
-
- void arnsetid(char **argv)
- {
- int realid,effid;
- displayids();
- if (getargc(argv)!=3)
- {
- printf("usage: %s realid effectiveid\n",argv[0]);
- return;
- };
- realid=atoi(argv[1]);
- effid=atoi(argv[2]);
- printf("trying to set: real id = %d , effective id = %d\n",realid,effid);
- if (setreuid(realid,effid))
- {
- printf("failed\n");
- perror("setreuid");
- }
- else
- printf("success\n");
- displayids();
- return;
- }
-
- void arnsetgid(char **argv)
- {
- int realgid,effgid;
- displaygids();
- if (getargc(argv)!=3)
- {
- printf("usage: %s realgid effectivegid\n",argv[0]);
- return;
- };
- realgid=atoi(argv[1]);
- effgid=atoi(argv[2]);
- printf("trying to set: real gid = %d , effective gid = %d\n",realgid,effgid);
- if (setregid(realgid,effgid))
- {
- printf("failed\n");
- perror("setregid");
- }
- else
- printf("success\n");
- displaygids();
- return;
- }
-
- void arnsetpgid(char **argv)
- {
- int pid,pgid;
- displaypids();
- if (getargc(argv)!=3)
- {
- printf("usage: %s pid pgid\n",argv[0]);
- return;
- };
- pid=atoi(argv[1]);
- pgid=atoi(argv[2]);
- printf("trying to set the process group of process %d to %d\n",pid,pgid);
- if (setpgid(pid,pgid))
- {
- printf("failed\n");
- perror("setpgid");
- }
- else
- printf("success\n");
- displaypids();
- return;
- }
-
- void displayids()
- {
- printf("real uid = %d , effective uid = %d\n",getuid(),geteuid());
- }
-
- void arnspawn(char **argv)
- {
- int argcdec;
- argcdec=(getargc(argv)-1);
- if (strcmp(argv[argcdec],"&")) aswait(argv);
- else
- {
- argv[argcdec]=NULL;
- asbg(argv);
- };
- }
-
- void aswait(char **argv)
- {
- int childpid,waitstat,waitret;
- switch(childpid=fork())
- {
- case -1 : printf("can not fork, :-(\n");
- break;
- case 0 : arnexec(argv);
- default : printf("program forked, waiting for child process (%d) to exit.....\n",childpid);
- waitret=waitpid(childpid,&waitstat,0);
- printf("return value of wait : %d wait status : %d\n",waitret,waitstat);
- }
- }
-
- void asbg(char **argv)
- {
- int childpid;
- switch(childpid=fork())
- {
- case -1 : printf("can not fork, :-(\n");
- break;
- case 0 : arnexec(argv);
- default : printf("program forked, child process id : %d\n",childpid);
- sleep(1);
- }
- }
-
- void arnexec(char **argv)
- {
- int x,fdin,fdout,trunc,append;
- for(x=1,trunc=1;argv[x]!=NULL;x++) if(!(trunc=(strcmp(argv[x],"<")))) break;
- if (!trunc)
- {
- printf("redirecting stdin from filename >%s<\n",argv[x+1]);
- if ((fdin=open(argv[x+1],O_RDONLY))== -1)
- {
- perror("cannot open file");
- printf("cannot open file for stdin, better luck next time ;-)\n");
- exit(1);
- };
- if (close(STDIN_FILENO))
- {
- perror("cannot close");
- printf("sorry but I'm confused again\n");
- exit(1);
- };
- if (dup(fdin)!=STDIN_FILENO)
- {
- printf("something wrong with dup(2), sorry but I'm out a here\n");
- close(fdin);
- exit(1);
- };
- if (close(fdin))
- {
- perror("cannot close");
- printf("sorry but I'm confused again\n");
- exit(1);
- };
- cutarg(x,argv);
- cutarg(x,argv);
- }
- for(x=1,trunc=1;argv[x]!=NULL;x++) if(!(trunc=(strcmp(argv[x],">")))) break;
- if (trunc) for(x=1,append=1;argv[x]!=NULL;x++) if(!(append=(strcmp(argv[x],">>")))) break;
- if ((!trunc)||(!append))
- {
- printf("redirecting stdout to filename >%s<\n",argv[x+1]);
- if ((fdout=open(argv[x+1],O_WRONLY|O_CREAT|(trunc?0:O_TRUNC)|(append?0:O_APPEND),0666))== -1)
- {
- perror("cannot open file");
- printf("cannot open file for stdout, better luck next time ;-)\n");
- exit(1);
- };
- if (close(STDOUT_FILENO))
- {
- perror("cannot close");
- printf("sorry but I'm confused again\n");
- exit(1);
- };
- if (dup(fdout)!= STDOUT_FILENO)
- {
- printf("something wrong with dup(2), sorry but I'm out a here\n");
- close(fdout);
- exit(1);
- };
- if (close(fdout))
- {
- perror("cannot close");
- printf("sorry but I'm confused again\n");
- exit(1);
- };
- cutarg(x,argv);
- cutarg(x,argv);
- };
- if ((execvp(argv[0],argv))==-1)
- {
- printf("can not use command, sorry\n");
- exit(1);
- };
- printf("whats happened? exec has a strange return value! I'm confused ;-O\n");
- exit(1);
- }
-
- void cutarg(int x,char **argv)
- {
- for(;argv[x]!=NULL;x++) argv[x]=argv[x+1];
- }
-
- void displaypinfo()
- {
- displayids();
- displaygids();
- displaypids();
- }
-
- void displaygids()
- {
- printf("real group id = %d , effective group id = %d\n",getgid(),getegid());
- }
-
- void displaypids()
- {
- printf("pid = %d , parent pid = %d , process group = %d\n",getpid(),getppid(),getpgrp());
- }
-
- void pwdatanam(char **argv)
- {
- struct passwd *a;
- if(getargc(argv)!=2)
- {
- printf("usage: %s username\n",*argv);
- return;
- };
- if((a=getpwnam(argv[1]))==NULL)
- {
- printf("%s: cant get info\n",*argv);
- perror(*argv);
- return;
- };
- printf("username=%s passwd=%s uid=%d gid=%d gecos=%s home=%s shell=%s\n",
- a->pw_name,a->pw_passwd,a->pw_uid,a->pw_gid,a->pw_gecos,a->pw_dir,a->pw_shell);
- }
-
- void pwdatauid(char **argv)
- {
- struct passwd *a;
- if(getargc(argv)!=2)
- {
- printf("usage: %s uid\n",*argv);
- return;
- };
- if((a=getpwuid(atoi(argv[1])))==NULL)
- {
- printf("%s: cant get info\n",*argv);
- perror(*argv);
- return;
- };
- printf("username=%s passwd=%s uid=%d gid=%d gecos=%s home=%s shell=%s\n",
- a->pw_name,a->pw_passwd,a->pw_uid,a->pw_gid,a->pw_gecos,a->pw_dir,a->pw_shell);
- }
-
- void displayhostinfo(char **argv)
- {
- int c;
- struct hostent *he;
- if(getargc(argv)!=2)
- {
- printf("usage: %s hostname\n",*argv);
- return;
- };
- if((he=gethostbyname(argv[1]))==NULL)
- {
- printf("%s: error with gethostbyname\n",*argv);
- return;
- };
- if(he->h_addrtype!=AF_INET) printf("warning, address returned is a type I dont know of\n");
- printf("official name=\"%s\"\n",he->h_name);
- printf("length of address=%d\n",he->h_length);
- printf("aliases:\n");
- for(c=0;he->h_aliases[c]!=NULL;c++) printf("\"%s\"\n",he->h_aliases[c]);
- printf("addresses:\n");
- for(c=0;he->h_addr_list[c]!=NULL;c++) dispinetaddr(he->h_addr_list[c],he->h_length);
- }
-
- void dispinetaddr(char *a,int b)
- {
- int c;
- for(c=0;c<b;c++) printf("%u.",(unsigned char)a[c]);
- putchar('\n');
- }
-
-