#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#ifndef NO_CRYPT_DOT_H
#include <crypt.h>
#endif

#define default_file "/usr/local/etc/nakenchat.passwd"

struct user_t
{
  char passwd[1024];
  char username[1024];
  char password[1024];
  char enc_password[20];
  char channel[1024];
  char emote_char;
  int level;
  int hilite;
  int echos;
  int beeps;
  int flags;
};

void forget_line(FILE *in)
{
int ch;

  while(1)
  {
    ch=getc(in);
    if (ch==EOF || ch=='\r' || ch=='\n') break;
  }
}

void copy_line(FILE *in, FILE *out)
{
int ch;

  while(1)
  {
    ch=getc(in);
    if (ch!=EOF) putc(ch,out);
    if (ch==EOF || ch=='\r' || ch=='\n') break;
  }
}

void write_user(FILE *fp, struct user_t *user)
{
  fprintf(fp,"%s:%s:%d:%c:%d:%s\n",user->username,user->enc_password,user->level,user->emote_char,user->flags,user->channel);
}

int read_param(FILE *fp, char *s)
{
int ch;
int r;

  r=0;
  s[0]=0;

  while(1)
  {
    ch=getc(fp);
    if (ch==EOF && r==0) return -1;
    if ((ch=='\n' || ch=='\r') && r==0) continue;
    if (ch=='\\') { s[r++]=getc(fp); continue; }
    if (ch==':' || ch=='\n' || ch=='\r' || ch==EOF) break;
    s[r++]=ch;
  }

  s[r]=0;

  if (ch==':') return 1;

  return 0;
}

int check_user(struct user_t *user)
{
FILE *fp;
char param[1024];
int i;

  fp=fopen(user->passwd,"rb");
  if (fp==0)
  {
    printf("Cannot open file %s for reading!\n",user->passwd);
    exit(1);
  }

  while(1)
  {
    i=read_param(fp,param);

    if (strcmp(param,user->username)==0)
    {
      fclose(fp);
      return 1;
    }

    if (i==1)
    { while(read_param(fp,param)); }
      else
    { break; }
  }

  fclose(fp);

  return 0;
}

void delete_user(struct user_t *user)
{
FILE *fp,*tp;
char username[1024];
int ch,flag=0;

  fp=fopen(user->passwd,"rb");
  if (fp==0)
  {
    printf("Cannot open file %s for reading!\n",user->passwd);
    exit(1);
  }

  tp=fopen("/tmp/nkncht","wb");
  if (tp==0)
  {
    printf("Cannot open temp file!\n");
    fclose(fp);
    exit(1);
  }

  while(1)
  {
    if (read_param(fp,username)==-1) break;
    if (strcmp(username,user->username)==0)
    {
      forget_line(fp);
      flag=1;
    } 
      else
    {
      fprintf(tp,"%s:",username);
      copy_line(fp,tp);
    }
  }

  fclose(fp);
  fclose(tp);

  if (flag==0)
  {
    printf("User does not exist.\n");
    unlink("/tmp/nkncht");
    return;
  }

  fp=fopen(user->passwd,"wb");
  if (fp==0)
  {
    printf("Cannot open file %s for writing!\n",user->passwd);
    exit(1);
  }

  tp=fopen("/tmp/nkncht","rb");
  if (tp==0)
  {
    printf("Cannot open temp file!\n");
    fclose(fp);
    exit(1);
  }

  while ((ch=getc(tp))!=EOF) putc(ch,fp);

  fclose(fp);
  fclose(tp);

  unlink("/tmp/nkncht");
}

void edit_user(struct user_t *user)
{
FILE *fp;

  fp=fopen(user->passwd,"rb");
  if (fp==0)
  {
    printf("Cannot open file %s for reading!\n",user->passwd);
    exit(1);
  }

  fclose(fp);

printf("not supported yet\n");

}

