Ciao, sto scrivendo un programma, ma mi dà un errore alla linea 157.
L'errore è questo: 157: undefined reference to `strcnpy'
collect2: ld returned 1 exit status

è in rosso la linea di codice che mi da errore

Grazie

codice:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

#define DIMENSIONE 2560
#define TAGLIA_OBJ 56
#define TAGLIA_TXT 200
#define NUM_MAX_MSG (DIMENSIONE/TAGLIA_OBJ + TAGLIA_TXT)

typedef struct {
  int tipo;
  int memoria;
  int semaforo;
} boot;

typedef struct {
  char obj[TAGLIA_OBJ];
  char txt[TAGLIA_TXT];
} message;

message messaggio;

void errore(char* temp){
  printf("%s",temp);
  exit(-1);
}

void printMenu() {
	printf("==================================================\n");
	printf("	BACHECA ELETTRONICA VOLATILE		\n");
	printf("==================================================\n");
	printf("A. Leggi tutti i messaggi nella bacheca;\n");
	printf("B. Leggi un messaggio in bacheca;\n");
	printf("C. Inserisci un messaggio in bacheca;\n");
	printf("D. Rimuovi un messaggio dalla bacheca;\n");
	printf("Q. Esci dal programma;\n");
	printf("--------------------------------------------------\n");
	printf("Immetti la tua scelta: ");
}