void add_user(struct user_t *user)
{
FILE *fp;
char seed[3];

  fp=fopen(user->passwd,"ab");
  if (fp==0)
  {
    printf("Cannot open file %s for writing!\n",user->passwd);
    exit(1);
  }

  if (user->channel[0]==0) strcpy(user->channel,"Main");
  if (user->emote_char==0) user->emote_char='%';
  if (user->password[0]==0)
  { user->enc_password[0]='*'; }
    else
  {
    seed[0]=user->username[0];
    if (user->username[1]!=0)
    { seed[1]=user->username[1]; }
      else
    { seed[1]=user->username[0]; }
    seed[2]=0;

    if (seed[0]==':') seed[0]='a';
    if (seed[1]==':') seed[1]='b';

    strcpy(user->enc_password,crypt(user->password,seed));
  }

  if (user->level<0 || user->level>10) user->level=0;
  if (user->hilite==1) user->flags|=2;
  if (user->echos==1) user->flags|=16;
  if (user->beeps==1) user->flags|=1;

  if (user->channel[0]==0) strcpy(user->channel,"main");

  write_user(fp,user);

  fclose(fp);
}

int check_option(char *s)
{
  if (strcasecmp(s,"on")==0 || strcmp(s,"1")==0) return 1;
    else
  if (strcasecmp(s,"off")==0 || strcmp(s,"0")==0) return 0;

  return -1;
}

int main(int argc, char *argv[])
{
struct user_t user;
int r,d;

  strcpy(user.passwd,default_file);

  user.channel[0]=0;
  user.emote_char=0;
  user.password[0]=0;
  user.username[0]=0;
  user.level=-1;
  user.hilite=-1;
  user.echos=-1;
  user.beeps=-1;
  user.emote_char=0;
  user.flags=0;

  d=0;

  if (argc<2)
  {
    printf("\nNaken Chat 2.xx password file editor.\n");
    printf("Usage: nakenpasswd [ options ] <username>\n");
    printf("   -password_file <password_file [ default /usr/local/etc/nakenchat.passwd ]>\n");
    printf("   -password <password [ default cannot login ]>\n");
    printf("   -channel <channel [ default Main ]>\n");
    printf("   -level <user_level [ default 0 ]>\n");
    printf("   -hilite <(on/off) [ default off ]>\n");
    printf("   -echo <(on/off) [ default off ]>\n");
    printf("   -beeps <(on/off) [ default off ]>\n");
    printf("   -emote <emote char>\n");
    printf("   -delete\n");
    printf("\n");
    exit(0);
  }

  for (r=1; r<argc; r++)
  {
    if (strcmp(argv[r],"-password_file")==0)
    { strcpy(user.passwd,argv[++r]); }
      else
    if (strcmp(argv[r],"-password")==0)
    { strcpy(user.password,argv[++r]); }
      else
    if (strcmp(argv[r],"-channel")==0)
    { strcpy(user.channel,argv[++r]); }
      else
    if (strcmp(argv[r],"-level")==0)
    { user.level=atoi(argv[++r]); }
      else
    if (strcmp(argv[r],"-hilite")==0)
    { user.hilite=check_option(argv[++r]); }
      else
    if (strcmp(argv[r],"-echo")==0)
    { user.echos=check_option(argv[++r]); }
      else
    if (strcmp(argv[r],"-beeps")==0)
    { user.beeps=check_option(argv[++r]); }
      else
    if (strcmp(argv[r],"-emote")==0)
    { user.emote_char=argv[++r][0]; }
      else
    if (strcmp(argv[r],"-delete")==0)
    { d=1; }
      else
    { strcpy(user.username,argv[r]); }
  }

  if (user.username[0]==0)
  {
    printf("Username required!\n");
    exit(0);
  }

  if (d==1)
  { delete_user(&user); }
    else
  if (check_user(&user)==0)
  { add_user(&user); }
    else
  { edit_user(&user); }

  return 0;
}



syntax highlighted by Code2HTML, v. 0.9.1