void readMessages(int ds_shm){
  char* temp;
  int cont =1;
  temp = shmat(ds_shm, NULL, SHM_R);
  if(temp == (char*) -1){
    printf("Errore nella call shmat\n");
    exit(-1);
  }

    while(strcmp(temp,"")!=0){
      if(strcmp(temp,"_")==0){
        temp += TAGLIA_OBJ + TAGLIA_TXT;
        cont++;
      }
      else{
        printf("Codice del messaggio: %d\n", index);
        printf("Oggetto: %s\n", temp);
        temp+=TAGLIA_OBJ;
        printf("Testo: %s\n", temp);
        printf("--------------------------------------------------\n");
        temp += TAGLIA_TXT;
        cont++;
      }
    }

    }
    
    void readAMessage(int ds_shm){
      char* temp;
      int cont = 1;
      int codice;
      temp = shmat(ds_shm, NULL, SHM_R);
      if(temp == (char*) -1){
      printf("Errore nella call shmat\n");
      exit(-1);
      }
      printf("Inserire il codice del messaggio: ");
      scanf("%d", &codice);
      
      if(codice>NUM_MAX_MSG){
        printf("Errore: non esiste questo messaggio\n");
	exit(-1);
      }
      while(cont != codice){
        temp += TAGLIA_OBJ + TAGLIA_TXT;
        cont ++;
      }

      if(strcmp(temp,"")== 0 || strcmp(temp,"_") == 0){
        printf("Il messaggio non è presente in bacheca\n");
        exit(0);
      }
      else{
        printf("Codice del messaggio: d%\n", index);
        printf("Oggetto: %s\n",temp);
        temp+=TAGLIA_OBJ;
        printf("Testo: %s\n", temp);
        printf("----------------------------------------------------------\n");
        exit(0);
      }

    }

    void postAMessage(int ds_shm, int ds_sem){
      int letti;
      int ret;
      int index = 1;
      char* temp;
      struct sembuf oper;
      /*Blocco i semafori*/
      oper.sem_num = 0;
      oper.sem_op = -1;
      oper.sem_flg = 0;
      ret = semop(ds_sem, &oper, 1);  
      oper.sem_num = 1;
      oper.sem_op = -1;
      oper.sem_flg = 0;
      ret = semop(ds_sem, &oper, 1);

      temp = shmat(ds_shm, NULL, SHM_W);
      if(temp == (char*) -1){
        printf("errore nella call shmat\n");
        exit(-1);
      }
      while(strcmp(temp,"")!=0){
        if(strcmp(temp, "_") == 0 || index > NUM_MAX_MSG)
        break;
        else if(index == NUM_MAX_MSG){

          /*Sblocco i semafori*/
          oper.sem_num = 0;
          oper.sem_op = 1;
          oper.sem_flg = 0;
          ret = semop(ds_sem, &oper, 1);

          oper.sem_num = 1;
          oper.sem_op = 1;
          oper.sem_flg = 0;
          ret = semop(ds_sem, &oper, 1);

          printf("Bacheca piena, riprovare più tardi\n");
	  exit(-1);
        }
        else{
          temp += TAGLIA_OBJ + TAGLIA_TXT;
          index ++;
        }
      }
        printf("Oggetto: \n");
        scanf("%s\n", &messaggio.obj);
        strcnpy(temp,messaggio.obj,TAGLIA_OBJ);         temp += TAGLIA_OBJ; 

        printf("Testo: \n");
        scanf("%s\n",&messaggio.txt);
        strncpy(temp,messaggio.txt, TAGLIA_TXT);
        temp += TAGLIA_TXT; 

        /*Sblocco i semafori*/
        oper.sem_num = 0;
        oper.sem_op = 1;
        oper.sem_flg = 0;       
        ret = semop(ds_sem, &oper, 1);

        oper.sem_num = 1;
        oper.sem_op = 1;
        oper.sem_flg = 0;
        ret = semop(ds_sem, &oper, 1);

        exit(0);

    }

    getAMessage(int ds_shm, int ds_sem){
      char* temp;
      int codice;
      int index = 1;
      int ret;
      struct sembuf oper;

      /*blocco i semafori*/
      oper.sem_num = 0;
      oper.sem_op = -1;
      oper.sem_flg = 0;
      ret = semop(ds_sem, &oper, 1);

      oper.sem_num = 1;
      oper.sem_op = -1;
      oper.sem_flg = 0;
      ret = semop(ds_sem, &oper, 1);

      temp = shmat(ds_shm, NULL, SHM_W|SHM_R);
      if(temp == (char*) -1){
        printf("errore nella call shmat\n");
        exit(-1);
      }
      /*Stampo tutti i messaggi*/
      readMessages(ds_shm);

      scanf("%d", &codice);
      if(codice > NUM_MAX_MSG){
        oper.sem_num = 0;
        oper.sem_op = 1;
        oper.sem_flg = 0;
        ret = semop(ds_sem, &oper, 1);

        oper.sem_num = 1;
        oper.sem_op = 1;
        oper.sem_flg = 0;
        ret = semop(ds_sem, &oper, 1);
        printf("Errore, non ci sono tutti questi messaggi nella bacheca\n");
        exit(-1);
      }
      while(index != codice){
        temp += TAGLIA_OBJ + TAGLIA_TXT;
        index++;
      }
      if(strcmp(temp,"") == 0 || strcmp(temp,"_") == 0){
        printf("Il messaggio non è presente nella bacheca\n");
	exit(-1);
      }
      strncpy(temp,"_",TAGLIA_OBJ);
      temp += TAGLIA_OBJ;
      strncpy(temp,"", TAGLIA_TXT);
      temp += TAGLIA_TXT;

      /*Sblocco i semafori*/
      oper.sem_num = 0;
      oper.sem_op = 1;
      oper.sem_flg = 0;
      ret = semop(ds_sem, &oper, 1);

      oper.sem_num = 1;
      oper.sem_op = 1;
      oper.sem_flg = 0;
      ret = semop(ds_sem, &oper, 1);

      exit(0);

    }

    int main(){
      char scelta;
      int chiave_msg = 50;
      int status;
      int ds_shm;
      int ds_sem;
      int ds_coda;
      int ctl;
      int ret;     
      boot avvio;
      
      ds_coda = msgget(chiave_msg, IPC_CREAT|0666);
      ctl = msgrcv(ds_coda, &avvio, 2*sizeof(int), 1, IPC_NOWAIT);
      if(ctl == -1){
        printf("Errore: il server non ha installato la bacheca\n");
        exit(-1);
      }
      
      msgsnd(ds_coda, &avvio,2*sizeof(int), IPC_NOWAIT);
      
      ds_shm = avvio.memoria;
      ds_sem = avvio.semaforo;
      
      	while(scelta != 'Q' || scelta != 'q') {
		printMenu();
		scanf("%s",&scelta);
		if(scelta == 'A' || scelta == 'a') 
                if (fork()!= 0) wait(&status);
			else readMessages(ds_shm);
		else if(scelta == 'B' || scelta == 'b') {
			if (fork()!= 0) wait(&status);
			else readAMessage(ds_shm);
		}else if(scelta == 'C' || scelta == 'c') {
			if (fork()!= 0) wait(&status);
			else postAMessage(ds_shm,ds_sem);
		}
		else if(scelta == 'D' || scelta == 'd') {
			if (fork()!= 0) wait(&status);
			else getAMessage(ds_shm,ds_sem);
		}
		else if(scelta == 'Q' || scelta == 'q') {
			printf("Grazie di aver usato\nBACHECA ELETTRONICA VOLATILE\n");
			exit(0);
		}
		else printf("Scelta non valida.\n");
	}
	exit(0);
    }